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

D3.js如何筛选d3.csv加载的数据,仅保留出现次数排名前n的结果

D3.js 奥运奖牌数据Top15国家筛选方案

核心优化思路

原有实现需要为每个国家单独遍历全量数据做过滤,时间复杂度为O(n*m),数据量较大时性能损耗明显。优化方案仅需单次遍历全量数据完成国家计数,结合排序取前15,整体时间复杂度为O(n + m log m),效率更高。

实现代码

步骤1:统计各国出现次数

使用d3.rollup单次遍历完成分组计数:

// 入参为已按年份筛选后的data
const countryCountMap = d3.rollup(
  data,
  group => group.length, // 每个国家分组的计数(即奖牌获得次数)
  item => item.Country // 按国家字段分组
)

步骤2:排序取Top15国家

将统计结果转为数组后排序,截取前15位:

const top15CountryList = Array.from(countryCountMap)
  .sort((a, b) => b[1] - a[1]) // 按计数降序排列,奖牌数多的在前
  .slice(0, 15) // 取前15个国家
  .map(item => item[0]) // 仅提取国家名用于后续过滤

步骤3:过滤得到绘图数据

仅保留前15国家的原始数据用于绘图:

const finalChartData = data.filter(item => top15CountryList.includes(item.Country))

额外说明

如果柱状图的Y轴直接展示各国奖牌总数,可直接使用排序后的Array.from(countryCountMap).sort((a, b) => b[1] - a[1]).slice(0,15)作为绘图绑定数据,无需再过滤原始数据,每一项的结构为[国家名, 奖牌总数],可直接读取映射到坐标轴。

如果使用的是v6及以下版本的D3,没有内置d3.rollup,可以用d3.nest实现同等逻辑:

const countryCount = d3.nest()
  .key(d => d.Country)
  .rollup(v => v.length)
  .entries(data)

const top15CountryList = countryCount
  .sort((a, b) => b.value - a.value)
  .slice(0,15)
  .map(d => d.key)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 08:06:03