2

我有 2 个 CSV 文件,一个描述树的链接(graph.csv - 2 列:源和目标),另一个是节点名称的字典(nodes.csv - 2 列:node_id,node_name)。带有源/目标的 CSV 引用第二个 CSV 中的 node_id 列。

现在我想使用第二个 CSV 将节点名称(以及最终的其他属性)附加到树中的节点。我已经想出了如何将文本附加到节点,但我不知道如何“交叉”第二个 CSV 中的数据以将每个节点的名称作为文本附加到相应的节点。

我让这段代码像我想要的那样工作,但现在它只根据Mike Bostock在 SO 中的回答从第一个 CSV 中提取节点。现在我无法确定哪个节点是哪个节点,我想使用第二个 CSV 来识别节点。

据我所知,这段代码显然识别了 graph.csv 中的唯一节点,确定了根,然后构建了树。如果有办法从第一个 CSV 读取并复制它,用第二个 CSV 中的节点名称更改节点的 ID,我认为这将是第一步,但我无法正确执行它。

CSV 示例:

图.csv:

源,目标
1,2
1,3
1,4
2,5
2,6
11,22
14,21
3,7
3,8
4,9
4,10
5,11
5,12
5,13
6,14
6,15
7,16
8,17
9,18
10,19
10,20

节点.csv:

node_id,node_name
1,节点1
2、节点2
3、节点3
4、节点4
5、节点5
6、节点6
7、节点7
8、节点8
9、节点9
10、节点10
11、节点11
12、节点12
13、节点13
14、节点14
15,节点15
16、节点16
17、节点17
18、节点18
19、节点19
20,节点20
21、节点21
22、节点22

到目前为止的代码是:

 

    var margin = {top: 40, right: 40, bottom: 40, left: 40}, width = 1024 - margin.left - margin.right, height = 768 - margin.top - margin.bottom;

    var tree = d3.layout.tree()
        .size([高度,宽度]);

    var svg = d3.select("body").append("svg")
        .attr("宽度", width + margin.left + margin.right)
        .attr("高度", 高度 + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    d3.csv(“graph.csv”,函数(链接){
        var 节点名称 = {};

        链接.forEach(函数(链接){
            var parent = link.source = nodeByName(link.source),
            child = link.target = nodeByName(link.target);
            if (parent.children) parent.children.push(child);
            否则 parent.children = [孩子];
        });

    var 节点 = tree.nodes(links[0].source);

    svg.selectAll(".link")
        .data(链接)
        .enter().append("行")
        .attr("类", "链接")
        .attr("x1", function(d) { return d.source.y; })
        .attr("y1", function(d) { return d.source.x; })
        .attr("x2", function(d) { return d.target.y; })
        .attr("y2", function(d) { return d.target.x; });

    svg.selectAll(".node")
        .data(节点)
            .enter().append("圆")
       .attr(“类”,“节点”)
            .attr("r", 10)
            .attr("cx", function(d) { return dy; })
            .attr("cy", function(d) { return dx; });

    svg.selectAll("文本")     
            .data(节点)
       .enter().append("文本")
       .attr(“类”,“标签”)
       .attr("x",function(d) { return (dy - 25); })
       .attr("y",function(d) { return (dx + 20); })
       .text("文本");

    功能节点名称(名称){
        返回节点名称[名称] || (nodesByName[name] = {name:name});
    }
    });

有没有人知道如何“关联”这两个 CSV 并在文本附加中输出各自的名称?

编辑:我一直在寻找根据其他数组的内容替换数组内容的技术,我在 PHP 中发现了这个漂亮的函数,它可以满足我的需要:array_replace。现在我在 Javascript/D3.js 中需要它,但我似乎可以找到完全相同的解决方案或类似的解决方案。有任何想法吗?

4

1 回答 1

4

我认为最简单的方法是在你使用它的地方直接将id映射到名称,如下:

svg.selectAll("text")
  [...]
  .text( function(d) { return namesMap[d.name]; });

假设namesMap转换node_idnode_name.

现在你只需要创建上述namesMap的,例如:

d3.csv("nodes.csv", function(names) {
  var namesMap = {};
  names.forEach(function(d) {
    namesMap[d.node_id] = d.node_name;
  });
  // code using namesMap goes here
});

这个 fiddle<pre>中提供了一个稍微修改过的代码(从 HTML 中的节点加载 csv 数据) 。

于 2013-04-29T19:48:43.823 回答