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

如何在dc.js饼图中实现分组数据的平均值展示?

如何用dc.js实现分组平均值的饼图配置?

没问题,我来帮你搞定这个dc.js的饼图配置,实现分组平均值的计算和悬浮提示显示~

首先,我们得先把你的原始数据集转换成crossfilter能处理的结构化格式。比如你的data1 data1 1 2 2 3 3 4应该拆成每个分组对应单个数值的对象数组,像这样:

const data = [
  { group: 'data1', value: 1 },
  { group: 'data1', value: 2 },
  { group: 'data2', value: 2 },
  { group: 'data2', value: 3 },
  { group: 'data3', value: 3 },
  { group: 'data3', value: 4 }
];

接下来,创建crossfilter实例,然后定义维度(dimension)和分组(group):

1. 创建Crossfilter实例

const cf = crossfilter(data);

2. 定义Dimension

我们要按group字段分组,所以维度直接基于这个字段:

const groupDimension = cf.dimension(d => d.group);

3. 定义计算平均值的Group

这是关键步骤,因为dc.js默认的分组只能做计数或求和,我们需要用reduce方法来同时统计每个分组的数值总和、条目数量,进而计算平均值:

const avgGroup = groupDimension.group().reduce(
  // 累加函数:新增数据时更新总和、计数和平均值
  (accumulator, current) => {
    accumulator.total += current.value;
    accumulator.count += 1;
    accumulator.average = accumulator.total / accumulator.count;
    return accumulator;
  },
  // 减少函数:移除数据时更新状态(处理过滤等场景)
  (accumulator, current) => {
    accumulator.total -= current.value;
    accumulator.count -= 1;
    // 避免除以0的情况
    accumulator.average = accumulator.count > 0 ? accumulator.total / accumulator.count : 0;
    return accumulator;
  },
  // 初始化函数:每个分组的初始状态
  () => ({ total: 0, count: 0, average: 0 })
);

4. 把Dimension和Group应用到饼图

现在把上面定义的groupDimension和avgGroup填入你的饼图配置,同时调整title函数来显示平均值:

Chart1
  .width(250)
  .height(250)
  .slicesCap(4)
  .innerRadius(0)
  .dimension(groupDimension) // 填入我们定义的维度
  .title(function(d) {
    // 这里d.value是我们reduce返回的对象,直接取average即可,保留两位小数更友好
    return `The Average is ${d.value.average.toFixed(2)}`;
  })
  .colors(d3.scaleOrdinal(["#ff2222","#4855ff"]))
  .label(function (d) {
    if (Chart1.hasFilter() && !Chart1.hasFilter(d.key)) {
      return d.key + ' (0%)';
    }
    let label = d.key;
    // 如果需要显示分组数值总和在总数值中的占比,先创建一个总数值的groupAll
    const totalAll = cf.groupAll().reduceSum(d => d.value);
    if (totalAll.value()) {
      // 用分组的总和除以总数值计算占比
      label += ` (${Math.floor(d.value.total / totalAll.value() * 100)}%)`;
    }
    return label ;
  })
  .group(avgGroup); // 填入我们定义的分组

关键说明

  • 用reduce方法可以自定义分组的聚合逻辑,这里我们维护了total(总和)、count(条目数)、average(平均值)三个属性
  • 悬浮提示(title)里直接通过d.value.average获取计算好的平均值
  • 标签里的占比计算我改成了基于分组数值总和的占比,如果你想要的是平均值的占比,可以再创建一个所有分组平均值的总和来计算,按需调整即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:57:30