如何在Recharts柱状图的每个柱子下方添加复选框?
在Recharts柱状图的X轴刻度下方添加复选框的实现方法
可以通过自定义X轴刻度组件,结合SVG的<foreignObject>标签嵌入HTML复选框来实现需求。具体实现如下:
核心思路
Recharts的XAxis支持通过tick属性传入自定义组件,虽然官方示例多使用SVG元素,但我们可以利用SVG的<foreignObject>标签在刻度区域嵌入HTML元素,从而添加可交互的复选控件。
完整代码实现
import React, { useState } from 'react'; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ReferenceLine, ResponsiveContainer, LabelList, } from 'recharts'; const data = [ { name: 'Ingredient 1', deviation: 9, data: { alertCount: 8, deviation: 9, }, fill: '#007DC5', }, { name: 'Ingredient 2', deviation: 144, data: { alertCount: 7, deviation: 144, }, fill: '#007DC5', }, { name: 'Ingredient 3', deviation: -10, data: { alertCount: 4, deviation: -10, }, fill: '#E46A68', }, { name: 'Ingredient 4', deviation: -212, data: { alertCount: 8, deviation: -212, }, fill: '#E46A68', }, { name: 'Ingredient 5', deviation: 25, data: { alertCount: 3, deviation: 25, }, fill: '#007DC5', }, ]; // 自定义X轴刻度组件,包含复选框和标签文本 const CustomizedAxisTick = ({ x, y, payload }) => { return ( <g transform={`translate(${x},${y})`}> <foreignObject width="80" height="40" x="-40" y="10"> <div style={{ textAlign: 'center', fontSize: '12px' }}> <input type="checkbox" style={{ marginBottom: '4px' }} /> <div>{payload.value}</div> </div> </foreignObject> </g> ); }; export const LoadDeviationWidgetL = () => { // 可选:管理复选框选中状态 const [checkedItems, setCheckedItems] = useState([]); const handleCheckboxChange = (itemName, isChecked) => { setCheckedItems(prev => isChecked ? [...prev, itemName] : prev.filter(item => item !== itemName) ); }; return ( <> <ResponsiveContainer width="100%" height="100%"> <BarChart width={500} height={300} data={data} margin={{ top: 5, right: 30, left: 20, bottom: 60, // 增大底部边距,容纳复选框 }} > <CartesianGrid strokeDasharray="3 3" /> <XAxis dataKey="name" color="#46BC01" height={70} // 设置足够高度容纳复选框和文本 tick={<CustomizedAxisTick />} /> <YAxis domain={[-50, 50]} allowDataOverflow /> <Tooltip /> <ReferenceLine y={0} stroke="#000" /> <Bar dataKey="deviation"> <LabelList dataKey="data" /> </Bar> </BarChart> </ResponsiveContainer> </> ); };
关键细节说明
<foreignObject>的作用:SVG本身不支持直接渲染HTML元素,通过该标签可以在SVG内部嵌入HTML内容,实现复选框这类可交互表单控件。- 布局调整:需要增大
BarChart的margin.bottom和XAxis的height,确保复选框和标签文本有足够显示空间,避免被截断。 - 状态扩展:示例中包含了复选框选中状态的管理逻辑,可根据需求联动图表数据的显示/隐藏等功能。
内容的提问来源于stack exchange,提问作者Aliaksandr Yanushkevich
相关产品推荐
相关产品推荐

