35

在遵循众多 D3 示例时,数据通常以flare.json中给出的格式格式化:

{
 "name": "flare",
 "children": [
  {
   "name": "analytics",
   "children": [
    {
     "name": "cluster",
     "children": [
      {"name": "AgglomerativeCluster", "size": 3938},
      :

我有一个邻接列表如下:

A1 A2
A2 A3
A2 A4

我想将其转换为上述格式。目前,我正在服务器端执行此操作,但有没有办法使用 d3 的功能来实现这一点?我在这里找到了一个,但该方法似乎需要修改 d3 核心库,由于可维护性,我不赞成这样做。有什么建议么?

4

2 回答 2

56

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

第一个问题是您打算显示图形还是。对于图,数据结构是根据节点链接定义的。对于树,布局的输入是根节点,它可能有一个子节点数组,其叶节点有一个关联的

如果你想显示一个图形,而你所拥有的只是一个边列表,那么你需要遍历边以生成节点数组和链接数组。假设您有一个名为“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});
  }
});

像这样:

于 2012-06-18T19:02:08.963 回答
5

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

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

于 2012-06-18T18:53:09.180 回答