如何组织/嵌套d3.js图表​​输出的数据

时间:2016-05-17 10:36:28

标签: javascript csv d3.js nested hierarchical-data

我正在寻找有关如何使用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可能是更合乎逻辑的选择?

对于这些数据将进入何种图表的背景,我想创建一个饼图,可以根据所选的国家/月更新数据,并每次比较三个组织的得分。

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

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

1 个答案:

答案 0 :(得分:3)

我会说你提出的中间步骤是一个很好的保持内存中的一切。您不必浏览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,其中包含此脚本的运行代码。一切都显示在控制台中。