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

D3 Dimple饼图优化:将小数据系列归至“Others”类别

解决Dimple/D3饼图中小区块合并为“Others”的方案

当然有办法啦!我平时用Dimple和D3做饼图的时候,也经常遇到这种细碎小区块破坏观感的问题,其实核心思路就是先预处理数据,把占比/数值太小的类别合并成“Others”,再用处理后的数据画图就行。下面给你具体的实现方法:

一、Dimple实现方式

Dimple本身没有直接提供合并小类别的内置函数,但我们可以先手动处理数据,再喂给Dimple绘制图表,步骤很简单:

  1. 设定一个阈值(可以是固定数值,也可以是总占比的百分比)
  2. 遍历原始数据,累加所有小于阈值的项的数值
  3. 过滤掉小项,添加一个“Others”条目
  4. 用处理后的数据绘制饼图

举个实际代码例子:

// 假设你的原始数据长这样
const rawData = [
  { Category: "A", Value: 40 },
  { Category: "B", Value: 30 },
  { Category: "C", Value: 15 },
  { Category: "D", Value: 5 },
  { Category: "E", Value: 4 },
  { Category: "F", Value: 3 },
  { Category: "G", Value: 3 }
];

// 这里用百分比阈值更灵活,比如把占比小于5%的归为Others
const total = rawData.reduce((sum, item) => sum + item.Value, 0);
const thresholdRatio = 0.05; // 5%
const threshold = total * thresholdRatio;

let othersTotal = 0;
// 过滤数据,累加小项数值
const processedData = rawData.filter(item => {
  if (item.Value < threshold) {
    othersTotal += item.Value;
    return false;
  }
  return true;
});

// 如果有需要合并的小项,就添加Others条目
if (othersTotal > 0) {
  processedData.push({ Category: "Others", Value: othersTotal });
}

// 用处理后的数据绘制Dimple饼图
const svg = dimple.newSvg("#chartContainer", 600, 400);
const chart = new dimple.chart(svg, processedData);
chart.addMeasureAxis("p", "Value");
chart.addSeries("Category", dimple.plot.pie);
chart.draw();

二、纯D3实现方式

纯D3的思路和上面完全一致,也是先处理数据再绘图,代码示例如下:

// 同样的原始数据
const rawData = [/* 同上 */];
const total = rawData.reduce((sum, item) => sum + item.Value, 0);
const threshold = total * 0.05; // 5%阈值

let othersTotal = 0;
const processedData = rawData.reduce((acc, item) => {
  if (item.Value < threshold) {
    othersTotal += item.Value;
  } else {
    acc.push(item);
  }
  return acc;
}, []);

if (othersTotal > 0) {
  processedData.push({ Category: "Others", Value: othersTotal });
}

// 绘制D3饼图
const svg = d3.select("#chartContainer")
              .append("svg")
              .attr("width", 600)
              .attr("height", 400)
              .append("g")
              .attr("transform", "translate(300, 200)");

// 生成饼图布局
const pie = d3.pie().value(d => d.Value);
const arcs = pie(processedData);

// 生成弧线路径
const arcGenerator = d3.arc().innerRadius(0).outerRadius(150);

// 绘制扇形
svg.selectAll("path")
   .data(arcs)
   .enter()
   .append("path")
   .attr("d", arcGenerator)
   .attr("fill", (d, i) => d3.schemeCategory10[i]);

// 可选:添加类别标签
svg.selectAll("text")
   .data(arcs)
   .enter()
   .append("text")
   .attr("transform", d => `translate(${arcGenerator.centroid(d)})`)
   .attr("text-anchor", "middle")
   .text(d => d.data.Category);

小技巧

  • 如果你不想用百分比阈值,也可以直接设固定数值(比如数值小于5的都合并),根据你的数据场景调整就行
  • 合并后记得检查“Others”的数值是否合理,避免把太多重要类别误合并进去

这样处理之后,你的饼图就会清爽很多,再也不会被一堆细碎的小区块干扰啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:38:18