You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在同一页面中放置两个D3环形图

嘿,这个问题其实很适合用代码复用来解决——把环形图的绘制逻辑封装成一个可复用的函数,只需要传入不同的数据和容器,就能轻松生成多个结构一致的图表,完全避免重复代码。我给你整理了一个完整的示例,你可以参考下:

解决方案:封装可复用的环形图函数

核心思路是把环形图的通用绘制逻辑抽成一个独立函数,通过传入不同的容器选择器和数据集来生成不同的图表,位置可以通过CSS控制容器来实现。

1. 准备HTML结构

给两个环形图分别准备独立的容器,方便控制位置:

<div id="donut-chart-1" class="donut-container"></div>
<div id="donut-chart-2" class="donut-container"></div>

用CSS设置容器的位置(比如并排显示,你可以根据需求调整):

.donut-container {
  width: 300px;
  height: 300px;
  float: left;
  margin: 0 20px;
}

2. 封装D3.js环形图函数

这个函数接收两个关键参数:containerSelector(指定图表要渲染到哪个容器)和data(当前图表的数据集),其他样式、尺寸参数统一设置(满足你“除数据和位置外完全一致”的要求):

function createDonutChart(containerSelector, data) {
  // 通用配置(所有图表共享)
  const width = 300;
  const height = 300;
  const radius = Math.min(width, height) / 2;
  const color = d3.scaleOrdinal(d3.schemeCategory10);

  // 清除容器内已有内容(避免重复渲染)
  d3.select(containerSelector).selectAll("*").remove();

  // 创建SVG,绑定到指定容器
  const svg = d3.select(containerSelector)
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", `translate(${width/2}, ${height/2})`);

  // 创建弧生成器
  const arc = d3.arc()
    .innerRadius(radius * 0.6) // 内环半径,控制环形粗细
    .outerRadius(radius);

  // 创建饼图布局
  const pie = d3.pie()
    .value(d => d.value)
    .sort(null);

  // 绑定数据,绘制环形路径
  const arcs = svg.selectAll("arc")
    .data(pie(data))
    .enter()
    .append("g");

  arcs.append("path")
    .attr("d", arc)
    .attr("fill", (d, i) => color(i))
    .attr("stroke", "#fff")
    .attr("stroke-width", 2);

  // 添加中心文本(可选,根据你的需求调整或删除)
  svg.append("text")
    .attr("text-anchor", "middle")
    .attr("dy", "0.35em")
    .style("font-size", "18px")
    .text(() => {
      const total = d3.sum(data, d => d.value);
      return `总计: ${total}`;
    });
}

3. 调用函数生成两个环形图

准备不同的数据集,然后分别调用函数即可:

// 第一个图表的数据
const data1 = [
  { label: "A", value: 30 },
  { label: "B", value: 50 },
  { label: "C", value: 20 }
];

// 第二个图表的数据
const data2 = [
  { label: "X", value: 45 },
  { label: "Y", value: 35 },
  { label: "Z", value: 20 }
];

// 生成两个环形图
createDonutChart("#donut-chart-1", data1);
createDonutChart("#donut-chart-2", data2);

为什么这样做?

  • 避免代码重复:所有通用逻辑只写一次,修改样式、交互时只需要改函数,不用两个图表分别调整
  • 位置灵活控制:通过CSS控制容器的位置(比如并排、上下排列、绝对定位等),完全满足你“位置不同”的需求
  • 可扩展性强:如果之后需要加更多环形图,只需要再调用一次函数,传入新的容器和数据就行

如果你的现有代码里有自定义的样式或交互,只需要把对应的逻辑移到这个通用函数里,保持参数只传数据和容器就好~

内容的提问来源于stack exchange,提问作者user8893965

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:02:51