如何在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
相关产品推荐
相关产品推荐

