基于嵌套JSON实现多州确诊病例折线图的优化实现问询
解决方案:用Crossfilter和dc.js绘制多州确诊趋势折线图
我来帮你解决手动创建37个组的麻烦问题!你的核心需求是基于Crossfilter的维度和组概念,不用扁平化数据就能画出所有州的确诊趋势折线图,咱们可以通过自定义聚合函数+dc.js复合图表来实现,具体步骤如下:
1. 理解数据结构与聚合思路
你的原始数据是按日期分组的嵌套结构:每个日期条目包含day(日期)和statewise(37个州的确诊数据数组)。我们不需要扁平化数据,而是通过自定义Crossfilter的reduce函数,把每个日期下所有州的确诊数聚合到一个组对象中,每个州对应一个键值对。
2. 实现自定义聚合函数
我们不用reduceSum,而是自己写reduceAdd、reduceRemove和reduceInitial方法,来动态聚合所有州的数据:
d3.json('https://api.rootnet.in/covid19-in/unofficial/covid19india.org/statewise/history').then(function(json_data) { var data = json_data.data.history; const cf = crossfilter(data); // 创建日期维度(把字符串日期转为Date对象,保证排序正确性) const dateDimension = cf.dimension(function(d) { return new Date(d.day); }); // 自定义reduce函数,聚合所有州的确诊数 const stateCasesGroup = dateDimension.group().reduce( // reduceAdd: 新增数据时,累加每个州的确诊数 function(p, v) { v.statewise.forEach(state => { const stateName = state.state; p[stateName] = (p[stateName] || 0) + parseInt(state.confirmed); }); return p; }, // reduceRemove: 移除数据时,减去每个州的确诊数 function(p, v) { v.statewise.forEach(state => { const stateName = state.state; p[stateName] -= parseInt(state.confirmed); }); return p; }, // reduceInitial: 初始化聚合对象,所有州初始值为0 function() { const initial = {}; // 从第一条数据中提取所有州名,初始化值为0 data[0].statewise.forEach(state => { initial[state.state] = 0; }); return initial; } ); // 配置复合折线图 const compositeChart = dc.compositeChart("#line-chart"); // 获取所有州名(从初始聚合对象的键中提取) const stateNames = Object.keys(stateCasesGroup.top(1)[0].value); // 动态生成每个州对应的子折线图 const subCharts = stateNames.map(stateName => { return dc.lineChart(compositeChart) .group(stateCasesGroup, stateName) .valueAccessor(d => d.value[stateName]) // 指定当前州的数值读取逻辑 .colors(d3.schemeCategory10); // 用分类色区分不同州 }); // 配置复合图表基础参数 compositeChart .width(1200) .height(600) .x(d3.scaleTime().domain(dateDimension.extent())) // X轴绑定日期范围 .xAxisLabel("日期") .yAxisLabel("累计确诊数") .legend(dc.legend().x(800).y(20).itemHeight(13).gap(5)) // 添加图例区分各州 .compose(subCharts) // 组合所有子折线图 .render(); });
3. 关键细节说明
- 自定义reduce函数:通过遍历每个日期下的
statewise数组,动态累加/减去每个州的确诊数,最终每个组条目会包含所有州的确诊数据,彻底避免手动创建37个独立组。 - 复合图表配置:通过
dc.compositeChart组合多个子折线图,利用map方法动态生成每个州的子图表,大幅减少重复代码。 - 数值访问器:每个子折线图通过
valueAccessor指定读取当前州的确诊数值,确保每条折线对应正确的数据维度。
这样就能高效实现37个州的确诊趋势折线图,完全基于Crossfilter的维度和组概念,无需扁平化数据!
内容的提问来源于stack exchange,提问作者Pygirl
相关产品推荐
相关产品推荐

