d3 CSV中的Zoomable Treemap

时间:2013-11-03 23:03:10

标签: javascript csv d3.js treemap

我刚接触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 example

我希望树能够任意深入,即如果巴特在我的例子中有孩子,并根据姓名积累父母/子女的关系。

我找到了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 HERE

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对象格式
  • 许多(如果不是全部)对“孩子”的引用已被“值”替换,因为d3.nest()使用keyvalues属性构建树,而不是Treemap的预期{{1} }和name属性。用于块大小调整的children属性保持不变。

剩余问题

  • 它不会任意深入。我正在考虑一种重新组织数据的方法,以便更好地利用value功能,但还没有尝试过。
  • 儿童的姓名正在显示d3.nest()。我确定我只是忽略了一些简单的事情,但我主要关心的是让核心功能正常工作,所以当我有一分钟的时候,我会对这篇文章进行一些修改。

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

3 个答案:

答案 0 :(得分: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是[下划线js库]的扩展名   将平面数据转换为嵌套树结构“。

使用此库(再次,依赖于underscore.js)意味着您没有 诉诸d3.nest并担心它产生的键/值数据格式。

工作示例
下面是一个树形图的工作示例,它采用了一个平面的对象列表 已被underscore.nest转换为d3 treemap所期望的分层格式。 (没有underscore.nest的原始树形图来自mbostock的例子:http://bost.ocks.org/mike/treemap/

<强> http://jsbin.com/aGIvOnEH/3

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

希望这很有用。

答案 1 :(得分: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);
    ...

答案 2 :(得分:0)

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

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

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

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