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

如何用Crossfilter驱动的dc.js创建单产品切片的饼图?

问题

现有包含订单信息的客户数据如下:

const customers = [
  { id: 1, orders: [{ products: ["apple", "banana"] }, { products: ["apple"] }] },
  { id: 2, orders: [{ products: ["strawberry"] }] },
  { id: 3, orders: [{ products: ["apple"] }, { products: ["strawberry"] }] },
  { id: 4, orders: [] }
]

需求是生成饼图,要求每个切片对应单个产品;点击apple切片时,能过滤出所有曾购买过苹果的客户。

目前已实现饼图渲染和过滤功能,但饼图切片显示的是产品组合(比如apple, banana、strawberry、apple, strawberry、none),不符合需求。当前创建维度的代码如下:

const dimension = crossfilter.dimension((customer: Customer) => {
    const productList = customer.orders.flatMap(x => x.products)
    const products = new Set<string>(productList);
    const result = [...products ];
    if (result.length === 0) return "none";

    return result;
})

const group = dimension.group();
解决方案

要实现单个产品作为饼图切片,同时保留按产品过滤客户的功能,需调整Crossfilter的维度与分组逻辑,核心是让每个客户关联的产品拆分为独立维度条目,但统计时确保同一客户只被计数一次。

1. 重新定义维度与分组

// 创建多值维度:每个客户对应其购买过的所有独立产品,无订单则对应"none"
const productDimension = crossfilter.dimension((customer) => {
  const uniqueProducts = [...new Set(customer.orders.flatMap(o => o.products))];
  return uniqueProducts.length ? uniqueProducts : ["none"];
});

// 自定义分组逻辑:统计每个产品对应的客户数量(避免同一客户重复计数)
const productGroup = productDimension.group().reduce(
  // 添加记录时,将客户ID存入Set,确保唯一性
  (acc, customer) => {
    acc.customerIds.add(customer.id);
    acc.count = acc.customerIds.size;
    return acc;
  },
  // 移除记录时,删除对应客户ID,更新计数
  (acc, customer) => {
    acc.customerIds.delete(customer.id);
    acc.count = acc.customerIds.size;
    return acc;
  },
  // 初始化分组数据结构
  () => ({ customerIds: new Set(), count: 0 })
);

2. 适配饼图数据

饼图需要使用分组后的count值作为切片的数值:

// 转换为饼图所需的格式
const pieChartData = productGroup.all().map(item => ({
  key: item.key,
  value: item.value.count
}));

3. 保留过滤逻辑

点击产品切片时,直接过滤维度即可,多值维度会自动匹配所有包含该产品的客户:

// 示例:点击apple切片时执行过滤
productDimension.filter("apple");
// 刷新所有dc.js图表
dc.renderAll();

逻辑说明

  • 多值维度:当维度函数返回数组时,Crossfilter会自动将该客户记录关联到数组中的每个产品,这样每个产品能独立成为饼图的一个切片。
  • 自定义reduce:通过Set存储客户ID,确保同一客户不会被重复统计(比如同时买过苹果和香蕉的客户,只会给苹果和香蕉的计数各加1)。
  • 无订单处理:将无订单客户统一映射到"none",保证饼图包含该分类切片。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:44:56