如何为 d3.js 图表输出 organise/nest 数据

How to organise/nest data for d3.js chart output

我正在寻找有关如何通过 d3.js 有效使用大量数据的建议。比方说,我从原始 .csv 文件中获取了这个数据集(从 excel 转换而来);

EA
,Jan_2016,Feb_2016,Mar_2016
Netherlands,11.7999,15.0526,13.2411
Belgium,25.7713,24.1374
France,27.6033,23.6186,20.2142

EB
,Jan_2016,Feb_2016,Mar_2016
Netherlands,1.9024,2.9456,4.0728
Belgium,-,6.5699,7.8894
France,5.3284,4.8213,1.471

EC
,Jan_2016,Feb_2016,Mar_2016
Netherlands,3.1499,3.1139,3.3284
Belgium,3.0781,4.8349,5.1596
France,16.3458,12.6975,11.6196

我想使用 csv 表示此数据的最佳方式是这样的;

Org,Country,Month,Score
EA,Netherlands,Jan,11.7999
EA,Belgium,Jan,27.6033
EA,France,Jan,20.2142
EA,Netherlands,Feb,15.0526
EA,Belgium,Feb,25.9374
EA,France,Feb,23.6186
EA,Netherlands,Mar,13.2411
EA,Belgium,Mar,24.1374
EA,France,Mar,20.2142

这对我来说似乎很啰嗦,而且会占用很多时间。我想知道是否有更简单的方法来做到这一点?

据我所知,我认为 JSON 可能是更合理的选择?

关于这些数据将进入哪种图表的上下文,我希望创建一个饼图,它可以根据所选 country/month 更新数据并每次比较三个组织的分数.

(plnk 可视化) http://plnkr.co/edit/P3loEGu4jMRpsvTOgCMM?p=preview

感谢您的任何建议,我在这里有点迷路。

我想说你提出的中间步骤是一个很好的步骤,可以让所有内容在内存中井井有条。不过,您不必查看 csv 文件,只需加载原始 csv 文件并将其转换为对象数组即可。这是一个解析器:

d3.text("data.csv", function(error, dataTxt) { //import data file as text first
 var dataCsv=d3.csv.parseRows(dataTxt); //parseRows gives a 2D array
 var group=""; // the current group header ("organization")
 var times=[]; //the current month headers
 var data=[];  //the final data object, will be filled up progressively
 for (var i=0;i<dataCsv.length;i++) {
    if (dataCsv[i].length==1 ) { //group name
       if ( dataCsv[i][0] == "") 
          i++; //remove empty line
       group = dataCsv[i][0]; //get group name
       i++;
       times = dataCsv[i];//get list of time headings for this group 
       times.shift(); // (shift out first empty element)
     } else {
       country=dataCsv[i].shift(); //regular row: get country name
       dataCsv[i].forEach(function(x,j){ //enumerate values
         data.push({ //create new data item
           Org: group,  
           Country: country,
           Month: times[j],
           Score: x
         })
       }) 
    }
 }

这给出了以下数据数组:

data= [{"Org":"EA","Country":"Netherlands","Month":"Jan_2016","Score":"11.7999"},
       {"Org":"EA","Country":"Netherlands","Month":"Feb_2016","Score":"15.0526"}, ...]

这是 IMO 您可以拥有的最通用的结构。虽然不是内存使用的最佳选择。

嵌套的简单方法如下:

d3.nest()
  .key(function(d) { return d.Month+"-"+d.Country; })
  .map(data);

它将给出一个带有键值的地图,例如:

"Jan_2016-Netherlands":[{"Org":"EA","Country":"Netherlands","Month":"Jan_2016","Score":"11.7999"},{"Org":"EB","Country":"Netherlands","Month":"Jan_2016","Score":"1.9024"},{"Org":"EC","Country":"Netherlands","Month":"Jan_2016","Score":"3.1499"}]

使用 entries 而不是 map 来使用数组而不是地图,如果您想通过仅保留分数数组来简化数据,请使用 rollup 函数.此时将它插入任何 d3 绘图工具都相当简单。

PS: Plunker 加上此脚本的 运行 代码。一切都显示在控制台中。