1

この例のような折りたたみ可能な力のレイアウトを生成しようとしています: http://bl.ocks.org/mbostock/1062288 :

ここに画像の説明を入力

フォース レイアウトの生成に使用されているデータは、API から供給される JSON オブジェクトです。データ構造をうまくトラバースし、SVG に追加されるノード (ルート ノードとその子ノードの両方) を生成できます。

ただし、親ノードを子ノードにリンクすると問題が発生します。リンクが生成されず、リンク変数が空の配列を返しています。この問題は、例と比較してアプリでデータがどのように構造化されているかに関係していると確信しているため、JS コードと各ノードのデータ構造の両方を投稿します。

どんな助けでも大歓迎です!前もって感謝します!!

これが私のコードを使用したJS Fiddleです:http://jsfiddle.net/tmzjW/

これが私のJSコードです:

//Force Layout Code
var w = 607,
    h = 500,
    node,
    link,
    root;

var force = d3.layout.force()
    .on("tick", tick)
    .size([w, h]);

var vis = d3.select("#chart").append("svg:svg")
    .attr("width", w)
    .attr("height", h);

function initiateForceJS(currentURL) {
    //Generate the URL
    forceURL = currentURL + ".json?jsonp=?";
    $('#commentArea').show();
    $.getJSON(forceURL,handleRequest2);
    function handleRequest2(json) {
        //Set the root as the first object returned
        root = json[1]['data']['children'][0];
        update();
    }
}

function update() {
  nodes = flatten(root),
  links = d3.layout.tree()
            .sort(null)
            .children(function(d) {return (!d['replies']['data']['children']|| d['replies']['data']['children'].length === 0) ? null : d['replies']['data']['children'];})
            .links(nodes);

  // Restart the force layout.
  force
      .nodes(nodes)
      .links(links)
      .start();

  // Update the links…
  link = vis.selectAll("line.link")
      .data(links, function(d) { return d.target.id; });

  // Enter any new links.
  link.enter().insert("svg:line", ".node")
      .attr("class", "link")
      .attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

  // Exit any old links.
  link.exit().remove();

  // Update the nodes…
  node = vis.selectAll("circle.node")
      .data(nodes, function(d) {return d.id; })
      .style("fill", color);

  // Enter any new nodes.
  node.enter().append("svg:circle")
      .attr("class", "node")
      .attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; })
      .attr("r", function(d) { return Math.sqrt(d.ups) || 4.5; })
      .style("fill", color)
      //.on("click", click)
      .call(force.drag);

  // Exit any old nodes.
  node.exit().remove();
  //This will add the name of the character to the node

  node.append("comment").text(function(d) { return d.body });
  //This will put the comment in the Comment Area div
  node.on("mouseover", function() {
    var currentNode = d3.select(this);
    var currentTitle = currentNode.select("comment").text();
    $('#commentArea').html('<p>' + currentTitle + '</p>')  
  });
} 


function tick() {
  link.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

  node.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
}

// Color leaf nodes orange, and packages white or blue.
function color(d) {
  return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
// Returns a list of all nodes under the root.
function flatten(root) {
  var nodes = [], i = 0;
  function recurse(node) {

    if (node['data']['replies'] != "" && node['kind'] != "more") {
        node['data']['replies']['data']['children'].forEach(recurse);
    }
    if (node['kind'] !="more") {
        //Add an ID value to the node starting at 1
        node.data.id = ++i;
        var comment = node.data;
        nodes.push(comment);
    }
  }
  recurse(root);
  return nodes;
}
4

1 に答える 1

2

問題は、hierarchy.links関数が設定した子アクセサーを監視しないことです。childrenノードのプロパティのみに依存します。childrenこの例では標準の階層ノード構造(各ノードの配列)を使用しているため、これは元の例で機能します。非標準の構造(サードパーティのAPIで定義されている)を使用しているため、この場合は機能しません。

リンクメソッドは子アクセサを監視しません。これは、データに対して階層レイアウト(ツリーレイアウトなど)を呼び出すと、children定義した子アクセサに基づいてプロパティが設定されるためです。非標準の入力データを標準形式に自動的にマッピングします。ただし、ここでは実際には階層レイアウトを使用していないため、ノードを標準形式にマップする機会はありません。したがって、hierarchy.linksは結果を返しません。つまり、ノードにchildren配列はありません。

ここでのもう1つの問題は、rootノードに実際には応答がないため、ルートノードの子がないことです。(ありますが、お子様のアクセサーが定義されているroot.data.replies.data.childrenわけではありません。)root.replies.data.children

ここで行う最も簡単なことは、データをより単純な階層構造にマップすることだと思います。ここでは、子がchildren配列として定義されています。階層レイアウトを使用してそれを支援できる場合もありますが、既にフラット化関数(または少なくとも変更された関数)を作成していることを考えると、とにかくほとんどの方法でそこにいます。

于 2013-03-21T02:08:43.747 に答える