D3.js Collapsible Force Layout,默认折叠 [英] D3.js Collapsible Force Layout, collapsed by default

查看:413
本文介绍了D3.js Collapsible Force Layout,默认折叠的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



有人能识别问题吗?



也可以让它部分收合?这意味着第一组儿童扩展了,但一切都崩溃了?



我在plunker上的非工作示例



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



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

 函数更新(d){

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

//重新启动强制布局。
force
.nodes(nodes)
.links(links)
.start();

我在这里: d3.js可折叠力布局与所有节点折叠,这里:

$

$

b
$ b

没有一个解决方案能为我工作。



感谢任何建议。



UPDATED 28.1.2018



感谢以下答案,效果很好。



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

解决方案

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

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



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

  if(parentschildren.length <1){//因此它不会多次填充
node.filter(function(d){
//console.log(d.name)
return d.name ==='PARENT'//只返回父节点
})。each(function(d){
for (i = 0; i parentschildren.push(d.children [i] .name);
}

});
}

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

  function simulateClick(){


$ .fn.d3Click = function(i){//模拟点击
// 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; 0,null);
console.log(e);

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


}); //}
};

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

我会做这样的事情:

  node.each(function(d,i){//使用i迭代
d.uniqueID ='uniqueNode'+ i;
}

代码将给每一个唯一的值,所以第一个将是uniqueNode1然后uniqueNode2等等,然后应用这到你的节点:

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

至于你的其他问题(我认为你应该添加到这个问题,而不是在评论,所以人们知道为什么我的答案是这么大)这里是这个问题的答案。 p>

为了让所有的节点开始折叠,我使用了递归函数,你必须填充一个数组,让你有一个有孩子的节点:

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

函数recurse(node){
if(node.children){
nodes2.push(node.name)//将节点的名称推送到数组
node.children.forEach(recurse);
}
if(!node.id)node.id = ++ i;
nodes.push(node);
}

recurse(root);
console.log(nodes2)
返回节点;
}



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

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

现在使用这个数组来遍历以选择具有相同ID的节点:

  for(i = 0; i  if(newNodes [i]){//检查是否未定义等
$ ('#'+ newNodes [i])。d3Click();
}

}

(关闭然后打开),如你想要的那样:

  $('#PARENT')。 

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

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


I would like to use a collapsible force diagram which is collapsed by default (starting out with only one node). I ran across this: http://bl.ocks.org/david4096/6168323 but it is blank and not working. I'm using the latest Mozilla Firefox 43.0.4. I even put it to plunker with the same result - blank.

Can someone identify the problem?

Also would it be possible to have it partially collpased? That means the first set of children expanded but everything else collapsed?

My non-working example on plunker

I believe it can be achieved by modifying the update function.

Changing "children" to "_children" in the json data sheet does not work properly.

function update(d) {

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

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

i looked here: d3.js collapsible force layout with all the nodes collapsed and here: How can I start with all the nodes collapsed in d3js?

None of the solution is working for me.

Will be thankful for any advice.

UPDATED 28.1.2018

Works nicely thanks to the answer below.

Here is a working example: http://plnkr.co/edit/QtFXa53Q7p65NQpO4z5f?p=preview

解决方案

Basically, I added ID's to the circles on the nodes based on names :

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

Then I populated an array of all the parents childrens names, i.e the nodes you want to collapse :

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);
            }

          });
          }

Then I used the populated array to loop through to select the nodes I want to click and call a click function which simulates a click on selected nodes :

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
}
    }

As for the unique id's i would do something like this :

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

That piece of code will give each one a unique value. So the first one will be uniqueNode1 then uniqueNode2 and so on. Then to apply this to your nodes :

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

As for your other question (which i think you should add to this question rather than in the comments so people know why my answer is so big) here is the answer to that.

To get all of the nodes started collapsed i made use of the recursive function you already have to populate an array to give you ever node that has children :

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;
    }

Now, as i said before, i had given them id's based on name, so to select them all i have to do is go through this new node array (nodes2) and click on the node that has the same ID as each element in that array. But you can't do this straight away as this array starts from the highest point (PARENT) and goes down, so I had to reverse the array :

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

Now use this array to itterate through to select the nodes that have the same ID:

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

}

And then click the parent twice again (to close then open) as you wanted that selected:

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

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

Hope that solves all your problems and here is the final updated plnkr : http://plnkr.co/edit/QtFXa53Q7p65NQpO4z5f?p=preview

这篇关于D3.js Collapsible Force Layout,默认折叠的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆