我正在尝试使用颜色选择器修改强制布局中某些节点的颜色。
我还没有找到任何示例来说明如何修改力布局中的元素而不会在这些元素之内/由这些元素触发事件。
This example使用按钮更新布局,但仅更改传递的数据,然后更新图形。我正在使用的数据包含一个确定颜色的“组”,该颜色在JS中定义。因此,更新数据不是一种选择,但是更新变量也不起作用。
This question询问有关更新仿真本身的力/属性而不是其元素的问题,并且这里的解决方案对我不起作用,因为重新加热仿真不会拾取变化的颜色。
var cp = document.getElementById("useCasePicker");
cp.value = useCaseColor;
cp.addEventListener("change", updateColor, false);
function updateColor(event)
{
useCaseColor = event.target.value;
update();
}
这是我尝试执行的操作(使用update()函数使用任何新输入重绘图形),但是要更改的现有节点已被跳过,因为它们已经存在。
我也尝试过这种方法(其中节点是包含所有圆圈的<g>
元素)-
node.selectAll("circle").style("fill", useCaseColor);
这对于更改颜色也不起作用-
node.selectAll("circle").remove();
label.selectAll("text").remove();
update();
我猜我可以做一个类似事件发生的newColor
标志,并且当事件为true时,以某种方式触发节点自身的事件,但是我认为有一种更好的方法
这是在update()
函数中定义节点的方式。
node = node.data(config.nodes, d => d.id);
node.exit().remove();
node = node.enter().append("circle")
.attr("class", "node")
.attr("r", function (d) {
switch(d.group)
{
case "use case":
return useCaseRad;
case "data service":
return dataServRad;
case "source":
return sourceRad;
}
})
.attr("fill", function (d) {
switch(d.group)
{
case "use case":
return useCaseColor;
case "data service":
return dataServColor;
case "source":
return sourceColor;
}
})
.attr("stroke", "black")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("mouseover", mouseOver)
.on("mouseout", mouseOut)
.merge(node);
如果需要,我可以提供更多代码,但是我知道图形的所有功能都可以正常工作,我只想能够更新颜色而不必破坏整个图形并重新绘制。
答案 0 :(得分:1)
您不必破坏图形-只需在合并后放置fill方法调用即可。
.merge(data)
.attr("fill", function (d) {
switch(d.group) {
case "use case":
return useCaseColor;
case "data service":
return dataServColor;
case "source":
return sourceColor;
}
})
合并允许您同时使用初始和输入选择,因此您可以正确更新它。