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
rx.recharts.radar_chartrx.recharts.radarrx.recharts.polar_gridrx.recharts.polar_angle_axisrx.recharts.polar_radius_axisOfficial docs
Workshop order
Please overlay two students' scores per subject as a spiderweb, so it's clear at a glance who is strong in which subject.
rx.recharts.radar_chart plots the scores of several items on axes radiating from the center and joins them into a polygon. Use it to compare the "shape" of subjects across five or six items measured on the same scale. Give the chart data and add one rx.recharts.radar(data_key=…) per series.
Circular charts use polar parts instead of Cartesian axes. polar_grid is the spiderweb grid, polar_angle_axis shows the item names around the edge, and polar_radius_axis is the scale running from the center outward.
radarchart_data = [
{"subject": "Math", "Mina": 120, "Joon": 110},
{"subject": "Science", "Mina": 98, "Joon": 130},
{"subject": "English", "Mina": 86, "Joon": 130},
{"subject": "History", "Mina": 99, "Joon": 100},
{"subject": "Art", "Mina": 85, "Joon": 90},
{"subject": "Music", "Mina": 65, "Joon": 85},
]
rx.recharts.radar_chart(
rx.recharts.radar(data_key="Mina", stroke=rx.color("accent", 9), fill=rx.color("accent", 8)),
rx.recharts.polar_grid(),
rx.recharts.polar_angle_axis(data_key="subject"),
rx.recharts.polar_radius_axis(angle=90, domain=[0, 150]),
data=radarchart_data,
width="100%",
height=300,
)Change the fill strength (fill_opacity), the dots at the vertices (dot), the grid shape (grid_type), and the chart's inner and outer radius. The data is radarchart_data from above.
Try the props
color
fill_opacity
0.6
dot
grid_type
inner_radius
outer_radius
rx.recharts.radar_chart(
rx.recharts.radar(
data_key="Mina",
stroke=rx.color("indigo", 9),
fill=rx.color("indigo", 8),
fill_opacity=0.6,
dot=False,
),
rx.recharts.polar_grid(grid_type="polygon"),
rx.recharts.polar_angle_axis(data_key="subject"),
rx.recharts.polar_radius_axis(angle=90, domain=[0, 150]),
data=radarchart_data,
inner_radius="0%",
outer_radius="80%",
width="100%",
height=300,
)| Prop | Values | Default | Use |
|---|---|---|---|
radar_chart(data=) | list of dicts | none | One dict per item |
radar_chart(cx=, cy=) | number or percentage | "50%" | Center position |
radar_chart(inner_radius=, outer_radius=) | number or percentage | 0 / "80%" | Radius of the inner and outer grid |
radar_chart(start_angle=, end_angle=) | number (degrees) | 90 / -270 | Angle of the first axis and direction of rotation |
radar_chart(margin=) | dict | 0 | Space around the chart |
radar(data_key=) | string | none | Key of the value to draw |
radar(stroke=, fill=, fill_opacity=) | color / 0–1 | accent 9 / accent 3 / 0.6 | Border, fill and fill strength |
radar(dot=) | True / False / dict | none | Dots at the vertices |
radar(legend_type=, label=) | legend icon / bool | "rect" | Legend shape; value labels |
radar(animation_begin=, animation_duration=, animation_easing=) | ms / ms / "ease" … | 0 / 1500 / "ease" | Entrance animation |
polar_grid(grid_type=) | "polygon" "circle" | "polygon" | Grid shape |
polar_radius_axis(angle=, domain=) | number / [min, max] | Direction and range of the scale axis | |
| Events | on_click on_mouse_enter on_mouse_leave | On the chart. radar also has on_animation_start and on_animation_end |
With two radars, the polygons overlap on the same grid. Later series are drawn on top, so lower fill_opacity to let the series underneath show through. The chart's inner_radius and outer_radius set the size of the drawing and the empty space in the middle.
radarchart_data = [
{"subject": "Math", "Mina": 120, "Joon": 110},
{"subject": "Science", "Mina": 98, "Joon": 130},
{"subject": "English", "Mina": 86, "Joon": 130},
{"subject": "History", "Mina": 99, "Joon": 100},
{"subject": "Art", "Mina": 85, "Joon": 90},
{"subject": "Music", "Mina": 65, "Joon": 85},
]
rx.recharts.radar_chart(
rx.recharts.radar(
data_key="Mina",
stroke=rx.color("accent", 9),
fill=rx.color("accent", 8),
),
rx.recharts.radar(
data_key="Joon",
stroke=rx.color("teal", 9),
fill=rx.color("teal", 8),
fill_opacity=0.6,
),
rx.recharts.polar_grid(),
rx.recharts.polar_angle_axis(data_key="subject"),
rx.recharts.polar_radius_axis(angle=90, domain=[0, 150]),
rx.recharts.legend(),
data=radarchart_data,
inner_radius="15%",
outer_radius="80%",
width="100%",
height=300,
)dot=True puts a dot on every vertex, and legend_type="line" turns the legend icon into a line. animation_begin, animation_duration and animation_easing control how it first draws. The example below unfolds slowly over 4 seconds.
radarchart_data = [
{"subject": "Math", "Mina": 120, "Joon": 110},
{"subject": "Science", "Mina": 98, "Joon": 130},
{"subject": "English", "Mina": 86, "Joon": 130},
{"subject": "History", "Mina": 99, "Joon": 100},
{"subject": "Art", "Mina": 85, "Joon": 90},
{"subject": "Music", "Mina": 65, "Joon": 85},
]
rx.recharts.radar_chart(
rx.recharts.radar(
data_key="Mina",
dot=True,
stroke=rx.color("accent", 9),
fill=rx.color("accent", 8),
fill_opacity=0.6,
legend_type="line",
animation_begin=0,
animation_duration=4000,
animation_easing="ease-in",
),
rx.recharts.polar_grid(),
rx.recharts.polar_angle_axis(data_key="subject"),
rx.recharts.polar_radius_axis(angle=90, domain=[0, 150]),
rx.recharts.legend(),
data=radarchart_data,
width="100%",
height=300,
)In this example you distribute 100 points across five traits. Moving a slider changes traits in State and the chart redraws right away. The handler stops you from raising a trait by more than the points you have left. tick=False and axis_line=False on polar_radius_axis hide the scale, leaving only the shape.
Strength
15
Speed
15
Stamina
15
Wisdom
15
Charm
15
Remaining: 25
from typing import Any
class RadarChartTraitState(rx.State):
budget: int = 100
traits: list[dict[str, Any]] = [
{"trait": "Strength", "value": 15},
{"trait": "Speed", "value": 15},
{"trait": "Stamina", "value": 15},
{"trait": "Wisdom", "value": 15},
{"trait": "Charm", "value": 15},
]
@rx.var
def remaining(self) -> int:
return self.budget - sum(t["value"] for t in self.traits)
@rx.event
def set_trait(self, trait: str, value: list[float]):
new = int(value[0])
rows = []
for t in self.traits:
if t["trait"] == trait:
new = min(new, self.remaining + t["value"])
t = {**t, "value": new}
rows.append(t)
self.traits = rows
rx.flex(
rx.box(
rx.recharts.radar_chart(
rx.recharts.radar(data_key="value", stroke=rx.color("accent", 9), fill=rx.color("accent", 8)),
rx.recharts.polar_grid(),
rx.recharts.polar_angle_axis(data_key="trait"),
rx.recharts.polar_radius_axis(domain=[0, 100], tick=False, axis_line=False),
data=RadarChartTraitState.traits,
width="100%",
height=260,
),
flex="1 1 240px",
),
rx.vstack(
rx.foreach(
RadarChartTraitState.traits,
lambda t: rx.hstack(
rx.text(t["trait"], size="2", width="5em"),
rx.slider(
value=[t["value"].to(int)],
max=100,
on_change=lambda v: RadarChartTraitState.set_trait(t["trait"].to(str), v),
width="10em",
),
rx.text(t["value"], size="2"),
align="center",
),
),
rx.text("Remaining: ", RadarChartTraitState.remaining, size="2", weight="bold"),
flex="1 1 240px",
),
spacing="4",
wrap="wrap",
align="center",
width="100%",
)The data keys are the students' names ("Mina", "Joon"), so those names show up as-is in the legend and tooltip. radar has no name prop in 0.10, so giving the keys readable names is the simplest approach. Both are lightly filled with fill_opacity=0.4 so the overlap stays readable, and color and dots together tell the series apart.
radarchart_data = [
{"subject": "Math", "Mina": 120, "Joon": 110},
{"subject": "Science", "Mina": 98, "Joon": 130},
{"subject": "English", "Mina": 86, "Joon": 130},
{"subject": "History", "Mina": 99, "Joon": 100},
{"subject": "Art", "Mina": 85, "Joon": 90},
{"subject": "Music", "Mina": 65, "Joon": 85},
]
rx.recharts.radar_chart(
rx.recharts.polar_grid(),
rx.recharts.polar_angle_axis(data_key="subject"),
rx.recharts.polar_radius_axis(angle=90, domain=[0, 150], tick=False, axis_line=False),
rx.recharts.radar(
data_key="Mina",
stroke=rx.color("accent", 9),
fill=rx.color("accent", 8),
fill_opacity=0.4,
dot=True,
),
rx.recharts.radar(
data_key="Joon",
stroke=rx.color("teal", 9),
fill=rx.color("teal", 8),
fill_opacity=0.4,
dot=True,
),
rx.recharts.graphing_tooltip(),
rx.recharts.legend(),
data=radarchart_data,
width="100%",
height=320,
)Workshop notes
Put radar(data_key=…) and polar_grid, polar_angle_axis and polar_radius_axis inside radar_chart(data=…).
polar_angle_axis(data_key=) gives the item names around the edge; polar_radius_axis(domain=) the scale range.
Multiple series means multiple radars. Lower fill_opacity so overlaps show.
The chart's inner_radius, outer_radius, start_angle and end_angle set its shape and direction.
Give data a State value and inputs such as sliders reshape the polygon instantly.
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.