组件工坊:Reflex 组件库 100 例
·
课程概览
布局
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
排版
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
表单
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
数据展示
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
展开与切换
·
Tabs
·
Accordion
·
Segmented Control
浮层
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
动态渲染
·
Cond
·
Match
·
Foreach
·
Auto Scroll
媒体
·
Image
·
Audio
·
Video
表格与数据网格
·
Table
·
Data Table
·
Data Editor
图表
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
图表部件
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
其他图表库
·
Plotly
·
Pyplot
HTML 元素
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
其他工具
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
工坊订单
请把各门店的咖啡和茶的销量并排立起来,方便比较哪家店哪样卖得多。
rx.recharts.bar_chart 为每个项目立一根柱子来比较大小。比较门店销售额、各类别数量这类彼此独立的项目时,它是首选。把 data 交给图表容器,再为每个要画的系列放一个 rx.recharts.bar(data_key=…)。
本页的示例大多使用下面这份 barchart_data。
barchart_data = [
{"store": "North", "coffee": 4000, "tea": 2400},
{"store": "South", "coffee": 3000, "tea": 1398},
{"store": "East", "coffee": 2000, "tea": 5800},
{"store": "West", "coffee": 2780, "tea": 3908},
{"store": "Center", "coffee": 1890, "tea": 4800},
]
rx.recharts.bar_chart(
rx.recharts.bar(data_key="coffee", fill=rx.color("accent", 8)),
rx.recharts.x_axis(data_key="store"),
rx.recharts.y_axis(),
data=barchart_data,
width="100%",
height=250,
)放两个 bar,同一个项目里就会并排立两根柱子。试着改一改项目之间的间距(bar_category_gap)、同一项目内柱子之间的间距(bar_gap),以及柱子背后的灰色背景(background)。
试着改属性
color
bar_category_gap
bar_gap
background
rx.recharts.bar_chart(
rx.recharts.bar(
data_key="coffee",
fill=rx.color("indigo", 8),
background=False,
),
rx.recharts.bar(
data_key="tea",
fill=rx.color("teal", 8),
background=False,
),
rx.recharts.x_axis(data_key="store"),
rx.recharts.y_axis(),
data=barchart_data,
bar_category_gap="10%",
bar_gap="5%",
width="100%",
height=250,
)| 属性 | 取值 | 默认值 | 用途 |
|---|---|---|---|
bar_chart(data=) | dict 的列表 | 无 | 整张图表使用的数据 |
bar_chart(layout=) | "horizontal" "vertical" | "horizontal" | 竖向柱子或横向条形 |
bar_chart(bar_category_gap=) | 百分比或数字 | "10%" | 项目与项目之间的间距 |
bar_chart(bar_gap=) | 百分比或数字 | 4 | 同一项目内柱子之间的间距 |
bar_chart(bar_size=, max_bar_size=) | 数字 | 自动 | 所有柱子的粗细、粗细的上限 |
bar_chart(stack_offset=) | "none" "expand" "wiggle" "silhouette" | "none" | 堆叠柱子的基准计算方式 |
bar_chart(reverse_stack_order=) | True / False | False | 反转堆叠顺序 |
bar_chart(sync_id=, margin=) | 字符串 / dict | 无 | 与其他图表联动、四周留白 |
bar(data_key=) | 字符串 | 无 | 要绘制的值的键。值为 [低值, 高值] 时画范围柱 |
bar(fill=, stroke=) | 颜色 | accent 9 / 无 | 柱子颜色和边框颜色 |
bar(stack_id=) | 字符串 | 无 | 值相同的系列向上堆叠 |
bar(radius=) | 数字或 [左上, 右上, 右下, 左下] | 0 | 圆角大小 |
bar(background=) | True / False | False | 柱子所在位置的背景 |
bar(min_point_size=) | 数字 | 无 | 接近 0 的值也至少显示这么高 |
bar(name=, unit=, label=) | 字符串 / bool | 提示框和图例的名称、单位、柱顶数字 | |
on_click on_mouse_enter … | 事件 | 图表、bar、cell 都能接收 |
stack_id 相同的 bar 会在一根柱子上依次堆叠,整根柱子的高度就是总和。给图表加上 stack_offset="expand",所有柱子一样高,只剩下各部分的比例。
barchart_data = [
{"store": "North", "coffee": 4000, "tea": 2400},
{"store": "South", "coffee": 3000, "tea": 1398},
{"store": "East", "coffee": 2000, "tea": 5800},
{"store": "West", "coffee": 2780, "tea": 3908},
{"store": "Center", "coffee": 1890, "tea": 4800},
]
rx.flex(
rx.recharts.bar_chart(
rx.recharts.bar(data_key="coffee", stack_id="1", fill=rx.color("accent", 8)),
rx.recharts.bar(data_key="tea", stack_id="1", fill=rx.color("teal", 8)),
rx.recharts.x_axis(data_key="store"),
rx.recharts.y_axis(),
rx.recharts.legend(),
data=barchart_data,
width="100%",
height=250,
),
rx.recharts.bar_chart(
rx.recharts.bar(data_key="coffee", stack_id="1", fill=rx.color("accent", 8)),
rx.recharts.bar(data_key="tea", stack_id="1", fill=rx.color("teal", 8)),
rx.recharts.x_axis(data_key="store"),
rx.recharts.y_axis(),
rx.recharts.legend(),
data=barchart_data,
stack_offset="expand",
width="100%",
height=250,
),
direction="column",
spacing="4",
width="100%",
)如果 data_key 指向的值不是一个数字,而是 [低值, 高值] 两个数,柱子就不从 0 开始,而是从低值开始、到高值结束。适合展示一天的最低和最高气温这类范围。
rx.recharts.bar_chart(
rx.recharts.bar(
data_key="temperature",
stroke=rx.color("accent", 9),
fill=rx.color("accent", 7),
),
rx.recharts.x_axis(data_key="day"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
data=[
{"day": "Mon", "temperature": [-1, 10]},
{"day": "Tue", "temperature": [2, 15]},
{"day": "Wed", "temperature": [3, 12]},
{"day": "Thu", "temperature": [4, 12]},
{"day": "Fri", "temperature": [12, 16]},
{"day": "Sat", "temperature": [5, 16]},
{"day": "Sun", "temperature": [0, 8]},
],
width="100%",
height=250,
)bar_size 以像素为单位设定所有柱子的粗细,max_bar_size 设定粗细的上限。下面的示例虽然写了 bar_size=100,但 max_bar_size=24 优先,所以柱子不会超过 24 像素。项目很少时,用它可以防止柱子胖得离谱。
barchart_data = [
{"store": "North", "coffee": 4000, "tea": 2400},
{"store": "South", "coffee": 3000, "tea": 1398},
{"store": "East", "coffee": 2000, "tea": 5800},
{"store": "West", "coffee": 2780, "tea": 3908},
{"store": "Center", "coffee": 1890, "tea": 4800},
]
rx.recharts.bar_chart(
rx.recharts.bar(data_key="coffee", fill=rx.color("accent", 8)),
rx.recharts.bar(data_key="tea", fill=rx.color("teal", 8)),
rx.recharts.x_axis(data_key="store"),
rx.recharts.y_axis(),
data=barchart_data,
bar_category_gap="15%",
bar_gap=6,
bar_size=100,
max_bar_size=24,
width="100%",
height=250,
)给 radius 一个数字,四个角都会变圆;给 [8, 8, 0, 0] 这样的列表,就按左上、右上、右下、左下的顺序分别设定。只把上方做圆,柱子看起来就像稳稳立在底部。填充色和面积图一样,可以用 url(#id) 引用 rx.el.svg.defs 里的渐变。
barchart_data = [
{"store": "North", "coffee": 4000, "tea": 2400},
{"store": "South", "coffee": 3000, "tea": 1398},
{"store": "East", "coffee": 2000, "tea": 5800},
{"store": "West", "coffee": 2780, "tea": 3908},
{"store": "Center", "coffee": 1890, "tea": 4800},
]
rx.recharts.bar_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.9),
rx.el.svg.stop(offset="95%", stop_color=rx.color("accent", 9), stop_opacity=0.2),
id="barchart_gradient",
x1=0,
y1=0,
x2=0,
y2=1,
),
),
rx.recharts.bar(
data_key="coffee",
fill=rx.color("teal", 8),
radius=8,
),
rx.recharts.bar(
data_key="tea",
fill="url(#barchart_gradient)",
radius=[8, 8, 0, 0],
),
rx.recharts.x_axis(data_key="store"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
data=barchart_data,
width="100%",
height=250,
)设置 layout="vertical" 后,柱子从左向右伸展,变成横向条形图。把 x 轴改为数值(type_="number"),y 轴改为类别(type_="category")。项目名称较长时更易读。
barchart_data = [
{"store": "North", "coffee": 4000, "tea": 2400},
{"store": "South", "coffee": 3000, "tea": 1398},
{"store": "East", "coffee": 2000, "tea": 5800},
{"store": "West", "coffee": 2780, "tea": 3908},
{"store": "Center", "coffee": 1890, "tea": 4800},
]
rx.recharts.bar_chart(
rx.recharts.bar(
data_key="coffee",
stroke=rx.color("accent", 8),
fill=rx.color("accent", 4),
),
rx.recharts.x_axis(type_="number"),
rx.recharts.y_axis(data_key="store", type_="category"),
data=barchart_data,
layout="vertical",
margin={"top": 20, "right": 20, "left": 20, "bottom": 20},
width="100%",
height=280,
)把 State 的值接到 data 上,值变化时柱子会以动画方式长高。下面的图表点击任意位置(bar_chart 的 on_click),数字都会重新生成。
import random
from typing import Any
class BarChartLiveState(rx.State):
data: list[dict[str, Any]] = [
{"store": "North", "coffee": 4000, "tea": 2400},
{"store": "South", "coffee": 3000, "tea": 1398},
{"store": "East", "coffee": 2000, "tea": 5800},
{"store": "West", "coffee": 2780, "tea": 3908},
]
@rx.event
def shuffle(self):
self.data = [
{**row, "coffee": random.randint(500, 6000), "tea": random.randint(500, 6000)}
for row in self.data
]
rx.recharts.bar_chart(
rx.recharts.cartesian_grid(stroke_dasharray="3 3"),
rx.recharts.bar(data_key="coffee", fill=rx.color("accent", 8)),
rx.recharts.bar(data_key="tea", fill=rx.color("teal", 8)),
rx.recharts.x_axis(data_key="store"),
rx.recharts.y_axis(),
rx.recharts.legend(),
on_click=BarChartLiveState.shuffle,
data=BarChartLiveState.data,
width="100%",
height=280,
)要给每根柱子绑定不同的行为,就用 rx.recharts.cell。在 bar 里用 rx.foreach 按数据条数生成 cell,每个 cell 负责同一顺序位置上的柱子。把该项目的名称传给那个 cell 的 on_click,就能做出只保留被点击柱子的下钻效果。再点同一根柱子则回到全部数据。
foreach 的函数接收 (item, index),返回一个 cell。toggle(item["name"].to(str)))。rx.cond 只给选中的柱子换个颜色。data 本身是计算变量(rows),所以选中后图表只重新绘制该项目。同样的方法也适用于饼图(把 cell 放进 pie 里)。
barchart_genres = [
{"name": "Fiction", "count": 42},
{"name": "History", "count": 28},
{"name": "Science", "count": 35},
{"name": "Biography", "count": 17},
{"name": "Fantasy", "count": 24},
]
barchart_colors = ["#6366F1", "#8B5CF6", "#A855F7", "#D946EF", "#EC4899"]
class BarChartDrillState(rx.State):
picked: str = ""
@rx.var
def rows(self) -> list[dict[str, str | int]]:
if self.picked:
return [g for g in barchart_genres if g["name"] == self.picked]
return barchart_genres
@rx.event
def toggle(self, name: str):
self.picked = "" if self.picked == name else name
rx.recharts.bar_chart(
rx.recharts.cartesian_grid(stroke_dasharray="3 3", vertical=False),
rx.recharts.x_axis(data_key="name", tick_line=False, axis_line=False),
rx.recharts.y_axis(allow_decimals=False, axis_line=False, tick_line=False),
rx.recharts.bar(
rx.foreach(
BarChartDrillState.rows,
lambda item, index: rx.recharts.cell(
on_click=BarChartDrillState.toggle(item["name"].to(str)),
custom_attrs={"cursor": "pointer"},
fill=rx.cond(
BarChartDrillState.picked == item["name"],
"#1D4ED8",
rx.Var.create(barchart_colors)[index % 5],
),
),
),
data_key="count",
radius=[4, 4, 0, 0],
),
rx.recharts.graphing_tooltip(),
data=BarChartDrillState.rows,
width="100%",
height=280,
)每家门店的咖啡和茶柱子并排立起,只把顶部修成圆角。用 max_bar_size 防止柱子过粗,再用提示框和图例读出数值和名称。
barchart_data = [
{"store": "North", "coffee": 4000, "tea": 2400},
{"store": "South", "coffee": 3000, "tea": 1398},
{"store": "East", "coffee": 2000, "tea": 5800},
{"store": "West", "coffee": 2780, "tea": 3908},
{"store": "Center", "coffee": 1890, "tea": 4800},
]
rx.recharts.bar_chart(
rx.recharts.cartesian_grid(stroke_dasharray="3 3", vertical=False),
rx.recharts.bar(data_key="coffee", name="Coffee", fill=rx.color("accent", 8), radius=[4, 4, 0, 0]),
rx.recharts.bar(data_key="tea", name="Tea", fill=rx.color("teal", 8), radius=[4, 4, 0, 0]),
rx.recharts.x_axis(data_key="store"),
rx.recharts.y_axis(),
rx.recharts.graphing_tooltip(),
rx.recharts.legend(),
data=barchart_data,
bar_gap=2,
max_bar_size=32,
width="100%",
height=300,
)工坊笔记
在 bar_chart(data=…) 里为每个系列放 bar(data_key=…) 就会并排;stack_id 一致就会堆叠。
stack_offset="expand" 是 100% 柱;data_key 的值为 [低值, 高值] 时是范围柱。
间距用 bar_category_gap、bar_gap,粗细用 bar_size、max_bar_size,圆角用 radius。
layout="vertical" 是横向条形,坐标轴的 type_ 也要一起改。
想让每根柱子颜色或点击行为不同,就在 bar 里用 foreach 放入 rx.recharts.cell。
订阅新课时和新课程通知
本课程新增课时或推出后续课程时,我们会发邮件通知你。
问答
关于本课有任何疑问都可以在这里留言。所有语言版本页面的提问会汇集在一起。