2013-11-03 97 views
7

我是D3的新手,我发现它非常谦虚。d3 CSV中的可缩放树形图

我的目标是从CSV文件制作一个树形图。我想使用CSV格式,因为我将在电子表格中处理值,而且我很容易以这种方式保存文件。

我试图将数据存储在一个分层的格式,这样的事情(hier.csv):

parent,child,value 
Homer Simpson,Bart,20 
Homer Simpson,Lisa,14 
Homer Simpson,Maggie,6 
Peter Griffin,Chris,19 
Peter Griffin,Meg,12 
Peter Griffin,Stewie,9 

而且我用这个Zoomable Treemap example

我想让树变得任意深,即如果Bart在我的例子中有孩子,并根据姓名积累父母/孩子的关系。

我发现了一个great example of this for Sankey Diagrams,但我还没有找到Zoomable Treemaps的等价物。

有没有办法在Bostock's example的第124和126行之间插入一些代码以正确地为Zoomable Treemap格式化数据? (我可以更改我的CSV的布局,但想保留CSV格式)。使用这样的方法的东西nest(),但显然这并不工作:

d3.csv("./hier.csv", function(hier) { 

    var root = { 
    "name": "myrootnode", 
    "children": d3.nest() 
     .key(function (d) { return d.parent; }) 
     .key(function (d) { return d.child; }) 
     .entries(hier) 
    }; 

    initialize(root); 
    accumulate(root); 
    layout(root); 
    display(root); 
    //etc... 

我看到的例子和地址位和这件StackOverflow上的问题,但一直没能一起拔端到结束。而我一直在研究和黑客无济于事。我会欢迎一些帮助。谢谢!

FIDDLE这里

http://jsfiddle.net/KXuWD/

小提琴注:

  • 我在寻找近线#90,其中的注释表明
  • 我建立一个内嵌变量来保存帮助削减副本flare.json
  • 我打算在现实生活中将数据保存在单独的文件中,但对于JSFiddle,必须将其拉入内联;当然,如果我能够找出主要逻辑,这当然会很容易适应单独的数据文件。
  • 此示例似乎不适用于D3版本3.0.4,它是JSFiddle的当前内置版本。我为例子导入了v2.x,因为这与Bostock的例子一致。这是一个潜在的单独的问题...

更新

我克服我的问题的一部分。我的想法并不太远,nest()是必要的,但我没有正确更新我的访问器。这里的东西很邋遢的外观,主要作品: http://bl.ocks.org/maw246/7303963

主要差异(S)我的例子和博斯托克的关系:

  • 它的加载后CSV被嵌套,使用d3.nest()。这种强制转换成一个分层的JSON对象格式
  • 许多(如果不是全部)对“孩子”已经由“价值”替换,因为d3.nest()建立树木keyvalues属性,而不是树形图的预期namechildren性能。用于块大小的value属性保持不变。

问题剩余

  • 它不会去任意深度。我正在考虑一种重组我的数据的方法,以更好地利用d3.nest()功能,但尚未尝试过。
  • 孩子的名字显示undefined。我确信我只是略过了一些简单的东西,但我主要关心的是让核心功能发挥作用,所以当我有一分钟的时候,我会稍微深入一点。

注:我仍然在寻求帮助,干净且惯用的方法来这样做,包括如何最有效地组织CSV分层嵌套任意深度的咨询!

回答

1

未经测试,可能不是很习惯(javascript不是我的东西),但可能会让你走上正轨。我使用underscore.js,因为我很懒,如果你在意使用本地循环来做。

d3.csv(csv_url, function(error, data) { 
    var root = { 
     name: "Everybody", 
     value: 0, 
     children: [] 
    }; 

    var parents = {}; 
    _.each(data, function(row) { 
     var child = { 
      name: row.child, 
      value: row.value, 
      children: [] 
     }; 
     if(parents[row.parent]) { // parent seen already 
      parents[row.parent]['children'].push(child); 
      parents[row.parent]['value'] += row.value; 
     } else {     // new parent 
      parents[row.parent] = { 
       name: row.parent, 
       children: [child], 
       value: row.value 
      } 
     } 
     root.value += row.value; 
    }); 

    root.children = _.values(parents); 
    ... 
+0

谢谢您的输入,保罗。这个解决方案是否超过了一个深度?我没有尝试过,因为正如你所说,我正在追求一些更习惯的东西,正如我今天上午更新的那样。 – Marc

+0

对不起,这只适用于提供的数据样本(不是“Abe Simpson”)。我没有时间发布更通用的解决方案,但不应该很难将逻辑抽象为递归函数。 –

+0

我认为保罗斯的观点是有效的,也是很好的评价。 – VividD

3

我一直在调查树形图的使用时有类似的挫折感。 来自服务器的数据是平片状风格数据,如:

var myData = [{ "thedad": "Homer Simpson", "name": "Bart", "value": 20 }, 
{ "thedad": "Homer Simpson", "name": "Lisa", "value": 14 }, 
{ "thedad": "Homer Simpson", "name": "Maggie", "value": 6 }, 
{ "thedad": "Peter Griffin", "name": "Chris", "value": 19 }, 
{ "thedad": "Peter Griffin", "name": "Meg", "value": 12 }, 
{ "thedad": "Peter Griffin", "name": "Stewie", "value": 16 }, 
{ "thedad": "Bart", "name": "Bart Junior A", "value": 77 }, 
{ "thedad": "Bart", "name": "Bart Junior B", "value": 32 }]; 

然而,D3树形图预计,它处理JavaScript对象分层格式。 经过繁琐的搜索之后,我偶然发现d3谷歌组中提到了underscore.nesthttps://github.com/iros/underscore.nest

“Underscore.Nest是[下划线JS库的]的extenstion用于 转换平面数据转换成嵌套的树结构”。

使用这个库(再次,对underscore.js依赖)意味着你不必 诉诸d3.nest和担心它所产生的键/值数据格式。

工作实施例
这里是树形图以已经被转换由underscore.nest成分层格式的D3树形图期望对象 的平面列表的工作示例。 (不underscore.nest原树图是从mbostock的例子:http://bost.ocks.org/mike/treemap/

http://jsbin.com/aGIvOnEH/3

root = _.nest(myData, "thedad"); 
root.name = "TV Dads"; 

希望这是非常有用的。

+0

jsbin示例中存在问题。荷马辛普森是巴特的父亲,但巴特与他自己的孩子分开显示。在荷马辛普森下,巴特被列入名单,但没有孩子。我们期望看到'myData',应该让Bart的孩子成为Homer Simpson的孙辈,我们应该能够通过这种方式点击树形图。 – nikhilvj

0

mg1075's answer,我看到myData是自引用数据,意味着一行中的孩子成为另一行中的父亲并拥有自己的孩子。这导致了一种深度可变的层次结构,并且深度不能通过仅查看一行来计算;该计划需要遍历整个事情并建立关系。 d3.nest()不适用于此..它需要整个血统一直排列在每个单独的行本身排队的顶部。

我仍然需要探索underscore.js,但mg1075的jsbin工作示例表明,它实际上并没有解决问题:在树状图中,Bart在Homer Simpson旁边,他的孩子尽管是荷马辛普森的孩子,但仍然在那里;他也出现在荷马辛普森之下(让他成为他自己的叔叔:P),但没有任何孩子被列在他的下方(所以巴特的克隆叔叔偷走了他的孩子,可怜的霍默辛普森没有任何孙子)。所以基本上孙子们都不承认。

我发布了一个问题,然后使用一个名为DataStructures.Tree的库在这里找到了这种可变深度分层数据的可视化解决方案。我想这可能帮助:

https://stackoverflow.com/a/27756744/4355695