Recharts双饼图问题:单个禁用Tooltip及ResponsiveContainer样式调整
Recharts双饼图问题解决方案
问题概述
- 同一
PieChart容器内的两个Pie组件,左侧的Tooltip会干扰右侧基于activeIndex的自定义Label,需实现仅为单个Pie显示Tooltip。 - 将两个
Pie拆分到独立PieChart时出现报错;使用独立ResponsiveContainer虽可行,但难以实现并排布局的样式控制。
解决方案一:单个PieChart内实现Tooltip隔离
Recharts的Tooltip支持通过pieId属性配合filter方法,精准指定仅对目标Pie组件生效:
- 给两个
Pie组件分别设置唯一pieId - 在
Tooltip的filter回调中,只保留目标Pie的tooltip数据
修改后的核心代码片段:
// 左侧Pie:设置pieId并保留Tooltip <Pie pieId="account-balance" data={data} cx={120} cy={120} innerRadius={70} outerRadius={90} fill="#8884d8" paddingAngle={5} dataKey="value" > {data.map((entry, index) => ( <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} /> ))} <Label value={total_balance} offset={0} position="center" formatter={formatCurrency} /> </Pie> <Tooltip formatter={formatCurrency} // 仅显示pieId为account-balance的Tooltip filter={(payload) => payload.pieId === "account-balance"} /> // 右侧Pie:设置独立pieId,不绑定Tooltip <Pie pieId="asset-distribution" data={data2} cx={380} cy={120} labelLine={false} outerRadius={80} fill="#8884d8" dataKey="value" activeShape={renderActiveShape} activeIndex={activeIndex} onMouseEnter={onPieEnter} > {data2.map((entry, index) => ( <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} /> ))} </Pie>
解决方案二:独立PieChart实现并排布局
拆分到独立PieChart并通过CSS Flexbox实现并排,解决报错和样式问题:
完整组件代码:
const AccountSummary = (props) => { const [activeIndex, setActiveIndex] = useState(); let data = []; let total_balance = 0; props.accounts.forEach((account) => { data.push({ name: account.name, value: account.current_balance }); total_balance += account.current_balance; }); const formatCurrency = (value) => new Intl.NumberFormat("en-US", { maximumSignificantDigits: 10, style: "currency", currency: "USD", }).format(value); const data2 = [ { name: "Equities", value: 800 }, { name: "Bonds", value: 400 }, ]; const onPieEnter = (_, index) => { setActiveIndex(index); }; // 并排布局容器样式 const chartWrapperStyle = { display: "flex", gap: "40px", justifyContent: "center", width: "100%", maxWidth: "800px", margin: "0 auto", }; // 单个饼图容器样式 const chartItemStyle = { flex: 1, minWidth: "200px", }; return ( <div> <h4>Total Account Value: {formatCurrency(total_balance)}</h4> <div style={chartWrapperStyle}> {/* 第一个独立饼图:账户余额 */} <ResponsiveContainer width="100%" height={300} style={chartItemStyle}> <PieChart> <Pie data={data} cx="50%" cy="50%" innerRadius={70} outerRadius={90} fill="#8884d8" paddingAngle={5} dataKey="value" > {data.map((entry, index) => ( <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} /> ))} <Label value={total_balance} offset={0} position="center" formatter={formatCurrency} /> </Pie> <Tooltip formatter={formatCurrency} /> </PieChart> </ResponsiveContainer> {/* 第二个独立饼图:资产分布 */} <ResponsiveContainer width="100%" height={300} style={chartItemStyle}> <PieChart> <Pie data={data2} cx="50%" cy="50%" labelLine={false} outerRadius={80} fill="#8884d8" dataKey="value" activeShape={renderActiveShape} activeIndex={activeIndex} onMouseEnter={onPieEnter} > {data2.map((entry, index) => ( <Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} /> ))} </Pie> </PieChart> </ResponsiveContainer> </div> </div> ); }; export default AccountSummary;
关键说明:
- 外层
div使用Flexbox实现并排,通过flex:1让两个饼图容器平分可用宽度 - 每个
PieChart用cx="50%"和cy="50%"自动居中,避免手动设置固定坐标的适配问题 - 拆分后两个饼图完全独立,无Tooltip干扰或组件冲突问题
内容的提问来源于stack exchange,提问作者Lauren Boland
相关产品推荐
相关产品推荐

