D3嵌套任意深度的数据

时间:2014-06-26 18:25:34

标签: javascript d3.js underscore.js treemap

我有一个如下所示的数据结构,我想将其嵌套以制作D3树形图。我可以使用Underscore.nestD3.nest()嵌套它。但是,由于我的数据具有任意深度,我最终得到了一堆未定义的节点。如何将其嵌套到任意深度或rollup未定义的节点?

// Example Data 
data = [
    {'name' : 'Post 1', '0' : 'tag_a'},
    {'name' : 'Post 2', '0' : 'tag_b'},
    {'name' : 'Post 3', '0' : 'tag_b', '1' : 'tag_c'},
    {'name' : 'Post 4', '0' : 'tag_d', '1' : 'tag_e', '2' : 'tag_f', '3' : 'tag_g'}
];


// Nesting with the Underscore nest plugin
var underscoreNested = _.nest(data, ['0', '1', '2', '3']);

{
  "children": [
    {
      "name": "tag_a",
      "children": [
        {
          "name": "undefined",
          "children": [
            {
              "name": "undefined",
              "children": [
                {
                  "name": "undefined",
                  "children": [
                    {
                      "0": "tag_a",
                      "name": "Post 1"
                    }
                  ],
                  "index": 0
                }
              ],
              "index": 0
            }
          ],
          "index": 0
        }
      ],
      "index": 0
    }...

// Nesting with D3
var d3Nested = d3.nest()
    .key(function(d) { return d['0']; })
    .key(function(d) { return d['1']; })
    .key(function(d) { return d['2']; })
    .key(function(d) { return d['3']; })
    .entries(data);

[
  {
    "key": "tag_a",
    "values": [
      {
        "key": "undefined",
        "values": [
          {
            "key": "undefined",
            "values": [
              {
                "key": "undefined",
                "values": [
                  {
                    "0": "tag_a",
                    "name": "Post 1"
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },...

1 个答案:

答案 0 :(得分:0)

我使用solution here找到了一个不错的burrow.js。它与D3 zoomable treemap示例非常吻合。

// nest rows with keys array, requires Underscore.js
burrow = function (data) {
  // create simple nested object
  var object = {};
  _(data).each(function(d) {
    var _object = object;
    // branch based on an array of items,
    // with arbitray depth/length,
    // in this case the tags array
    _(d.tags).each(function(element,index) {
      _object[element] = _object[element] || {};
      _object = _object[element];
    });
  });

  // recursively create children array
  function descend(object) {
    if (!_.isEmpty(object)) {    
      var array = [];
        _(object).each(function(value, key) {
          var children = descend(value);
          if (!!children) {
            var branch = {
              name: key,
              children: children
            };
          } else {
            var branch = {
              name: key,
              value: 1
            }; 
          }
          array.push(branch)
        }); // _.each
        return array;
    } // if
    else return false;
  }; // descend

  // nested objectect
  return {
    name: "Nested Data",
    children: descend(object)
  };
};