-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add Layer and Rectangle components to Recharts #6729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Added `rx.recharts.layer` and `rx.recharts.rectangle`, wrapping the Recharts `Layer` and `Rectangle` components used for constructing custom node elements. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -73,6 +73,10 @@ | |
| "LabelList", | ||
| "cell", | ||
| "Cell", | ||
| "layer", | ||
| "Layer", | ||
| "rectangle", | ||
| "Rectangle", | ||
| ], | ||
| "polar": [ | ||
| "pie", | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -299,9 +299,77 @@ class Cell(Recharts): | |||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| class Layer(Recharts): | ||||||||||||||
| """A Layer component in Recharts. Renders an SVG <g> element that groups | ||||||||||||||
| other SVG elements, e.g. when constructing custom node elements. | ||||||||||||||
| """ | ||||||||||||||
|
|
||||||||||||||
| tag = "Layer" | ||||||||||||||
|
|
||||||||||||||
| alias = "RechartsLayer" | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| class Rectangle(Recharts): | ||||||||||||||
| """A Rectangle shape component in Recharts, e.g. used as a building block | ||||||||||||||
| for custom node elements. | ||||||||||||||
| """ | ||||||||||||||
|
|
||||||||||||||
| tag = "Rectangle" | ||||||||||||||
|
|
||||||||||||||
| alias = "RechartsRectangle" | ||||||||||||||
|
|
||||||||||||||
| x: Var[int | float] = field( | ||||||||||||||
| doc="The x-coordinate of the top left corner of the rectangle. Default: 0" | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| y: Var[int | float] = field( | ||||||||||||||
| doc="The y-coordinate of the top left corner of the rectangle. Default: 0" | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| width: Var[int | float] = field(doc="The width of the rectangle. Default: 0") | ||||||||||||||
|
|
||||||||||||||
| height: Var[int | float] = field(doc="The height of the rectangle. Default: 0") | ||||||||||||||
|
|
||||||||||||||
| radius: Var[int | float | Sequence[int | float]] = field( | ||||||||||||||
| doc="The radius of the rectangle's corners. When a number, sets all four corners; when a sequence of four numbers, sets the radii of the top-left, top-right, bottom-right and bottom-left corners. Default: 0" | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| fill: Var[str | Color] = field(doc="The fill color of the rectangle.") | ||||||||||||||
|
|
||||||||||||||
| fill_opacity: Var[float] = field(doc="The opacity of the rectangle fill.") | ||||||||||||||
|
|
||||||||||||||
| stroke: Var[str | Color] = field(doc="The stroke color of the rectangle.") | ||||||||||||||
|
|
||||||||||||||
| stroke_width: Var[str | int | float] = field( | ||||||||||||||
| doc="The width of the rectangle stroke." | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| is_animation_active: Var[bool] = field( | ||||||||||||||
| doc="If set false, animation of the rectangle will be disabled. Default: False" | ||||||||||||||
| ) | ||||||||||||||
|
Comment on lines
+347
to
+349
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When
Suggested change
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keeping the // src/shape/Rectangle.tsx
export const defaultRectangleProps = {
...
isAnimationActive: false,
isUpdateAnimationActive: false,
...
} as const satisfies Partial<Props>;So when the prop is omitted, recharts applies Generated by Claude Code |
||||||||||||||
|
|
||||||||||||||
| is_update_animation_active: Var[bool] = field( | ||||||||||||||
| doc="If set false, the animation of the rectangle when its coordinates or size update will be disabled. Default: False" | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| animation_begin: Var[int] = field( | ||||||||||||||
| doc="Specifies when the animation should begin, the unit of this option is ms. Default: 0" | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| animation_duration: Var[int] = field( | ||||||||||||||
| doc="Specifies the duration of animation, the unit of this option is ms. Default: 1500" | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| animation_easing: Var[LiteralAnimationEasing] = field( | ||||||||||||||
| doc='The type of easing function. Default: "ease"' | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| responsive_container = ResponsiveContainer.create | ||||||||||||||
| legend = Legend.create | ||||||||||||||
| graphing_tooltip = tooltip = GraphingTooltip.create | ||||||||||||||
| label = Label.create | ||||||||||||||
| label_list = LabelList.create | ||||||||||||||
| cell = Cell.create | ||||||||||||||
| layer = Layer.create | ||||||||||||||
| rectangle = Rectangle.create | ||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| from reflex_components_recharts import Layer, Rectangle | ||
|
|
||
|
|
||
| def test_layer(): | ||
| layer = Layer.create().render() | ||
| assert layer["name"] == "RechartsLayer" | ||
|
|
||
|
|
||
| def test_layer_with_children(): | ||
| layer = Layer.create(Rectangle.create()).render() | ||
| assert layer["name"] == "RechartsLayer" | ||
| assert layer["children"][0]["name"] == "RechartsRectangle" | ||
|
|
||
|
|
||
| def test_rectangle(): | ||
| rectangle = Rectangle.create().render() | ||
| assert rectangle["name"] == "RechartsRectangle" | ||
|
|
||
|
|
||
| def test_rectangle_props(): | ||
| rectangle = Rectangle.create( | ||
| x=10, | ||
| y=20.5, | ||
| width=100, | ||
| height=50, | ||
| radius=[4, 4, 0, 0], | ||
| fill="#5192ca", | ||
| fill_opacity=0.8, | ||
| stroke="none", | ||
| stroke_width=2, | ||
| is_animation_active=False, | ||
| ).render() | ||
| props = rectangle["props"] | ||
| assert "x:10" in props | ||
| assert "y:20.5" in props | ||
| assert "width:100" in props | ||
| assert "height:50" in props | ||
| assert "radius:[4, 4, 0, 0]" in props | ||
| assert 'fill:"#5192ca"' in props | ||
| assert "fillOpacity:0.8" in props | ||
| assert 'stroke:"none"' in props | ||
| assert "strokeWidth:2" in props | ||
| assert "isAnimationActive:false" in props |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When users use
Layerto build custom SVG nodes and pass common group attributes such astransformorstyle, those names are not declared on the wrapper, so Reflex treats them as style entries and this subclass then inheritsRecharts._get_style, which serializes them aswrapperStyle. RechartsLayerexpects normal SVG attributes on its<g>element, notwrapperStyle, so translated/styled custom node groups are silently rendered without those attributes.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, and accurate — an undeclared kwarg (or
style=) folds intoself.style, whichRecharts._get_styleemits aswrapperStyle, and recharts drops that on the bare<g>/<path>. Note this is the shared behavior of every recharts SVG-element wrapper (e.g.Cell), not something specific to these two, so I've kept it consistent here rather than diverging from the base_get_styleconvention in this PR.For the custom-node use case the practical paths are:
x/y/width/height/fill/stroke/… all serialize correctly;class_name— merged onto the<g>/recharts-layergroup;custom_attrs={"transform": "translate(…)"}— raw SVG attributes pass straight through to the element.Forwarding
styleto the SVG element for the whole recharts package (or just these primitives) is a reasonable follow-up, but it's a convention change I'd rather make deliberately across the package than one-off here.Generated by Claude Code