dkapur17 / streamlit-flow

Streamlit Component to quickly create Interactive Flow Diagrams using React Flow
https://stflow.streamlit.app
52 stars 6 forks source link

Add new node within canvas #1

Closed George-bai closed 1 week ago

George-bai commented 1 month ago

This project is great. One feature that will be super helpful is to add a tool bar, allowing user to create new node by drag-n-drop, or using the right click menu. Similarly, it will be more intuitive if one can edit the properties of any created nodes by double / right click.

Again, thanks for your good work.

dkapur17 commented 1 month ago

Thanks for the idea @George-bai. The current implementation doesn't support state updates from within the canvas, and as such the component can really only render flows that are computed on the backend. Adding the capability that allows changes made to the flow from within the canvas to be propagated back to the streamlit application is something that will require significant re-engineering of the component - I'll look into this as soon as I can.

Until then however, it is possible to dynamically build flows at run-time, except you'll need to rely on other streamlit components as well for this. Here is a quick example that uses the st.form to add new nodes to the flow:

import streamlit as st
from streamlit_flow import streamlit_flow
from streamlit_flow.interfaces import StreamlitFlowNode, StreamlitFlowEdge

if 'nodes' not in st.session_state:
    st.session_state.nodes = []
if 'edges' not in st.session_state:
    st.session_state.edges = []

st.title("Dynamic Node Addition Example")
streamlit_flow(st.session_state.nodes, st.session_state.edges, get_node_on_click=True)

with st.form("Node Adder"):
    node_name = st.text_input("Node Name")

    if st.form_submit_button("Add Node"):
        st.session_state.nodes.append(StreamlitFlowNode(node_name, (0, 0,), {'label': node_name}))
        st.rerun()

DNAE

You can do something similar for adding edges. (I know there is a facility to connect nodes within the canvas itself, however since that state update is not propagated back to streamlit, the edges made in such a way will disappear on re-run). You can also use the return value of the component to edit the nodes that you select, by rendering a form with the component details, and updating the state when the form is submitted.

George-bai commented 1 month ago

@dkapur17 thanks for your quick response. Your example is helpful.

I also come crossed another Streamlit barfi, I am not familiar with frontend development, and not sure similar the underline frontend technologies powered Streamlit-flow and Barfi, but it would be great to see the Streamlit-flow to have the in-canvas editing ability. Thanks again.

dkapur17 commented 1 month ago

Hey @George-bai. I've released v1.0.0 and that includes the features you requested. Do check it out!

George-bai commented 1 month ago

@dkapur17 Thanks, I just updated and tested the new features. Really appreciated your effort.

How to save the diagram that created in canvas, so it can be loaded later?

dkapur17 commented 1 month ago

You can access the current state of the flow at st.session_state[key], where key is the key of the component. From this you'll get a dictionary containing all the nodes, edges and the selectedID. The nodes and edges are already a list of dictionaries, so you can save them as a JSON. For loading, you can load the JSON back and then use the StreamlitFlowNode.from_dict and StreamlitFlowEdge.from_dict methods to convert back into the list of elements, and then use them in the component as needed.

You can get a clearer understanding of this by looking at this demo: https://stflow.streamlit.app/Hackable_State