在d3的指导下,如何通过点击来改变节点的形状?

我在d3中有一个强制定向图,并希望能够点击圆形节点并将它们变成矩形。 然后,如果我点击一个矩形,我想它恢复到一个圆圈。

我已经看过这个和有关的问题,但我认为他们是D3的早期版本,不为我工作。

我可以做到这一点,我的圈子的大小和颜色会改变点击,并与下面的代码,我可以用一个黑色的矩形replace圆节点,但它不附加在图上,只是一个黑色的方块SVG。

node.on("click", function(d,i) { var size = 20; d3.select(this).remove(); svg.append("rect") .attr("x", dx) .attr("y", dy) .attr("height", size) .attr("width", size) .style("fill", function(d) { return color( d.group); }); }) 

任何人都可以告诉我我失踪了吗? 我怀疑rect没有被附加到graphics数据上,但是我没有足够的熟悉d3来理解我应该改变什么。 谢谢。

当你说:

我已经看过这个和有关的问题,但我认为他们是D3的早期版本,不为我工作。

在我看来,答案中没有任何暗示它在D3 v4.x中不起作用。 值得一提的是,在你链接的答案(和问题)中, node是一个组元素,因此this指的是组,而不是圆/矩形。

继续前进,一个可能的解决scheme(不涉及删除和附加元素)是模拟一个矩形的圆:

 node.append("rect") .attr("width", 16) .attr("height", 16) .attr("rx", 8) .attr("ry", 8) 

而且,在点击function里,改变rxry

 function click() { if(d3.select(this).attr("rx") == 8){ d3.select(this).attr("rx", 0).attr("ry", 0); } else { d3.select(this).attr("rx", 8).attr("ry", 8);}; }; 

这里是一个演示:

 var nodes = [ {"id": 1}, {"id": 2}, {"id": 3}, {"id": 4}, {"id": 5}, {"id": 6}, {"id": 7}, {"id": 8}, {"id": 9}, {"id": 10}, {"id": 11}, {"id": 12} ]; var links = [ {source: 1, target: 8}, {source: 1, target: 3}, {source: 1, target: 4}, {source: 1, target: 9}, {source: 1, target: 10}, {source: 1, target: 11}, {source: 2, target: 5}, {source: 2, target: 6}, {source: 2, target: 7}, {source: 2, target: 12}, {source: 2, target: 4}, {source: 2, target: 8}, {source: 6, target: 7}, {source: 6, target: 8}, {source: 6, target: 9}, {source: 6, target: 5}, {source: 6, target: 3}, {source: 6, target: 9}, ] var index = 10; var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), node, link; var simulation = d3.forceSimulation() .force("link", d3.forceLink().id(function(d) { return d.id; })) .force("charge", d3.forceManyBody()) .force("collide", d3.forceCollide(30)) .force("center", d3.forceCenter(width / 2, height / 2)); update(); function update() { link = svg.selectAll(".link") .data(links, function(d) { return d.target.id; }) link = link.enter() .append("line") .attr("class", "link"); node = svg.selectAll(".node") .data(nodes, function(d) { return d.id; }) node = node.enter() .append("g") .attr("class", "node"); node.append("rect") .attr("width", 16) .attr("height", 16) .attr("rx", 8) .attr("ry", 8) .attr("fill", "teal") .on("click", click); simulation .nodes(nodes) .on("tick", ticked); simulation.force("link") .links(links); } function click() { if(d3.select(this).attr("rx") == 8){d3.select(this).attr("rx", 0).attr("ry", 0);} else{d3.select(this).attr("rx", 8).attr("ry", 8);}; } function ticked() { link .attr("x1", function(d) { return d.source.x + 8; }) .attr("y1", function(d) { return d.source.y + 8; }) .attr("x2", function(d) { return d.target.x+ 8; }) .attr("y2", function(d) { return d.target.y+ 8; }); node .attr("transform", function(d) { return "translate(" + dx + ", " + dy + ")"; }); } 
 .link { stroke: #aaa; } .node { stroke: none; stroke-width: 40px; } 
 <script src="https://d3js.org/d3.v4.min.js"></script> <svg width="400" height="300"></svg>