如何转换为D3的JSON格式?

时间:2012-06-18 17:52:05

标签: javascript json graph d3.js tree

在遵循众多D3示例的​​同时,数据通常采用flare.json

中给出的格式进行格式化
{
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
     "children": [
      {"name": "AgglomerativeCluster", "size": 3938},
      :

我有一个邻接列表如下:

A1 A2
A2 A3
A2 A4

我想转换为上面的格式。目前,我在服务器端这样做,但有没有办法使用d3的功能实现这一目标?我发现了一个here,但这种方法似乎需要修改d3核心库,由于可维护性,我不赞成。有什么建议吗?

2 个答案:

答案 0 :(得分:54)

没有规定的格式,因为您通常可以通过各种访问器功能(例如hierarchy.children)和array.map重新定义数据。但是你引用的格式可能是树最方便的表示,因为它适用于默认的访问器。

第一个问题是您是否打算显示graphtree。对于图表,数据结构是根据nodeslinks定义的。对于树,布局的输入是根节点,其可以具有child nodes的数组,并且其叶节点具有关联的value

如果你想显示一个,你所拥有的只是一个边列表,那么你需要迭代边缘以产生一个节点数组和一个数组链接。假设您有一个名为“graph.csv”的文件:

source,target
A1,A2
A2,A3
A2,A4

您可以使用d3.csv加载此文件,然后生成一组节点和链接:

d3.csv("graph.csv", function(links) {
  var nodesByName = {};

  // Create nodes for each unique source and target.
  links.forEach(function(link) {
    link.source = nodeByName(link.source);
    link.target = nodeByName(link.target);
  });

  // Extract the array of nodes from the map by name.
  var nodes = d3.values(nodeByName);

  function nodeByName(name) {
    return nodesByName[name] || (nodesByName[name] = {name: name});
  }
});

然后,您可以将这些节点和链接传递给力布局,以显示图形:

如果您想要生成,那么您需要进行稍微不同的数据转换形式,以便为每个父级累积子节点。

d3.csv("graph.csv", function(links) {
  var nodesByName = {};

  // Create nodes for each unique source and target.
  links.forEach(function(link) {
    var parent = link.source = nodeByName(link.source),
        child = link.target = nodeByName(link.target);
    if (parent.children) parent.children.push(child);
    else parent.children = [child];
  });

  // Extract the root node.
  var root = links[0].source;

  function nodeByName(name) {
    return nodesByName[name] || (nodesByName[name] = {name: name});
  }
});

像这样:

答案 1 :(得分:5)

D3不需要特定格式。这一切都取决于您的应用程序。您当然可以将邻接列表转换为flare.json中使用的格式,但这又是特定于应用程序的代码。通常,您不能这样做,因为邻接列表不具有构建树所需的“头”或“根”元素。此外,您需要单独处理周期,孤儿等。

鉴于您目前正在服务器端进行转换,我很想说“如果没有损坏,请不要修复它”;)