The Component Workshop: Reflex's 100 Library Components
·
Course overview
Layout
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
Typography
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
Forms
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
Data display
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
Disclosure
·
Tabs
·
Accordion
·
Segmented Control
Overlay
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
Dynamic rendering
·
Cond
·
Match
·
Foreach
·
Auto Scroll
Media
·
Image
·
Audio
·
Video
Tables and data grids
·
Table
·
Data Table
·
Data Editor
Charts
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
Chart parts
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
Other chart libraries
·
Plotly
·
Pyplot
HTML elements
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
Other tools
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
Workshop order
Please make a graph that stacks monthly web and app visitors, so the overall trend and each one's share are visible at a glance.
rx.recharts.area_chart is an area chart: a line with the space beneath it filled in. Use it to show how a quantity changes over time, together with the total size of several values added up. You give the chart container (area_chart) the data, and put the series to draw (area) and the axes inside it as children.
The data is a list of dicts. Each dict is one slot on the x-axis, and data_key is the key that picks which value in that dict to draw. Every example on this page uses the areachart_data below.
areachart_data = [
{"month": "Jan", "web": 4000, "app": 2400},
{"month": "Feb", "web": 3000, "app": 1398},
{"month": "Mar", "web": 2000, "app": 5800},
{"month": "Apr", "web": 2780, "app": 3908},
{"month": "May", "web": 1890, "app": 4800},
{"month": "Jun", "web": 2390, "app": 3800},
]
rx.recharts.area_chart(
rx.recharts.area(data_key="web"),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(),
data=areachart_data,
width="100%",
height=250,
)A chart's width and height accept only numbers (pixels) or percentage strings such as "100%". CSS units like "20em" go on the box that wraps the chart. Axes (x_axis, y_axis), grids, tooltips and legends are covered in detail on the chart parts pages; here we use only what we need.
The two areas are stacked with stack_id="1". Change the curve shape, color, stroke width, dots and stacking mode. The data is areachart_data from above.
Try the props
curve
color
stroke_width
1
dot
stack_offset
rx.recharts.area_chart(
rx.recharts.area(
data_key="web",
type_="monotone",
stroke=rx.color("indigo", 9),
fill=rx.color("indigo", 5),
stroke_width=1,
dot=False,
stack_id="1",
),
rx.recharts.area(
data_key="app",
type_="monotone",
stroke=rx.color("teal", 9),
fill=rx.color("teal", 5),
stroke_width=1,
dot=False,
stack_id="1",
),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
data=areachart_data,
stack_offset="none",
width="100%",
height=250,
)| Prop | Values | Default | Use |
|---|---|---|---|
area_chart(data=) | list of dicts | none | Data used by the whole chart |
area_chart(width=, height=) | number or "100%" | "100%" | Chart size. A numeric height is the safe choice |
area_chart(layout=) | "horizontal" "vertical" | "horizontal" | Horizontal or vertical flow |
area_chart(stack_offset=) | "none" "expand" "wiggle" "silhouette" | none | How the baseline of stacked areas is computed |
area_chart(sync_id=) | string | none | Charts with the same value move their tooltips and brushes together |
area_chart(margin=) | {"top": 5, ...} | none | Space around the chart |
area_chart(base_value=) | number, "dataMin" "dataMax" "auto" | "auto" | The floor value the area starts from |
area(data_key=) | string | none | Key of the value to draw |
area(type_=) | "monotone" "linear" "natural" "step" … | "monotone" | Curve interpolation |
area(stroke=, fill=) | color | accent 9 / accent 5 | Line color and fill color |
area(stroke_width=) | number | 1 | Line thickness |
area(dot=, active_dot=) | True / False / dict | False / accent dot | Show dots; the dot shown on hover |
area(stack_id=) | string | none | Areas with the same value stack on top of each other |
area(name=, unit=) | string | data_key | Name and unit shown in the tooltip and legend |
area(connect_nulls=) | True / False | False | Draw across empty values (None) |
area(x_axis_id=, y_axis_id=) | string or number | 0 | Which axis it attaches to |
on_click on_mouse_enter … | events | Accepted by both the chart and the area. area also has on_animation_start and on_animation_end |
areas with the same stack_id stack one on top of another from the bottom up. The top edge becomes the total, so you can read the overall size and each part at the same time. stack_offset sets the stacking baseline: usually "none", and "expand" when you only care about proportions.
areachart_data = [
{"month": "Jan", "web": 4000, "app": 2400},
{"month": "Feb", "web": 3000, "app": 1398},
{"month": "Mar", "web": 2000, "app": 5800},
{"month": "Apr", "web": 2780, "app": 3908},
{"month": "May", "web": 1890, "app": 4800},
{"month": "Jun", "web": 2390, "app": 3800},
]
rx.recharts.area_chart(
rx.recharts.area(
data_key="web",
stroke=rx.color("accent", 9),
fill=rx.color("accent", 6),
stack_id="1",
),
rx.recharts.area(
data_key="app",
stroke=rx.color("teal", 9),
fill=rx.color("teal", 6),
stack_id="1",
),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(),
rx.recharts.legend(),
data=areachart_data,
stack_offset="none",
margin={"top": 5, "right": 5, "bottom": 5, "left": 5},
width="100%",
height=280,
)Painting the area dark at the top and transparent at the bottom makes the line stand out. Define an SVG gradient inside the chart with rx.el.svg.defs and point to it with fill="url(#id)". Give each gradient an id that is unique on the page.
areachart_data = [
{"month": "Jan", "web": 4000, "app": 2400},
{"month": "Feb", "web": 3000, "app": 1398},
{"month": "Mar", "web": 2000, "app": 5800},
{"month": "Apr", "web": 2780, "app": 3908},
{"month": "May", "web": 1890, "app": 4800},
{"month": "Jun", "web": 2390, "app": 3800},
]
rx.recharts.area_chart(
rx.el.svg.defs(
rx.el.svg.linear_gradient(
rx.el.svg.stop(offset="5%", stop_color=rx.color("accent", 9), stop_opacity=0.8),
rx.el.svg.stop(offset="95%", stop_color=rx.color("accent", 9), stop_opacity=0),
id="areachart_gradient",
x1=0,
x2=0,
y1=0,
y2=1,
),
),
rx.recharts.area(
data_key="web",
stroke=rx.color("accent", 9),
fill="url(#areachart_gradient)",
type_="natural",
),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
data=areachart_data,
width="100%",
height=280,
)When you draw two values of completely different magnitudes on one chart, give it two axes. Name each axis with y_axis_id and connect each area to it with the same y_axis_id. The x-axis works the same way with x_axis_id. Two scales confuse readers easily, though, so use this only when the units really differ.
areachart_data = [
{"month": "Jan", "web": 4000, "app": 2400},
{"month": "Feb", "web": 3000, "app": 1398},
{"month": "Mar", "web": 2000, "app": 5800},
{"month": "Apr", "web": 2780, "app": 3908},
{"month": "May", "web": 1890, "app": 4800},
{"month": "Jun", "web": 2390, "app": 3800},
]
rx.recharts.area_chart(
rx.recharts.area(
data_key="web",
stroke=rx.color("accent", 9),
fill=rx.color("accent", 5),
y_axis_id="left",
),
rx.recharts.area(
data_key="app",
stroke=rx.color("teal", 9),
fill=rx.color("teal", 5),
y_axis_id="right",
),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(y_axis_id="left"),
rx.recharts.y_axis(y_axis_id="right", orientation="right"),
rx.recharts.graphing_tooltip(),
rx.recharts.legend(),
data=areachart_data,
width="100%",
height=280,
)With layout="vertical" the areas flow from top to bottom. The axes swap roles too: the x-axis becomes the numbers (type_="number") and the y-axis the categories (type_="category"). Set margin on all four sides so labels don't get cut off.
areachart_data = [
{"month": "Jan", "web": 4000, "app": 2400},
{"month": "Feb", "web": 3000, "app": 1398},
{"month": "Mar", "web": 2000, "app": 5800},
{"month": "Apr", "web": 2780, "app": 3908},
{"month": "May", "web": 1890, "app": 4800},
{"month": "Jun", "web": 2390, "app": 3800},
]
rx.recharts.area_chart(
rx.recharts.area(
data_key="web",
stroke=rx.color("accent", 8),
fill=rx.color("accent", 3),
),
rx.recharts.x_axis(type_="number"),
rx.recharts.y_axis(data_key="month", type_="category"),
data=areachart_data,
layout="vertical",
margin={"top": 20, "right": 20, "bottom": 20, "left": 20},
width="100%",
height=300,
)Charts with the same sync_id share their tooltip position and brush range. Hover over the top chart and the bottom one shows the tooltip for the same month; narrow the range with the brush below and the top chart narrows with it. You can link area charts with bar, line and composed charts as well.
areachart_data = [
{"month": "Jan", "web": 4000, "app": 2400},
{"month": "Feb", "web": 3000, "app": 1398},
{"month": "Mar", "web": 2000, "app": 5800},
{"month": "Apr", "web": 2780, "app": 3908},
{"month": "May", "web": 1890, "app": 4800},
{"month": "Jun", "web": 2390, "app": 3800},
]
rx.vstack(
rx.recharts.area_chart(
rx.recharts.area(data_key="web", stroke=rx.color("accent", 9), fill=rx.color("accent", 5)),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
data=areachart_data,
sync_id="areachart_sync",
width="100%",
height=180,
),
rx.recharts.area_chart(
rx.recharts.area(data_key="app", stroke=rx.color("teal", 9), fill=rx.color("teal", 5)),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
rx.recharts.brush(data_key="month", height=24),
data=areachart_data,
sync_id="areachart_sync",
width="100%",
height=210,
),
width="100%",
)Give data a State value and the chart redraws with an animation every time the value changes. Here, clicking the button or an area changes the numbers, and the select box changes type_ from State as well. Assigning a whole new list makes sure the change gets through.
import random
from typing import Any
class AreaChartLiveState(rx.State):
data: list[dict[str, Any]] = [
{"month": "Jan", "web": 4000, "app": 2400},
{"month": "Feb", "web": 3000, "app": 1398},
{"month": "Mar", "web": 2000, "app": 5800},
{"month": "Apr", "web": 2780, "app": 3908},
{"month": "May", "web": 1890, "app": 4800},
{"month": "Jun", "web": 2390, "app": 3800},
]
curve: str = "monotone"
@rx.event
def shuffle(self):
self.data = [
{**row, "web": random.randint(500, 6000), "app": random.randint(500, 6000)}
for row in self.data
]
@rx.event
def set_curve(self, value: str):
self.curve = value
rx.vstack(
rx.hstack(
rx.button("Shuffle", on_click=AreaChartLiveState.shuffle),
rx.select(
["monotone", "linear", "natural", "step", "basis"],
value=AreaChartLiveState.curve,
on_change=AreaChartLiveState.set_curve,
),
),
rx.recharts.area_chart(
rx.recharts.area(
data_key="web",
type_=AreaChartLiveState.curve,
on_click=AreaChartLiveState.shuffle,
),
rx.recharts.area(
data_key="app",
type_=AreaChartLiveState.curve,
stroke=rx.color("teal", 9),
fill=rx.color("teal", 5),
on_click=AreaChartLiveState.shuffle,
),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(),
rx.recharts.cartesian_grid(stroke_dasharray="3 3"),
rx.recharts.legend(),
data=AreaChartLiveState.data,
width="100%",
height=300,
),
width="100%",
)The two areas are stacked with the same stack_id, and a gradient fades out the bottom. name sets the label shown in the legend and tooltip, and keeping only the horizontal grid lines gives it a calm look.
areachart_data = [
{"month": "Jan", "web": 4000, "app": 2400},
{"month": "Feb", "web": 3000, "app": 1398},
{"month": "Mar", "web": 2000, "app": 5800},
{"month": "Apr", "web": 2780, "app": 3908},
{"month": "May", "web": 1890, "app": 4800},
{"month": "Jun", "web": 2390, "app": 3800},
]
rx.recharts.area_chart(
rx.el.svg.defs(
rx.el.svg.linear_gradient(
rx.el.svg.stop(offset="5%", stop_color=rx.color("accent", 9), stop_opacity=0.7),
rx.el.svg.stop(offset="95%", stop_color=rx.color("accent", 9), stop_opacity=0.1),
id="areachart_order_web",
x1=0, x2=0, y1=0, y2=1,
),
rx.el.svg.linear_gradient(
rx.el.svg.stop(offset="5%", stop_color=rx.color("teal", 9), stop_opacity=0.7),
rx.el.svg.stop(offset="95%", stop_color=rx.color("teal", 9), stop_opacity=0.1),
id="areachart_order_app",
x1=0, x2=0, y1=0, y2=1,
),
),
rx.recharts.cartesian_grid(stroke_dasharray="3 3", vertical=False),
rx.recharts.area(
data_key="web",
name="Web",
stroke=rx.color("accent", 9),
stroke_width=2,
fill="url(#areachart_order_web)",
stack_id="visits",
),
rx.recharts.area(
data_key="app",
name="App",
stroke=rx.color("teal", 9),
stroke_width=2,
fill="url(#areachart_order_app)",
stack_id="visits",
),
rx.recharts.x_axis(data_key="month"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
rx.recharts.legend(),
data=areachart_data,
width="100%",
height=300,
)Workshop notes
Put area(data_key=…) plus x_axis and y_axis as children inside area_chart(data=list).
width and height take only numbers or percentage strings. CSS units go on the outer box.
The same stack_id stacks areas, and stack_offset="expand" turns it into a 100% proportion chart.
Define gradients in rx.el.svg.defs and use them with fill="url(#id)".
sync_id links tooltips across charts, and a State value in data brings the chart to life.
Get news about new lessons
We'll email you when this course gets new lessons or a follow-up course opens.
R
ReflexKR
Learn Python and Reflex by doing. Every example was run and verified on Reflex 0.10.0.
ReflexKR is free, with no banner ads. If it helped you, you can support it with a coffee. ☕ Buy us a coffee
Affiliate disclosure© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
Questions & answers
Ask anything about this lesson. Questions from every language version of this page appear together.