7

我是使用 D3 的新手,我觉得它非常谦虚。

我的目标是从 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 示例

我希望树可以任意深入,即如果 Bart 在我的示例中有孩子,并根据名称相应地累积父/子关系。

为 Sankey Diagrams 找到了一个很好的例子,但我还没有找到 Zoomable Treemaps 的等价物。

有没有办法在Bostock 示例的第 124 行和第 126 行之间插入一些代码,以便为可缩放树形图正确格式化我的数据?(我可以更改 CSV 的布局,但想保留 CSV 格式)。类似这种方法 using 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 问题,这些问题解决了这个问题,但无法将它们端到端地结合在一起。而且我一直在研究和破解无济于事。我会欢迎一些帮助。谢谢!

在这里提琴

http://jsfiddle.net/KXuWD/

小提琴笔记:

  • 我在评论指出的第 90 行附近寻求帮助
  • 我设置了一个内联变量来保存flare.json的精简副本
  • 我计划在现实生活中将数据保存在一个单独的文件中,但对于 JSFiddle,它必须内联;当然,如果我能弄清楚主要逻辑,这将很容易适应单独的数据文件。
  • 此示例似乎不适用于 D3 版本 3.0.4,这是 JSFiddle 的当前内置版本。我为示例导入了 v2.x,因为这适用于 Bostock 的示例。这是一个潜在的单独问题......

更新

我克服了部分问题。我的想法并没有太远,这nest()是必要的,但我没有正确更新我的访问器。这是一个非常草率的看一些最有效的东西:http: //bl.ocks.org/maw246/7303963

我的示例和 Bostock 示例之间的主要区别:

  • CSV 在加载后被嵌套,使用d3.nest(). 这将其强制转换为分层 JSON 对象格式
  • 许多(如果不是全部)对“children”的引用已被“values”取代,因为使用和属性d3.nest()构建树,而不是 Treemap 的预期和属性。用于块大小调整的属性保持不变。keyvaluesnamechildrenvalue

遗留问题

  • 它不会随意深入。我正在考虑一种方法来重组我的数据以更好地利用该d3.nest()功能,但还没有尝试过。
  • 孩子们的名字出现了undefined。我确定我只是忽略了一些简单的事情,但我主要关心的是让核心功能正常工作,所以我会在有时间的时候稍微破解一下这篇文章。

注意:我仍在寻求一种干净且惯用的方法来执行此操作,包括有关如何最好地组织 CSV 以实现任意深度的分层嵌套的建议!

4

3 回答 3

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 treemap 需要它处理的 javascript 对象的分层格式。经过繁琐的搜索,我在 d3 google 组 中发现了underscore.nest的提及。https://github.com/iros/underscore.nest

“Underscore.Nest 是 [underscore js 库] 的扩展,用于将平面数据转换为嵌套树结构”。

使用这个库(同样依赖 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";

希望这是有用的。

于 2013-12-05T21:11:30.920 回答
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);
    ...
于 2013-11-04T00:54:49.023 回答
0

mg1075 的回答中,我看到myData的是自引用数据,这意味着一行中的孩子成为另一行的父母并拥有自己的孩子。这导致了一种深度可变的层次结构,并且无法通过仅查看一行来计算深度;程序需要遍历整个事物并建立关系。d3.nest()对此不起作用..它需要整个祖先一直排在每一行本身的顶部。

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

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

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

于 2015-07-09T02:12:21.620 回答