【问题标题】:How to organise/nest data for d3.js chart output如何为 d3.js 图表输出组织/嵌套数据
【发布时间】:2016-05-17 10:36:27
【问题描述】:

我正在寻找有关如何通过 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

感谢您的建议,我有点迷路了。

【问题讨论】:

  • 这取决于您要优化什么... 磁盘使用情况?从原始数据转换的简单性?快速加载?反应式饼图?适合将来添加吗?
  • 它们听起来都很重要!我认为从原始数据转换的简单性和适合未来添加的简单性是最重要的。
  • 你试过转换成你想要的格式吗?您从 excel 获得的原始 csv 文件看起来不正确。我的意思是,如果 Excel 表顶部的值是日期、左侧的国家和介于两者之间的值,那么第一个值(在 Jan_2016 之前)不应该为空吗?
  • 是的 - 很抱歉造成混乱,我只是在写帖子时将其删除,当我将 excel 文件导出到 csv(仅使用另存为 .csv)时,它的前面确实有逗号日期,我将编辑帖子以将其放回 - 谢谢
  • 您需要在国家/地区上方添加一个名称,例如,Country as as you can't have a empty attribute。从那里如果你只是使用 d3.csv("csvlink.csv", function(data){}) plnkr.co/edit/cKrhGF4QRbzXRsjTDQoj?p=preview 然后你可以像使用 D3 中的任何其他数据集一样使用它。检查示例的控制台日志。这就是你想要的吗?

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


【解决方案1】:

我会说您建议的中间步骤是一个很好的步骤,可以将所有内容组织在内存中。不过,您不必浏览 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 与此脚本的运行代码。一切都显示在控制台中。

【讨论】:

  • 嗨 - 这很有意义!非常感谢 :) 我正在尝试在静态饼图中将其付诸实施,但我认为我仍在努力理解如何使用您创建的脚本。这是迄今为止的plnk - 希望我不是一百万英里之外。 plnkr.co/edit/1fiXFyl4MFZRrZX7DRCl?p=preview
  • 给你:plnkr.co/edit/P2NvhAa6qrNkkvuA2Zvq?p=preview 查看代码中的 cmets。
  • 啊,是的,越来越清晰了!我已经完成了(大部分)如果你想看看-plnkr.co/edit/hLBoPsnqeTKwvpXwMJPm?p=preview,我觉得可以吗?还是您认为有更好的方法来构建代码?另外,想知道您是否可以提供有关如何使图表在负载时转换的任何指示? (抱歉重复cmets!如果违反规则,请告诉我)
  • 建议:使用对任意键进行延迟绘图的函数。加载时,首先使用虚拟数据进行绘制,然后调用开始键的绘制函数。见这里:plnkr.co/edit/kli6w2VUUAUa1w8UynRB?p=preview
  • 啊,好吧,这更有意义。我正在尝试用组织名称标记每个细分市场,我认为这很容易做到。但是,我发现它非常令人困惑。从我所见,我必须将图表分成切片 (plnk of progress) 但是,我不知道如何将 Org 数据放入返回函数中?抱歉问了这么多问题,也许我应该提出一个新问题?
猜你喜欢
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
  • 2015-10-17
  • 1970-01-01
  • 2011-10-30
  • 2014-05-13
  • 1970-01-01
  • 2016-12-27
相关资源
最近更新 更多