对 CSV 文件中列出的重复名称进行分组,并使用 d3.js 在单独的 Div 中显示每个组的总数

Group duplicated names listed in CSV file and display the total number of each group in seperate Div using d3.js

提问人:TonyT 提问时间:2/26/2023 最后编辑:TonyT 更新时间:2/27/2023 访问量:51

问:

我有一个CSV文件,其中包含包含重复名称(字符串)的列。我喜欢将所有相似/重复的名称分组,计算它们/添加它们并将它们的总数放在一个 div 中;即,Div Base 1:20,Div Base 2:80,Div Base 3:120。我试图使用 d3.js 完成这个想法,并且我让名称出现在 div 中,但无法弄清楚如何在提到的 div 中创建和放置不同重复名称(字符串)的总数。使用 D3 可以吗?以下是我到目前为止的尝试。 CSV 列/数据如下所示:

Sample CSV data

d3.selectAll(".container").append("div")
    .attr("id", function(d) { return  "base" + d.id})
    .html(function(d, i) {  
        if('Base' + d.id === 'Base' + d.id){
                 return data[i].location;
        }
    })
/////////My modification of your suggestion////////
var baseCount = d3.nest()
  .key(function(d) { return d.value; })
  .rollup(function(v) { return v.length; })
  .entries(data);
console.log(baseCount); 

// append divs
var mainDiv = d3.selectAll(".imgContainer");

mainDiv.selectAll(".imgContainer").data(baseCount).enter().append("div").attr("id", function(d) { return  "bases" + d.id}).html(function (d) {
  return d.values;
 // return "<pre>" + d[0] + " : " + d[1] + "</pre>";
 });
CSV D3.js

评论


答:

1赞 Robin Mackenzie 2/26/2023 #1

D3 v6 及更高版本具有适合您需求的 .rollups 数组转换。如果您使用早期版本的 D3,则有一些等效版本,或者您也可以编写普通的 Javascript。

该方法可以创建基本 ID 及其计数的“摘要”。然后,您可以将输出数组从这里传递到数据联接以创建 div。rollups

示例如下:

// summary of data
const baseSummary = d3.rollups(fakeData, v => v.length, d => d.name);

// append divs
const mainDiv = d3.select("body")
  .append("div")
  .attr("id", "main");
  
mainDiv.selectAll(".baseDiv")
  .data(baseSummary)
  .enter()
  .append("div")
  .attr("class", "baseDiv")
  .html(d => `<pre>${d[0]} : ${d[1]}</pre>`)
.baseDiv {
  border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.0/d3.min.js"></script>
<script>
const fakeData = [
  {name: 'base3', value: 3},
  {name: 'base1', value: 3},
  {name: 'base1', value: 2},
  {name: 'base3', value: 10},
  {name: 'base2', value: 10},
  {name: 'base2', value: 10},
  {name: 'base1', value: 2},
  {name: 'base1', value: 9},
  {name: 'base1', value: 3},
  {name: 'base2', value: 7},
  {name: 'base2', value: 10},
  {name: 'base2', value: 6},
  {name: 'base1', value: 6},
  {name: 'base3', value: 10},
  {name: 'base1', value: 1},
  {name: 'base3', value: 1},
  {name: 'base3', value: 2},
  {name: 'base3', value: 10},
  {name: 'base2', value: 10},
  {name: 'base2', value: 6},
  {name: 'base3', value: 2},
  {name: 'base2', value: 2},
  {name: 'base1', value: 10},
  {name: 'base2', value: 5},
  {name: 'base2', value: 9},
  {name: 'base2', value: 7},
  {name: 'base2', value: 3},
  {name: 'base1', value: 4},
  {name: 'base1', value: 5},
  {name: 'base3', value: 7}
];
</script>

评论

0赞 TonyT 2/26/2023
谢谢罗宾的例子。我很感激。目前,我的项目是使用 D3 版本 3 创建的。我打算将我的旧脚本修改为新的 V7。我没有这样做,因为有句话说,如果它没有坏,就不要修理它:)但是,您知道版本 3 的 D3.rollups() 等效的较低版本吗?或者一个普通的 javascript 方法,它将与我当前使用 D3 CSV 加载的数据一起使用。先谢谢你。
0赞 TonyT 2/26/2023
添加到我的热门评论中。我正在玩一个data.forEach(){循环,我可以通过console.log看到,但我无法添加类似的名称并将其放在全局变量中以在我的D3 .html()函数中使用。我很接近,但到目前为止:)
0赞 TonyT 2/27/2023
我能够让等效于 D3.rollups 的工作。但是这个所有总数的列表都在 div 中重复,而不是像您的示例那样在不同的 div 中分开;返回 “<pre>” + d[0] + “ : ” + d[1] + “</pre>”;这将返回数据 undefined。但是当我返回时:d.names,它显示了我上面解释的内容。我编辑了我的原始帖子,以显示我对您提供的脚本的修改。我不明白为什么我的加载数据不同。
0赞 TonyT 2/27/2023
您的解决方案是完美的!我纠正了在您的建议中所做的调整中的一些问题,现在它按预期工作。我感谢帮助和教育。