Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将节点添加到D3树v4_Javascript_D3.js_Tree - Fatal编程技术网

Javascript 将节点添加到D3树v4

Javascript 将节点添加到D3树v4,javascript,d3.js,tree,Javascript,D3.js,Tree,我正在使用D3V4构建一棵树 小提琴: 我现在尝试添加对从选定节点动态添加(和删除)子节点的支持 但是,我无法在不执行完全重画的情况下重画图表。我已在以下位置修改了可折叠树形图代码中的代码: 具体而言,以下块不会对其子级的布局执行重新计算 document.getElementById('add-child').onclick = function() { console.log(selected); selected.children.push({ type: 'resour

我正在使用D3V4构建一棵树

小提琴:

我现在尝试添加对从选定节点动态添加(和删除)子节点的支持

但是,我无法在不执行完全重画的情况下重画图表。我已在以下位置修改了可折叠树形图代码中的代码:

具体而言,以下块不会对其子级的布局执行重新计算

document.getElementById('add-child').onclick = function() {
  console.log(selected);
  selected.children.push({
    type: 'resource-delete',
    name: new Date().getTime(),
    attributes: [],
    children: []
  });

  update(selected);
};

有没有人有在D3.js v4中动态地向树添加/删除节点的好例子?

我提出了这个解决方案,用于向D3 tree v4动态添加新节点。

D3V4树需要节点

使用
d3.hierarchy(..)
从树数据(json)创建节点,并将其推送到它的
父.children
数组中并更新树

代码片段

//Adding a new node (as a child) to selected Node (code snippet)
var newNode = {
    type: 'node-type',
    name: new Date().getTime(),
    children: []
  };
  //Creates a Node from newNode object using d3.hierarchy(.)
  var newNode = d3.hierarchy(newNode);

  //later added some properties to Node like child,parent,depth
  newNode.depth = selected.depth + 1; 
  newNode.height = selected.height - 1;
  newNode.parent = selected; 
  newNode.id = Date.now();

  //Selected is a node, to which we are adding the new node as a child
  //If no child array, create an empty array
  if(!selected.children){
    selected.children = [];
    selected.data.children = [];
  }

  //Push it to parent.children array  
  selected.children.push(newNode);
  selected.data.children.push(newNode.data);

  //Update tree
  update(selected);


/####数据模型开始
风险值数据={
键入:“操作”,
名称:“1”,
属性:[],
儿童:[{
键入:“children”,
名称:‘2’,
属性:[{
“源类型属性值”:“路灯”
}],
儿童:[{
类型:'父',
名称:‘3’,
属性:[{
“源类型属性值”:“电缆”
}],
儿童:[{
键入:“资源删除”,
名称:‘4’,
属性:[],
儿童:[]
}]
}, {
键入:“children”,
名称:'5',
属性:[{
“源类型属性值”:“灯笼”
}],
儿童:[]
}]
}]
};
//####数据模型结束
//设置图表的尺寸和边距
var margin={顶部:20,右侧:90,底部:30,左侧:90},
宽度=960-margin.left-margin.right,
高度=500-margin.top-margin.bottom;
//将svg对象附加到页面主体
//将“组”元素附加到“svg”
//将“组”元素移动到左上角
var svg=d3.select(“body”)。
附加(“svg”)。
属性(“宽度”,宽度+边距。右+边距。左)。
属性(“高度”,高度+边距。顶部+边距。底部)。
附加(“g”)。
属性(“变换”、“平移”(+margin.left+)、“+margin.top+”);
变量i=0,持续时间=750,根;
//声明树布局并指定大小
var treemap=d3.tree().size([height,width]);
//指定父对象、子对象、高度和深度
root=d3.层次结构(数据、函数(d){
返回d.儿童;
});
root.x0=高度/2;
root.y0=0;
更新(根);
选择的var=null;
函数更新(源){
//为节点指定x和y位置
var treeData=树映射(根);
//计算新的树布局。
var nodes=treeData.subjects(),
links=treeData.subjects().slice(1);
//为固定深度进行规格化。
nodes.forEach(函数(d){
d、 y=d.深度*180
});
//####链接
//更新链接。。。
var link=svg.selectAll('line.link')。
数据(链接、功能(d){
返回d.id;
});
//在父对象的上一个位置输入任何新链接。
var linkEnter=link.enter()。
追加('行')。
属性(“类”、“链接”)。
属性(“笔划宽度”,2)。
属性(“笔划”,“黑色”)。
属性('x1',函数(d){
返回源0.y0;
}).
属性('y1',函数(d){
返回源.x0;
}).
属性('x2',函数(d){
返回源0.y0;
}).
属性('y2',函数(d){
返回源.x0;
});
var linkUpdate=linkEnter.merge(link);
linkUpdate.transition()。
持续时间(持续时间)。
属性('x1',函数(d){
返回d.parent.y;
}).
属性('y1',函数(d){
返回d.parent.x;
}).
属性('x2',函数(d){
返回d.y;
}).
属性('y2',函数(d){
返回d.x;
});
//转换回父元素位置
linkUpdate.transition()。
持续时间(持续时间)。
属性('x1',函数(d){
返回d.parent.y;
}).
属性('y1',函数(d){
返回d.parent.x;
}).
属性('x2',函数(d){
返回d.y;
}).
属性('y2',函数(d){
返回d.x;
});
//删除任何现有链接
var linkExit=link.exit()。
转换()。
持续时间(持续时间)。
属性('x1',函数(d){
返回源.x;
}).
属性('y1',函数(d){
返回源.y;
}).
属性('x2',函数(d){
返回源.x;
}).
属性('y2',函数(d){
返回源.y;
}).
删除();
//####圆圈
//更新节点。。。
var node=svg.selectAll('g.node')
.数据(节点、功能(d){
返回d.id | |(d.id=++i);
});
//在父对象的上一个位置输入任何新模式。
var nodenter=node.enter()。
附加('g')。
attr('class','node')。
属性(“转换”,函数(d){
返回“translate”(“+source.y0+”,“+source.x0+”);
}).
在(“点击”,点击);
//为节点添加圆
nodeEnter.append('circle')。
attr('class','node')。
属性('r',25)。
样式(“填充”,功能(d){
返回“#0e4677”;
});
//更新
var nodeUpdate=nodenter.merge(节点);
//转换到节点的正确位置
nodeUpdate.transition()。
持续时间(持续时间)。
属性(“转换”,函数(d){
返回“translate”(“+d.y+”,“+d.x+”);
});
//更新节点属性和样式
nodeUpdate.select('circle.node')。
属性('r',25)。
样式(“填充”,功能(d){
返回“#0e4677”;
}).
属性(“光标”、“指针”);
//删除任何现有节点
var nodeExit=node.exit()。
转换()。
持续时间(持续时间)。
属性(“转换”,函数(d){
返回“translate”(“+source.y+”,“+source.x+”);
}).
删除();
//退出时,将节点圆的大小减小为0
nodeExit.select('circle').attr('r',0);
//存储旧位置以进行转换。
nodes.forEach(函数(d){
d、 x0=d.x;
d、 y0=d.y;
});
//在单击时切换子项。
功能点击(d){
所选=d;
document.getElementById('add-child')。disabled=false;
document.getElementById('remove')。disabled=false;
更新(d);
}
}
document.getElem
function insert(par, data) {
   let newNode = d3.hierarchy(data);
   newNode.depth = par.depth + 1;
   newNode.parent = par;
   // Walk up the tree, updating the heights of ancestors as needed.
   for(let height = 1, anc = par; anc != null; height++, anc=anc.parent) {
     anc.height = Math.max(anc.height, height);
   }
   if (!par.data.children) {
      par.children = [];
      par.data.children = [];
   }
   par.children.push(newNode);
   par.data.children.push(newNode.data);
}
function insert(par, data) {
   let newNode = d3.hierarchy(data);
   newNode.depth = par.depth + 1;
   newNode.parent = par;
   if (!par.children)
      par.children = [];
   par.children.push(newNode);
}
insert(selected, {
   type: 'node-type',
   name: new Date().getTime()
});
update(selected);