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 draw the weekly visitor trends of the Seoul and Busan branches as two lines, so we can compare how they move differently.
rx.recharts.line_chart joins points with lines to show change over time. Use it when the ups and downs and the overall trend matter more than the sizes themselves. Give the chart container data and add one rx.recharts.line(data_key=…) per series.
The examples below use this linechart_data. Even without a color, lines are drawn in the theme's accent color.
linechart_data = [
{"week": "W1", "seoul": 4000, "busan": 2400},
{"week": "W2", "seoul": 3000, "busan": 1398},
{"week": "W3", "seoul": 2000, "busan": 5800},
{"week": "W4", "seoul": 2780, "busan": 3908},
{"week": "W5", "seoul": 1890, "busan": 4800},
{"week": "W6", "seoul": 2390, "busan": 3800},
{"week": "W7", "seoul": 3490, "busan": 4300},
]
rx.recharts.line_chart(
rx.recharts.line(data_key="seoul"),
rx.recharts.line(data_key="busan"),
rx.recharts.x_axis(data_key="week"),
rx.recharts.y_axis(),
data=linechart_data,
width="100%",
height=250,
)Most of a line's look is set on line. Wednesday's value in this data is None, so toggling connect_nulls shows the gap either bridged or left empty.
Try the props
curve
color
stroke_width
2
dash
dot
connect_nulls
hide
rx.recharts.line_chart(
rx.recharts.line(
data_key="sales",
type_="monotone",
stroke=rx.color("indigo", 9),
stroke_width=2,
stroke_dasharray="",
dot=True,
connect_nulls=False,
hide=False,
),
rx.recharts.x_axis(data_key="day"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
data=[
{"day": "Mon", "sales": 12},
{"day": "Tue", "sales": 18},
{"day": "Wed", "sales": None},
{"day": "Thu", "sales": 15},
{"day": "Fri", "sales": 24},
{"day": "Sat", "sales": 20},
],
width="100%",
height=250,
)| Prop | Values | Default | Use |
|---|---|---|---|
line_chart(data=) | list of dicts | none | Data used by the whole chart |
line_chart(layout=) | "horizontal" "vertical" | "horizontal" | Horizontal or vertical flow |
line_chart(margin=, sync_id=) | dict / string | none | Space around the chart; link with other charts |
line(data_key=) | string | none | Key of the value to draw |
line(type_=) | "monotone" "linear" "natural" "step" … | none (straight) | How points are joined |
line(stroke=, stroke_width=) | color / number | accent 9 / 1 | Line color and thickness |
line(stroke_dasharray=) | string such as "5 5" | none | Dashed line |
line(dot=, active_dot=) | True / False / dict | accent dot | Data points; the dot shown on hover |
line(connect_nulls=) | True / False | False | Draw across empty values |
line(hide=) | True / False | False | Hides the line |
line(name=, unit=, legend_type=) | string | Tooltip and legend name, unit, legend icon | |
line(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 line. line also has on_animation_start and on_animation_end |
Chart parts attach as soon as you add them as children. cartesian_grid is the background grid, graphing_tooltip shows the values where the mouse is, and legend labels the series. Give each line type_="monotone" and the jagged lines become smooth curves.
linechart_data = [
{"week": "W1", "seoul": 4000, "busan": 2400},
{"week": "W2", "seoul": 3000, "busan": 1398},
{"week": "W3", "seoul": 2000, "busan": 5800},
{"week": "W4", "seoul": 2780, "busan": 3908},
{"week": "W5", "seoul": 1890, "busan": 4800},
{"week": "W6", "seoul": 2390, "busan": 3800},
{"week": "W7", "seoul": 3490, "busan": 4300},
]
rx.recharts.line_chart(
rx.recharts.line(data_key="seoul", type_="monotone", stroke=rx.color("accent", 9)),
rx.recharts.line(data_key="busan", type_="monotone", stroke=rx.color("teal", 9)),
rx.recharts.x_axis(data_key="week"),
rx.recharts.y_axis(),
rx.recharts.cartesian_grid(stroke_dasharray="3 3"),
rx.recharts.graphing_tooltip(),
rx.recharts.legend(),
data=linechart_data,
width="100%",
height=280,
)Put an rx.recharts.label inside an axis as a child to give it a title. Stand the y-axis title upright with custom_attrs={"angle": 270}. Leave room for the titles with a generous x-axis height and chart margin. The label position values are covered in detail on the Label page among the chart parts.
linechart_data = [
{"week": "W1", "seoul": 4000, "busan": 2400},
{"week": "W2", "seoul": 3000, "busan": 1398},
{"week": "W3", "seoul": 2000, "busan": 5800},
{"week": "W4", "seoul": 2780, "busan": 3908},
{"week": "W5", "seoul": 1890, "busan": 4800},
{"week": "W6", "seoul": 2390, "busan": 3800},
{"week": "W7", "seoul": 3490, "busan": 4300},
]
rx.recharts.line_chart(
rx.recharts.line(
data_key="seoul",
stroke=rx.color("accent", 9),
stroke_width=2,
type_="natural",
),
rx.recharts.x_axis(
rx.recharts.label(value="Week", position="center"),
data_key="week",
height=60,
axis_line=False,
tick_line=False,
),
rx.recharts.y_axis(
rx.recharts.label(value="Visits", position="left", custom_attrs={"angle": 270}),
axis_line=False,
tick_line=False,
),
rx.recharts.graphing_tooltip(),
data=linechart_data,
margin={"left": 20, "right": 20, "top": 20},
width="100%",
height=300,
)With layout="vertical" the lines flow from top to bottom. Switch the x-axis to numbers (type_="number") and the y-axis to categories (type_="category"), and set margin on all four sides so labels don't get cut off.
linechart_data = [
{"week": "W1", "seoul": 4000, "busan": 2400},
{"week": "W2", "seoul": 3000, "busan": 1398},
{"week": "W3", "seoul": 2000, "busan": 5800},
{"week": "W4", "seoul": 2780, "busan": 3908},
{"week": "W5", "seoul": 1890, "busan": 4800},
{"week": "W6", "seoul": 2390, "busan": 3800},
{"week": "W7", "seoul": 3490, "busan": 4300},
]
rx.recharts.line_chart(
rx.recharts.line(data_key="seoul", stroke=rx.color("accent", 9)),
rx.recharts.line(data_key="busan", stroke=rx.color("teal", 9)),
rx.recharts.x_axis(type_="number"),
rx.recharts.y_axis(data_key="week", type_="category"),
data=linechart_data,
layout="vertical",
margin={"top": 20, "right": 20, "left": 20, "bottom": 20},
width="100%",
height=300,
)data and type_ are connected to State values. Press the button and the values wobble a little; the two select boxes change each line's shape independently. State lives separately in each browser tab, so other people's screens are unaffected. Using two axes with y_axis_id and linking charts with sync_id are covered on the area chart page.
import random
from typing import Any
class LineChartLiveState(rx.State):
data: list[dict[str, Any]] = [
{"week": "W1", "seoul": 4000, "busan": 2400},
{"week": "W2", "seoul": 3000, "busan": 1398},
{"week": "W3", "seoul": 2000, "busan": 5800},
{"week": "W4", "seoul": 2780, "busan": 3908},
{"week": "W5", "seoul": 1890, "busan": 4800},
]
seoul_type: str = "monotone"
busan_type: str = "monotone"
@rx.event
def set_seoul_type(self, value: str):
self.seoul_type = value
@rx.event
def set_busan_type(self, value: str):
self.busan_type = value
@rx.event
def munge(self):
self.data = [
{**row, "seoul": row["seoul"] + random.randint(-500, 500), "busan": row["busan"] + random.randint(-1000, 1000)}
for row in self.data
]
rx.vstack(
rx.recharts.line_chart(
rx.recharts.line(data_key="seoul", type_=LineChartLiveState.seoul_type, stroke=rx.color("accent", 9)),
rx.recharts.line(data_key="busan", type_=LineChartLiveState.busan_type, stroke=rx.color("teal", 9)),
rx.recharts.x_axis(data_key="week"),
rx.recharts.y_axis(),
data=LineChartLiveState.data,
margin={"top": 20, "right": 20, "left": 20, "bottom": 20},
width="100%",
height=280,
),
rx.hstack(
rx.button("Munge data", on_click=LineChartLiveState.munge),
rx.select(
["monotone", "linear", "step", "stepBefore", "stepAfter"],
value=LineChartLiveState.seoul_type,
on_change=LineChartLiveState.set_seoul_type,
),
rx.select(
["monotone", "linear", "step", "stepBefore", "stepAfter"],
value=LineChartLiveState.busan_type,
on_change=LineChartLiveState.set_busan_type,
),
wrap="wrap",
),
width="100%",
)The two branches' lines are told apart by both color and line style (solid and dashed). Not relying on color alone keeps the chart readable in black-and-white print and for color-blind users.
linechart_data = [
{"week": "W1", "seoul": 4000, "busan": 2400},
{"week": "W2", "seoul": 3000, "busan": 1398},
{"week": "W3", "seoul": 2000, "busan": 5800},
{"week": "W4", "seoul": 2780, "busan": 3908},
{"week": "W5", "seoul": 1890, "busan": 4800},
{"week": "W6", "seoul": 2390, "busan": 3800},
{"week": "W7", "seoul": 3490, "busan": 4300},
]
rx.recharts.line_chart(
rx.recharts.cartesian_grid(stroke_dasharray="3 3", vertical=False),
rx.recharts.line(data_key="seoul", name="Seoul", type_="monotone", stroke=rx.color("accent", 9), stroke_width=2),
rx.recharts.line(
data_key="busan",
name="Busan",
type_="monotone",
stroke=rx.color("teal", 9),
stroke_width=2,
stroke_dasharray="5 4",
),
rx.recharts.x_axis(data_key="week"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
rx.recharts.legend(),
data=linechart_data,
width="100%",
height=300,
)Workshop notes
Put one line(data_key=…) per series inside line_chart(data=…).
type_ sets how points are joined (monotone, linear, step…); stroke, stroke_width and stroke_dasharray shape the line.
dot for points, connect_nulls to bridge empty values, hide to hide a line.
Axis titles are rx.recharts.label inside the axis; make room with margin and the axis height.
Give data and type_ State values and buttons and select boxes change the chart.
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.