D3.js可折叠力布局,默认情况下已折叠

时间:2016-01-15 14:38:47

标签: javascript d3.js diagram

我想使用默认折叠的可折叠力图(仅从一个节点开始)。我遇到了这个问题:http://bl.ocks.org/david4096/6168323但它是空白的,无法正常工作。我正在使用最新的Mozilla Firefox 43.0.4。我甚至把它带到了同样的结果 - 空白。

有人可以识别问题吗?

也可以让它部分地碰撞吗?这意味着第一组儿童扩大了但其他一切都崩溃了?

My non-working example on plunker

我相信可以通过修改更新功能来实现。

在json数据表中将“children”更改为“_children”无法正常工作。

function update(d) {

  var nodes = flatten(root),
      links = d3.layout.tree().links(nodes);

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

我看了这里:d3.js collapsible force layout with all the nodes collapsed并在这里:How can I start with all the nodes collapsed in d3js?

这些解决方案都不适合我。

感谢任何建议。

更新于28.1.2018

由于下面的答案,效果很好。

以下是一个工作示例:http://plnkr.co/edit/QtFXa53Q7p65NQpO4z5f?p=preview

1 个答案:

答案 0 :(得分:2)

基本上,我根据名称将ID添加到节点上的圈子中:

.append("circle").attr('id', function(d){ return d.name})

然后我填充了所有父母孩子名字的数组,即你想要折叠的节点:

if(parentschildren.length<1){ //so it doesn't populate it more than once
          node.filter(function(d){
            //console.log(d.name)
            return d.name === 'PARENT' //return just the parent node
          }).each(function(d){
            for(i=0;i<d.children.length;i++){
              parentschildren.push(d.children[i].name);
            }

          });
          }

然后我使用填充的数组循环选择我想要点击的节点并调用一个模拟所选节点点击的点击功能:

function simulateClick(){


        $.fn.d3Click = function (i) { //simulate click
          //if(i===0){
  this.each(function (i, e) {

    var evt = document.createEvent("MouseEvents");
    evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
console.log(e);

    e.dispatchEvent(evt);
   // nodeEnter.on("click", click)
    evt.stopPropagation()


  }); //}
};

for(i=0;i<parentschildren.length;i++){ //loop through created array

$('#'+parentschildren[i]).d3Click(); //select element to click
}
    }

至于唯一身份证,我会这样做:

node.each(function(d,i){ // use i to iterate through
d.uniqueID = 'uniqueNode' + i;
}

这段代码将为每个代码赋予唯一值。所以第一个将是uniqueNode1然后是uniqueNode2,依此类推。然后将其应用于您的节点:

nodes.attr('id'(function(d){
return d.uniqueID;
})

至于你的另一个问题(我认为你应该加入这个问题,而不是在评论中,以便人们知道为什么我的答案如此之大),这就是答案。

为了让所有节点开始折叠,我使用了你已经拥有的递归函数来填充一个数组,为你提供有子节点的节点:

var nodes2 = [];
function flatten(root) {
      var nodes = [], i = 0;

      function recurse(node) {
        if (node.children) {
          nodes2.push(node.name) //push the name of the node to the array
          node.children.forEach(recurse);
        }
        if (!node.id) node.id = ++i;
        nodes.push(node);
    }

      recurse(root);
      console.log(nodes2)
      return nodes;
    }

现在,正如我之前所说的那样,我根据名称给了他们id,所以要选择它们我要做的就是通过这个新节点数组(nodes2)并点击具有与该数组中的每个元素相同的ID。但你不能马上这样做,因为这个数组从最高点(PARENT)开始并且下降,所以我不得不反转数组:

var newNodes = [];
  for(i=nodes2.length; i>=0; i--){
    newNodes.push(nodes2[i])
  }

现在使用此数组来迭代选择具有相同ID的节点:

for(i=0;i<newNodes.length;i++){
 if(newNodes[i]){ //check if i isnt undefined etc
   $('#'+newNodes[i]).d3Click();
 }

}

然后再次单击父级(关闭然后打开),如您所希望的那样:

$('#PARENT').d3Click();

$('#PARENT').d3Click();

希望能解决您的所有问题,这是最新更新的plnkr:http://plnkr.co/edit/QtFXa53Q7p65NQpO4z5f?p=preview