Javascript 将节点添加到D3树v4
我正在使用D3V4构建一棵树 小提琴: 我现在尝试添加对从选定节点动态添加(和删除)子节点的支持 但是,我无法在不执行完全重画的情况下重画图表。我已在以下位置修改了可折叠树形图代码中的代码: 具体而言,以下块不会对其子级的布局执行重新计算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
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);