From 899615f6ebafebbf9b2ae18b3906ce39925efe0e Mon Sep 17 00:00:00 2001 From: Khaleel Al-Adhami Date: Thu, 24 Apr 2025 23:35:33 -0700 Subject: [PATCH 1/2] wrap sankey recharts --- pyi_hashes.json | 10 +-- reflex/components/el/elements/__init__.py | 1 + reflex/components/el/elements/media.py | 10 +++ reflex/components/recharts/__init__.py | 2 + reflex/components/recharts/charts.py | 98 ++++++++++++++++++++++- reflex/components/recharts/general.py | 1 + 6 files changed, 113 insertions(+), 9 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index bd1389e0a25..258f8523d04 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -25,13 +25,13 @@ "reflex/components/datadisplay/code.pyi": "3d8f0ab4c2f123d7f80d15c7ebc553d9", "reflex/components/datadisplay/dataeditor.pyi": "cb03d732e2fe771a8d46c7bcda671f92", "reflex/components/datadisplay/shiki_code_block.pyi": "87db7639bfa5cd53e1709e1363f93278", - "reflex/components/el/__init__.pyi": "09042a2db5e0637e99b5173430600522", + "reflex/components/el/__init__.pyi": "0286a5b614420b25f59cb8ee462320df", "reflex/components/el/element.pyi": "06ac2213b062119323291fa66a1ac19e", - "reflex/components/el/elements/__init__.pyi": "280ed457675f3720e34b560a3f617739", + "reflex/components/el/elements/__init__.pyi": "c04167d619d9f0b00eba882fe5ab086c", "reflex/components/el/elements/base.pyi": "6e533348b5e1a88cf62fbb5a38dbd795", "reflex/components/el/elements/forms.pyi": "161f1ef847e5da8755528a7977fdcf53", "reflex/components/el/elements/inline.pyi": "33d9d860e75dd8c4769825127ed363bb", - "reflex/components/el/elements/media.pyi": "addd6872281d65d44a484358b895432f", + "reflex/components/el/elements/media.pyi": "58856abaf78df332b181cda887b3ae3e", "reflex/components/el/elements/metadata.pyi": "974a86d9f0662f6fc15a5bb4b3a87862", "reflex/components/el/elements/other.pyi": "995a4fbf10bfdb7f48808210dfe413bd", "reflex/components/el/elements/scripts.pyi": "cd5bd53c3a6b016fbb913aff36d63344", @@ -114,9 +114,9 @@ "reflex/components/react_player/audio.pyi": "972975ed0ba3e1dc4a867da20b11ae8e", "reflex/components/react_player/react_player.pyi": "63ffffbc24907103f797dcfd85894107", "reflex/components/react_player/video.pyi": "35ce5ad62e8bff17d9c09d27c362f8dc", - "reflex/components/recharts/__init__.pyi": "a52c9055e37c6ee25ded15688d45e8a5", + "reflex/components/recharts/__init__.pyi": "ea6d4bf27ea46d35f3ab447030947388", "reflex/components/recharts/cartesian.pyi": "9dd16c08abe5205c6c414474e2de2f79", - "reflex/components/recharts/charts.pyi": "3570af4627c601d10ee37033f1b2329c", + "reflex/components/recharts/charts.pyi": "59cbd1a7d6a6429e7df1eb807eda8fad", "reflex/components/recharts/general.pyi": "a1b846d5f2fd0a8b1969b472c5cab2e7", "reflex/components/recharts/polar.pyi": "973c3e6aa253914c4c5fd18ed32196fb", "reflex/components/recharts/recharts.pyi": "157acc830323075ffaf4f68d495d1787", diff --git a/reflex/components/el/elements/__init__.py b/reflex/components/el/elements/__init__.py index 173b9988ab5..56e1d7e0e62 100644 --- a/reflex/components/el/elements/__init__.py +++ b/reflex/components/el/elements/__init__.py @@ -71,6 +71,7 @@ "circle", "ellipse", "rect", + "g", "polygon", "path", "stop", diff --git a/reflex/components/el/elements/media.py b/reflex/components/el/elements/media.py index e76f12751ae..9a176eab973 100644 --- a/reflex/components/el/elements/media.py +++ b/reflex/components/el/elements/media.py @@ -316,6 +316,8 @@ class Text(BaseHTML): length_adjust: Var[str] # A width that the text should be scaled to fit. text_length: Var[str | int] + # Used to align the text with respect to the x and y attributes. + text_anchor: Var[str] class Line(BaseHTML): @@ -364,6 +366,12 @@ class Ellipse(BaseHTML): path_length: Var[int] +class G(BaseHTML): + """The SVG g component.""" + + tag = "g" + + class Rect(BaseHTML): """The SVG rect component.""" @@ -492,6 +500,7 @@ class SVG(ComponentNamespace): circle = staticmethod(Circle.create) ellipse = staticmethod(Ellipse.create) rect = staticmethod(Rect.create) + g = staticmethod(G.create) polygon = staticmethod(Polygon.create) path = staticmethod(Path.create) stop = staticmethod(Stop.create) @@ -506,6 +515,7 @@ class SVG(ComponentNamespace): circle = Circle.create ellipse = Ellipse.create rect = Rect.create +g = G.create polygon = Polygon.create path = Path.create stop = Stop.create diff --git a/reflex/components/recharts/__init__.py b/reflex/components/recharts/__init__.py index 7aa0041d901..1995eb44fd0 100644 --- a/reflex/components/recharts/__init__.py +++ b/reflex/components/recharts/__init__.py @@ -58,6 +58,8 @@ "FunnelChart", "treemap", "Treemap", + "sankey_chart", + "SankeyChart", ], "general": [ "responsive_container", diff --git a/reflex/components/recharts/charts.py b/reflex/components/recharts/charts.py index dc7fe262485..8af6d0ca32b 100644 --- a/reflex/components/recharts/charts.py +++ b/reflex/components/recharts/charts.py @@ -3,7 +3,7 @@ from __future__ import annotations from collections.abc import Sequence -from typing import Any, ClassVar +from typing import Any, ClassVar, TypedDict from reflex.components.component import Component from reflex.components.recharts.general import ResponsiveContainer @@ -37,9 +37,6 @@ class ChartBase(RechartsCharts): # The customized event handler of mouseenter on the component in this chart on_mouse_enter: EventHandler[no_args_event_spec] - # The customized event handler of mousemove on the component in this chart - on_mouse_move: EventHandler[no_args_event_spec] - # The customized event handler of mouseleave on the component in this chart on_mouse_leave: EventHandler[no_args_event_spec] @@ -122,6 +119,9 @@ class CategoricalChartBase(ChartBase): # The type of offset function used to generate the lower and upper values in the series array. The four types are built-in offsets in d3-shape. 'expand' | 'none' | 'wiggle' | 'silhouette' stack_offset: Var[LiteralStackOffset] + # The customized event handler of mousemove on the component in this chart + on_mouse_move: EventHandler[no_args_event_spec] + class AreaChart(CategoricalChartBase): """An Area chart component in Recharts.""" @@ -447,6 +447,9 @@ class FunnelChart(ChartBase): # The stroke color of each bar. String | Object stroke: Var[str | Color] + # The customized event handler of mousemove on the component in this chart + on_mouse_move: EventHandler[no_args_event_spec] + # Valid children components _valid_children: ClassVar[list[str]] = ["Legend", "GraphingTooltip", "Funnel"] @@ -512,6 +515,92 @@ def create(cls, *children, **props) -> Component: ) +class SankeyChartNode(TypedDict): + """A node in a Sankey chart.""" + + name: str + + +class SankeyChartLink(TypedDict): + """A link in a Sankey chart.""" + + source: int + target: int + value: int | float + + +class SankeyChartData(TypedDict): + """The data for a Sankey chart.""" + + nodes: Sequence[SankeyChartNode] + links: Sequence[SankeyChartLink] + + +class SankeyChart(ChartBase): + """A Sankey chart component in Recharts.""" + + tag = "Sankey" + + alias = "RechartsSankeyChart" + + # The key of each sector's name. + name_key: Var[str] + + # The key of a group of data which should be unique in a SankeyChart. + data_key: Var[int | str] + + # The source data, including the array of nodes, and the relationships, represented by links. + data: Var[SankeyChartData] + + # Whether to sort the nodes on th y axis, or to display them as user-defined. + sort: Var[bool] + + # The padding between the nodes. + node_padding: Var[int] + + # The width of the nodes. + node_width: Var[int] + + # The width of link. + link_width: Var[int] + + # The curvature of width. + link_curvature: Var[float] + + # The number of the iterations between the links + iterations: Var[int] + + # The sizes of whitespace around the chart, i.e. {"top": 50, "right": 30, "left": 20, "bottom": 5}. + margin: Var[dict[str, Any]] + + # Valid children components + _valid_children: ClassVar[list[str]] = ["GraphingTooltip", "Defs"] + + # The source number of X-axis + source_x: Var[int] + + # The source number of Y-axis + source_y: Var[int] + + # The source control of X-axis + source_control_x: Var[int] + + # The target control of X-axis + target_control_x: Var[int] + + # The target of X-axis + target_x: Var[int] + + # The target of Y-axis + target_y: Var[int] + + # If set a object, the option is the configuration of nodes. If set a React element, the option is the custom react element of drawing the nodes. + node: Var[Any] + + # If set a object, the option is the configuration of links. If set a React element, the option is the custom react element of drawing the links. + link: Var[Any] + + area_chart = AreaChart.create bar_chart = BarChart.create line_chart = LineChart.create @@ -522,3 +611,4 @@ def create(cls, *children, **props) -> Component: scatter_chart = ScatterChart.create funnel_chart = FunnelChart.create treemap = Treemap.create +sankey_chart = SankeyChart.create diff --git a/reflex/components/recharts/general.py b/reflex/components/recharts/general.py index bde06719e25..a706448d917 100644 --- a/reflex/components/recharts/general.py +++ b/reflex/components/recharts/general.py @@ -62,6 +62,7 @@ class ResponsiveContainer(Recharts, MemoizationLeaf): "Treemap", "ComposedChart", "FunnelChart", + "SankeyChart", ] From 8b2e5658aecb02ef2f12e01082a449edd3a75d00 Mon Sep 17 00:00:00 2001 From: Lendemor Date: Wed, 4 Jun 2025 14:11:00 +0200 Subject: [PATCH 2/2] remove another duplicate --- pyi_hashes.json | 2 +- reflex/components/el/elements/__init__.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pyi_hashes.json b/pyi_hashes.json index d13c448c427..86f0fd9a420 100644 --- a/pyi_hashes.json +++ b/pyi_hashes.json @@ -27,7 +27,7 @@ "reflex/components/datadisplay/shiki_code_block.pyi": "ac16fd6c23eef7ce0185437ecf2d529d", "reflex/components/el/__init__.pyi": "f07f5957ca4dc3d95ffdc2ddb75fe2f8", "reflex/components/el/element.pyi": "323cfb5d67d8ccb58ac36c7cc7641dc3", - "reflex/components/el/elements/__init__.pyi": "f1ae8344b2f5f105da7c14dd8890fe3f", + "reflex/components/el/elements/__init__.pyi": "baeddd04d4d3a82799420b2a6df368f6", "reflex/components/el/elements/base.pyi": "697cd6716e3b1127b35299435c3d4e69", "reflex/components/el/elements/forms.pyi": "14f2ac656d37c4a5343c77e89ad9107b", "reflex/components/el/elements/inline.pyi": "ab31eec758f1cff8a9d51bf0935b9fca", diff --git a/reflex/components/el/elements/__init__.py b/reflex/components/el/elements/__init__.py index c9228539aab..4661d7ecfc1 100644 --- a/reflex/components/el/elements/__init__.py +++ b/reflex/components/el/elements/__init__.py @@ -72,7 +72,6 @@ "g", "ellipse", "rect", - "g", "polygon", "path", "stop",