javascript - In d3 force directed, how do I change a nodes shape by clicking on it? -
i have force directed graph in d3, , want able click on circular nodes , have them turn rectangles. if click on rectangle, i'd revert circle.
i have looked @ this , related questions on so, think earlier versions of d3, , not work me.
i can make size , colour of circles change on click, , following code can have circle node replaced black rect, not attached graph , black square on svg.
node.on("click", function(d,i) { var size = 20; d3.select(this).remove(); svg.append("rect") .attr("x", d.x) .attr("y", d.y) .attr("height", size) .attr("width", size) .style("fill", function(d) { return color( d.group); }); }) can show me i'm missing? suspect rect not being attached graph data not familar enough d3 understand should change. thank you.
it makes little sense when say:
i have looked @ , related questions on so, think earlier versions of d3, , not work me.
it seems me nothing in that answer suggests won't work in d3 v4.x. it's worth mentioning that, in answer (and question) linked, node group element, , therefore this refers group, not circle/rectangle.
moving on, possible solution (which doesn't involve removing , appending elements) simulate circle rectangle:
node.append("rect") .attr("width", 16) .attr("height", 16) .attr("rx", 8) .attr("ry", 8) and, inside click function, changing rx , ry:
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);}; }; here demo:
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(" + d.x + ", " + d.y + ")"; }); } .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>
Comments
Post a Comment