所以我有下一个用于设置节点,链接和其他元素的强制布局图代码:
var setLinks = function ()
{
link = visualRoot.selectAll("line.link")
.data(graphData.links)
.enter().append("svg:line")
.attr("class", "link")
.style("stroke-width", function (d) { return nodeStrokeColorDefault; })
.style("stroke", function (d) { return fill(d); })
.attr("x1", function (d) { return d.source.x; })
.attr("y1", function (d) { return d.source.y; })
.attr("x2", function (d) { return d.target.x; })
.attr("y2", function (d) { return d.target.y; });
graphData.links.forEach(function (d)
{
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
};
var setNodes = function ()
{
node = visualRoot.selectAll(".node")
.data(graphData.nodes)
.enter().append("g")
.attr("id", function (d) { return d.id; })
.attr("title", function (d) { return d.name; })
.attr("class", "node")
.on("click", function (d, i) { loadAdditionalData(d.userID, this); })
.call(force.drag)
.on("mouseover", fadeNode(.1)).on("mouseout", fadeNode(1));
};
//append the visual element to the node
var appendVisualElementsToNodes = function ()
{
node.append("circle")
.attr("id", function (d) { return "circleid_" + d.id; })
.attr("class", "circle")
.attr("cx", function (d) { return 0; })
.attr("cy", function (d) { return 0; })
.attr("r", function (d) { return getNodeSize(d); })
.style("fill", function (d) { return getNodeColor(d); })
.style("stroke", function (d) { return nodeStrokeColorDefault; })
.style("stroke-width", function (d) { return nodeStrokeWidthDefault; });
//context menu:
d3.selectAll(".circle").on("contextmenu", function (data, index)
{
d3.select('#my_custom_menu')
.style('position', 'absolute')
.style('left', d3.event.dx + "px")
.style('top', d3.event.dy + "px")
.style('display', 'block');
d3.event.preventDefault();
});
//d3.select("svg").node().oncontextmenu = function(){return false;};
node.append("image")
.attr("class", "image")
.attr("xlink:href", function (d) { return d.profile_image_url; })//"Images/twitterimage_2.png"
.attr("x", -12)
.attr("y", -12)
.attr("width", 24)
.attr("height", 24);
node.append("svg:title")
.text(function (d) { return d.name + "\n" + d.description; });
};
现在,颜色和尺寸依赖性发生了变化,我需要重新绘制具有不同颜色和半径的图形圆(+所有附加元素)。有问题。
我可以这样做:
visualRoot.selectAll(".circle").remove();
但是我附加到'.circles'
的所有图片仍在那里。
无论如何,任何帮助都将不胜感激,如果解释不够明确,请告诉我,我会尽力解决。
P.S。 graphData.nodes
和d3.selectAll('.nodes')
之间有什么区别?
答案 0 :(得分:106)
你的回答是有效的,但对后人来说,这些方法更为通用。
从HTML中删除所有子项:
d3.select("div.parent").html("");
从SVG / HTML中删除所有子项:
d3.select("g.parent").selectAll("*").remove();
.html("")
调用适用于我的SVG,但使用innerSVG可能会产生副作用。
答案 1 :(得分:7)
我的第一个建议是,您应该阅读有关选择的d3.js
API:https://github.com/mbostock/d3/wiki/Selections
您必须了解enter()
命令的工作原理(API)。您必须使用它来处理新节点的事实具有帮助您的意义。
以下是处理selection.data()
时的基本流程:
首先,您要将某些数据“附加”到选择中。所以你有:
var nodes = visualRoot.selectAll(".node")
.data(graphData.nodes)
然后,您可以在每次更改数据时修改所有节点(这将完全符合您的要求)。例如,如果更改了加载的新数据集中旧节点的半径
nodes.attr("r", function(d){return d.radius})
然后,您必须处理新节点,为此您必须选择新节点,这是selection.enter()
的用途:
var nodesEnter = nodes.enter()
.attr("fill", "red")
.attr("r", function(d){return d.radius})
最后你肯定想要删除你不再需要的节点,要做到这一点,你必须选择它们,这就是selection.exit()
的用途。
var nodesRemove = nodes.exit().remove()
整个过程的一个很好的例子也可以在API wiki上找到:https://github.com/mbostock/d3/wiki/Selections#wiki-exit
答案 2 :(得分:7)
通过这种方式,我很容易解决它,
visualRoot.selectAll(".circle").remove();
visualRoot.selectAll(".image").remove();
然后我重新添加了以不同方式呈现的视觉元素,因为计算半径和颜色的代码已更改属性。谢谢。
答案 3 :(得分:4)
如果您想删除元素本身,请像使用element.remove()
一样使用。如果您只想删除元素的内容,但保持元素不变,则可以使用f.ex。
visualRoot.selectAll(".circle").html(null);
visualRoot.selectAll(".image").html(null);
而不是.html("")
(我不确定要删除哪个元素的子元素)。此 会保留元素本身,但会清除所有包含的内容 。它the official way to do this,因此应该跨浏览器工作。
PS:您想要更改圆圈尺寸。你试过吗
d3.selectAll(".circle").attr("r", newValue);
答案 4 :(得分:3)
要从节点中删除所有元素:
var siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
for (var j = 0; j < siblings.length; j++) {
siblings[i].parentElement.removeChild(siblings[j]);
}
}`