2

2 つの CSV ファイルがあります。1 つはツリーのリンクを記述したもの (graph.csv - 2 列: ソースとターゲット) で、もう 1 つはノード名の辞書 (nodes.csv - 2 列: node_id、node_name) です。ソース/ターゲットを含む CSV は、2 番目の CSV の node_id 列を参照します。

次に、この 2 番目の CSV を使用して、ノード名 (および最終的には他のプロパティ) をツリー内のノードにアタッチします。ノードにテキストを追加する方法は既に理解しましたが、2 番目の CSV のデータを「クロス」して、各ノードの名前をテキストとしてそれぞれのノードに追加する方法がわかりません。

私はこのコードを思いどおりに動作させましたが、現在は SO in Mike Bostock の回答に従って、最初の CSV からノードを抽出するだけです。現在、どのノードがどれであるかを把握できず、2 番目の CSV を使用してノードを識別したいと考えています。

私の知る限り、このコードは明らかにgraph.csv内の一意のノードを識別し、ルートを決定してからツリーを構築します。最初の CSV から読み取り、2 番目の 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,Node17
18,Node18
19,Node19
20,ノード20
21,Node21
22,Node22

これまでのコードは次のとおりです。

 

    var margin = {上: 40、右: 40、下: 40、左: 40}、幅 = 1024 - margin.left - margin.right、高さ = 768 - margin.top - margin.bottom;

    var ツリー = d3.layout.tree()
        .size([高さ、幅]);

    var svg = d3.select("本体").append("svg")
        .attr("幅", 幅 + マージン.左 + マージン.右)
        .attr("高さ", 高さ + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    d3.csv("graph.csv", 関数(リンク) {
        var nodesByName = {};

        links.forEach(関数(リンク) {
            var 親 = link.source = nodeByName(link.source),
            child = link.target = nodeByName(link.target);
            if (parent.children) 親.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("テキスト");

    関数 nodeByName(名前) {
        nodesByName[名前] を返します || (nodesByName[名前] = {名前: 名前});
    }
    });

2 つの CSV を "関連付け" て、それぞれの名前をテキストの追加に出力する方法を知っている人はいますか?

編集:他の配列のコンテンツに基づいて、配列のコンテンツを置き換える手法を探していました.PHPでこの美しい関数を見つけました。今、私はJavascript/D3.jsでこれを必要としていますが、まったく同じ解決策または同等の解決策を見つけることができるようです。何か案は?

4

1 に答える 1

4

最も簡単な方法は、次のように、ID を使用する場所の名前に直接マップすることだと思います。

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

namesMapに変換node_idすると仮定しnode_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
});

少し変更されたコード ( <pre>HTML のノードから読み込まれる csv データを含む) は、この fiddleで利用できます。

于 2013-04-29T19:48:43.823 に答える