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

如何基于reduceSum后的季度分组使用dc.js生成目标直方图

实现方案

核心思路

crossfilter本身仅支持对原始行数据做维度聚合,不能直接对聚合后的结果二次分组,所以我们通过**fake group(虚拟分组)**的方式实现需求:先按季度聚合总销量,再对季度总销量做分箱计数。

具体代码实现

第一步:聚合每个季度的总销量

先创建季度维度,统计每个季度的全品类销量总和:

// 季度维度,按日期字段分组
const quarterDim = ndx.dimension(d => d.Quarter);
// 按季度聚合总销量
const quarterTotalSalesGroup = quarterDim.group().reduceSum(d => d.unitsSold);

第二步:定义分箱用的虚拟分组

自定义函数生成符合crossfilter group规范的虚拟分组,自动对季度总销量做分箱、统计每个分箱对应的季度数量:

/**
 * 对季度总销量做分箱计数
 * @param {Object} quarterGroup 季度总销量的分组对象
 * @param {Number} binSize 分箱步长,可自行调整
 * @returns {Object} 符合crossfilter group规范的虚拟分组
 */
function getBinnedQuarterGroup(quarterGroup, binSize) {
  return {
    all: () => {
      const binMap = {};
      // 遍历所有季度的总销量,计算所属分箱
      quarterGroup.all().forEach(item => {
        const binKey = Math.round(item.value / binSize) * binSize;
        binMap[binKey] = (binMap[binKey] || 0) + 1;
      });
      // 按分箱值排序后返回
      return Object.entries(binMap)
        .map(([key, count]) => ({ key: Number(key), value: count }))
        .sort((a, b) => a.key - b.key);
    }
  };
}

第三步:初始化直方图

用虚拟分组作为直方图的数据源,完成常规配置即可:

const binSize = 10000; // 可根据需求调整分箱大小
const histogramChart = new dc.BarChart('#histogram');

histogramChart
  .dimension(quarterDim) // 维度使用季度维度即可
  .group(getBinnedQuarterGroup(quarterTotalSalesGroup, binSize)) // 传入虚拟分组
  .x(d3.scaleLinear())
  .xUnits(dc.units.fixed(binSize)) // 指定固定步长的分箱单位
  .elasticX(true)
  .elasticY(true)
  .xAxisLabel('季度总销量')
  .yAxisLabel('对应季度数量');

// 渲染图表
histogramChart.render();

补充说明

  • 该实现天然支持和其他dc.js图表的过滤联动:其他图表做过滤操作后,季度总销量分组会自动更新,虚拟分组也会实时重算分箱结果。
  • 如果需要支持点击直方图刷选对应销量区间的季度,只需额外配置filterHandler,根据用户选择的区间过滤quarterDim即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 10:36:07