2016-05-17 133 views
3

我正在寻找一些关于如何有效地使用d3.js大量数据的建议。比方说,例如,我有这个数据集从一个原始的.csv文件(从Excel转换);如何组织/嵌套数据为d3.js图表​​输出

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可能是更合乎逻辑的选择?

对于这种数据将进入什么样的图表环境,我将创建一个饼图,它可以根据选定的国家/月份更新数据并比较每次三个组织的得分。

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

感谢您的任何意见,我有点失去了这里。

+0

这取决于你想要优化什么...磁盘使用?从原始数据转换简单吗?快速加载?活性饼图?适合将来添加? – tarulen

+0

他们都听起来很重要!我认为从原始数据转换到适合未来增加的简单性是最重要的。 – since095

+0

你有没有尝试转换为你想要的格式?您从excel中获得的原始csv文件看起来不正确。我的意思是,如果Excel表格顶部的值是日期,那么左边的国家和中间的值不应该是第一个值(2016年1月之前)为空? – thatOneGuy

回答

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"}, ...] 

这是国际海事组织最通用的结构,你可以有。虽然不是最好的内存使用。

的简单方式巢这是以下内容:

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:a Plunker与此脚本的运行代码。一切都显示在控制台中。

+0

嗨 - 这很有道理!非常感谢:)我试图把它付诸行动,在静态饼图中,但我认为我仍然在努力理解如何使用您创建的脚本。到目前为止,这里是一条小路 - 希望我不会离开百万英里。 http://plnkr.co/edit/1fiXFyl4MFZRrZX7DRCl?p=preview – since095

+0

这里你去:http://plnkr.co/edit/P2NvhAa6qrNkkvuA2Zvq?p=preview请参阅代码中的评论。 – tarulen

+0

啊,是的,它变得更清晰了!我已经完成了它(大部分),如果你想看看 - http://plnkr.co/edit/hLBoPsnqeTKwvpXwMJPm?p=preview,我认为没关系?或者你认为可能有更好的方法来构建代码?另外,想知道是否可以提供关于如何让图表在加载时转换的指针? (对于重复的评论感到抱歉!让我知道它是否违反规则) – since095