diff --git a/.gitignore b/.gitignore index a100b943..3b773338 100644 --- a/.gitignore +++ b/.gitignore @@ -69,4 +69,7 @@ package-lock.json # Virtual Env -env/* \ No newline at end of file +env/* + +# example folder +examples/ \ No newline at end of file diff --git a/README.md b/README.md index e11cf98d..149cf06d 100644 --- a/README.md +++ b/README.md @@ -34,21 +34,56 @@ selected_points = plotly_events(fig, click_event=False, hover_event=True) What the component returns: ``` Returns -------- -list of dict - List of dictionaries containing point details (in case multiple overlapping points have been clicked). - - Details can be found here: - https://plotly.com/javascript/plotlyjs-events/#event-data - - Format of dict: + ------- + list of dict + List of dictionaries containing point details (in case multiple overlapping + points have been clicked). + + Details can be found here: + https://plotly.com/javascript/plotlyjs-events/#event-data + + Format of dict: + { + x: float (x value of point), + y: float (y value of point), + z: float (z value of point), # optional enabled using with_z + curveNumber: (index of curve), + pointNumber: (index of selected point), + pointIndex: (index of selected point) + } + + If measurement is enabled: + { + x: float (x value of point), + y: float (y value of point), + z: float (z value of point), # optional enabled using with_z + curveNumber: (index of curve), + pointNumber: (index of selected point), + pointIndex: (index of selected point) + }, + { + measurePointsX: (list of measurement points x value), + measurePointsY: (list of measurement points y value), + measurePointsZ: (list of measurement poitns z value), + dx: (delta x of measurement points, 0 when only one point is clicked), + dy: (delta y of measurement points, 0 when only one point is clicked), + dz: (delta z of measurement points, 0 when only one point is clicked) + dxyz: (delta xyz of measurement points, 0 when only one points is clicked) + dxy: (delta xy of measurement points, 0 when only one point is clicked), + dxz: (delta xz of measurement points, 0 when only one point is clicked), + dyz: (delta yz of measurement points, 0 when only one point is clicked) + } + If get_relayout is enabled, additional returns will happen when the chart is moved around { - x: int (x value of point), - y: int (y value of point), - curveNumber: (index of curve), - pointNumber: (index of selected point), - pointIndex: (index of selected point) + cameraLayout: { + x: float (x camera position) + y: float (y camera position) + z: float (z camera position) + } } + different dictionaries will be returned so you need to handle them + + ``` diff --git a/example.gif b/example.gif index b584444a..b6fafbb3 100644 Binary files a/example.gif and b/example.gif differ diff --git a/src/streamlit_plotly_events.egg-info/PKG-INFO b/src/streamlit_plotly_events.egg-info/PKG-INFO new file mode 100644 index 00000000..509897d8 --- /dev/null +++ b/src/streamlit_plotly_events.egg-info/PKG-INFO @@ -0,0 +1,14 @@ +Metadata-Version: 2.1 +Name: streamlit-plotly-events +Version: 0.0.6 +Summary: Plotly chart component for Streamlit that also allows for events to bubble back up to Streamlit. +Home-page: https://github.com/null-jones/streamlit-plotly-events +Author: Ellie Jones +Author-email: ellie@altaml.com +Requires-Python: >=3.6 +Description-Content-Type: text/plain +License-File: LICENSE +Requires-Dist: streamlit>=0.63 +Requires-Dist: plotly>=4.14.3 + +Plotly chart component for Streamlit that also allows for events to bubble back up to Streamlit. diff --git a/src/streamlit_plotly_events.egg-info/SOURCES.txt b/src/streamlit_plotly_events.egg-info/SOURCES.txt new file mode 100644 index 00000000..9f3cb1c2 --- /dev/null +++ b/src/streamlit_plotly_events.egg-info/SOURCES.txt @@ -0,0 +1,21 @@ +LICENSE +MANIFEST.in +README.md +setup.py +src/streamlit_plotly_events/__init__.py +src/streamlit_plotly_events.egg-info/PKG-INFO +src/streamlit_plotly_events.egg-info/SOURCES.txt +src/streamlit_plotly_events.egg-info/dependency_links.txt +src/streamlit_plotly_events.egg-info/requires.txt +src/streamlit_plotly_events.egg-info/top_level.txt +src/streamlit_plotly_events/frontend/build/asset-manifest.json +src/streamlit_plotly_events/frontend/build/index.html +src/streamlit_plotly_events/frontend/build/precache-manifest.73c82ebc749cad31f76721ccef17783d.js +src/streamlit_plotly_events/frontend/build/service-worker.js +src/streamlit_plotly_events/frontend/build/static/js/2.9330ddf9.chunk.js +src/streamlit_plotly_events/frontend/build/static/js/2.9330ddf9.chunk.js.LICENSE.txt +src/streamlit_plotly_events/frontend/build/static/js/2.9330ddf9.chunk.js.map +src/streamlit_plotly_events/frontend/build/static/js/main.0d52cef4.chunk.js +src/streamlit_plotly_events/frontend/build/static/js/main.0d52cef4.chunk.js.map +src/streamlit_plotly_events/frontend/build/static/js/runtime-main.44d30fc2.js +src/streamlit_plotly_events/frontend/build/static/js/runtime-main.44d30fc2.js.map \ No newline at end of file diff --git a/src/streamlit_plotly_events.egg-info/dependency_links.txt b/src/streamlit_plotly_events.egg-info/dependency_links.txt new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/src/streamlit_plotly_events.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/streamlit_plotly_events.egg-info/requires.txt b/src/streamlit_plotly_events.egg-info/requires.txt new file mode 100644 index 00000000..425c3181 --- /dev/null +++ b/src/streamlit_plotly_events.egg-info/requires.txt @@ -0,0 +1,2 @@ +streamlit>=0.63 +plotly>=4.14.3 diff --git a/src/streamlit_plotly_events.egg-info/top_level.txt b/src/streamlit_plotly_events.egg-info/top_level.txt new file mode 100644 index 00000000..a3c2343a --- /dev/null +++ b/src/streamlit_plotly_events.egg-info/top_level.txt @@ -0,0 +1 @@ +streamlit_plotly_events diff --git a/src/streamlit_plotly_events/__init__.py b/src/streamlit_plotly_events/__init__.py index abd03c49..4ced4539 100644 --- a/src/streamlit_plotly_events/__init__.py +++ b/src/streamlit_plotly_events/__init__.py @@ -6,7 +6,7 @@ # the component, and True when we're ready to package and distribute it. # (This is, of course, optional - there are innumerable ways to manage your # release process.) -_RELEASE = False +_RELEASE = True # Declare a Streamlit component. `declare_component` returns a function # that is used to create instances of the component. We're naming this @@ -47,11 +47,17 @@ def plotly_events( plot_fig, click_event=True, + with_z=False, select_event=False, hover_event=False, override_height=450, override_width="100%", key=None, + plot_clicked_point: bool = False, + clicked_point_size: float = 0.0, + measure_mode: bool = False, + measure_line_width: float = 4.0, + get_relayout: bool = False, ): """Create a new instance of "plotly_events". @@ -73,6 +79,16 @@ def plotly_events( An optional key that uniquely identifies this component. If this is None, and the component's arguments are changed, the component will be re-mounted in the Streamlit frontend and lose its current state. + plot_clicked_point: bool + An optional key if you want the clicked point on the chart to have a red point drawn + to indicate where you clicked (Stable for Scatter 3d plots not yet tested on other types) + clicked_point_size: float + What size to plot the clicked point, will work make a difference when plot_clicked_point is True + measure_mode: bool + Plot measurements after clicking 2 points on the chart, will modify the return value of the component + Measurement and plotting is done is in component space so no need to rerun + measure_line_width: float + What line width to plot when measurement is done, Returns ------- @@ -85,13 +101,45 @@ def plotly_events( Format of dict: { - x: int (x value of point), - y: int (y value of point), + x: float (x value of point), + y: float (y value of point), + z: float (z value of point), # optional enabled using with_z curveNumber: (index of curve), pointNumber: (index of selected point), pointIndex: (index of selected point) } + If measurement is enabled: + { + x: float (x value of point), + y: float (y value of point), + z: float (z value of point), # optional enabled using with_z + curveNumber: (index of curve), + pointNumber: (index of selected point), + pointIndex: (index of selected point) + }, + { + measurePointsX: (list of measurement points x value), + measurePointsY: (list of measurement points y value), + measurePointsZ: (list of measurement poitns z value), + dx: (delta x of measurement points, 0 when only one point is clicked), + dy: (delta y of measurement points, 0 when only one point is clicked), + dz: (delta z of measurement points, 0 when only one point is clicked) + dxyz: (delta xyz of measurement points, 0 when only one points is clicked) + dxy: (delta xy of measurement points, 0 when only one point is clicked), + dxz: (delta xz of measurement points, 0 when only one point is clicked), + dyz: (delta yz of measurement points, 0 when only one point is clicked) + } + If get_relayout is enabled, additional returns will happen when the chart is moved around + { + cameraLayout: { + x: float (x camera position) + y: float (y camera position) + z: float (z camera position) + } + } + different dictionaries will be returned so you need to handle them + """ # kwargs will be exposed to frontend in "args" component_value = _component_func( @@ -100,9 +148,15 @@ def plotly_events( override_width=override_width, key=key, click_event=click_event, + with_z=with_z, select_event=select_event, hover_event=hover_event, - default="[]", # Default return empty JSON list + default="[]", + plot_clicked_point=plot_clicked_point, + clicked_point_size=clicked_point_size, + measure_mode=measure_mode, + measure_line_width=measure_line_width, + get_relayout=get_relayout ) # Parse component_value since it's JSON and return to Streamlit @@ -126,7 +180,7 @@ def plotly_events( # Here we add columns to check auto-resize/etc st.subheader("Plotly Bar Chart (With columns)") - _, c2, _ = st.beta_columns((1, 6, 1)) + _, c2, _ = st.columns((1, 6, 1)) with c2: fig2 = px.bar(x=[0, 1, 2, 3], y=[0, 1, 2, 3]) plot_name_holder2 = st.empty() diff --git a/src/streamlit_plotly_events/frontend/build/asset-manifest.json b/src/streamlit_plotly_events/frontend/build/asset-manifest.json new file mode 100644 index 00000000..cc573bab --- /dev/null +++ b/src/streamlit_plotly_events/frontend/build/asset-manifest.json @@ -0,0 +1,19 @@ +{ + "files": { + "main.js": "./static/js/main.b4df662e.chunk.js", + "main.js.map": "./static/js/main.b4df662e.chunk.js.map", + "runtime-main.js": "./static/js/runtime-main.44d30fc2.js", + "runtime-main.js.map": "./static/js/runtime-main.44d30fc2.js.map", + "static/js/2.9330ddf9.chunk.js": "./static/js/2.9330ddf9.chunk.js", + "static/js/2.9330ddf9.chunk.js.map": "./static/js/2.9330ddf9.chunk.js.map", + "index.html": "./index.html", + "precache-manifest.9c7844760ffbfd02bfd7cf00c7dc1f22.js": "./precache-manifest.9c7844760ffbfd02bfd7cf00c7dc1f22.js", + "service-worker.js": "./service-worker.js", + "static/js/2.9330ddf9.chunk.js.LICENSE.txt": "./static/js/2.9330ddf9.chunk.js.LICENSE.txt" + }, + "entrypoints": [ + "static/js/runtime-main.44d30fc2.js", + "static/js/2.9330ddf9.chunk.js", + "static/js/main.b4df662e.chunk.js" + ] +} \ No newline at end of file diff --git a/src/streamlit_plotly_events/frontend/build/index.html b/src/streamlit_plotly_events/frontend/build/index.html new file mode 100644 index 00000000..11ad3e2f --- /dev/null +++ b/src/streamlit_plotly_events/frontend/build/index.html @@ -0,0 +1 @@ +