javascript - D3.js: Attributes after enter().append() not setting -
like people, i'm struggling d3's data join mechanics. have read every article on subject, , (mostly) bad. christian behrens' guest-and-chair party analogy best, though warn readers neglects 2/3 through, beginning "now our update() function performs 2 different sets of actions" -- doesn't clarify here that, apparently, dom construction (append/remove) calls ignored update selection, while attribute calls processed 3 selection types, despite appearing seamlessly in 1 method chain. (for part, mike bostock's several efforts @ explaining data joins , method chaining range mildly condescending entirely complicating matters.)
i still have problem understanding membrane between data() , enter(), when save variable , how calls in given chain operate on objects, , chain return value variable saves, , how should know (clearly, attr not affect variable, in chain includes series of selects, data, , enters, returned?); hence mild criticism of otherwise excellent behrens essay, because has promise there.
below, have force layout (could layout) displays 2 nodes on startup, , if click of nodes, third should added.
var graph = { "nodes":[ {"name":"1" }, {"name":"2" } ], "links":[ {"source":0,"target":1} ] } var width = 500, height = 400; var force = d3.layout.force() .size([width, height]); var svg = d3.select("#map").append("svg") .attr("width", width) .attr("height", height) .append("g") var rect = svg.append("rect") .attr("width", width) .attr("height", height) .style("fill", "none") .style("pointer-events", "all"); var container = svg.append("g"); force .nodes(graph.nodes) .links(graph.links) .start(); var link = container.append("g") .attr("class", "links") .selectall(".link") .data(graph.links) .enter() .append("line") .attr("class", "link") .style("stroke-width", function(d) { return math.sqrt(d.value); }); var nodes = container.append("g") .attr("class", "nodes"); function update() { var n = nodes.selectall(".node").data(graph.nodes); ne = n.enter() .append("g") .attr("class", "node") .attr("cx", function(d) { return d.x; }) // sets on initial enter() not on click .attr("cy", function(d) { return d.y; }); // sets on initial enter() not on click ne.append("rect") .attr("width", "20") .attr("height", "20") .attr("fill", "red"); return n; } // end update() var node = update(); force.on("tick", function() { link.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; }); node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); }); node.on("click", function(d) { graph.nodes.push({ "name":"3" }); update(); }); // end .on("click")
i made update() function economize, following behrens. setting cx , cy works fine not when click on node. new nodes stay @ [0,0]. think there must problem in way manage arguments , returns on update(). better way this, 1 works?
you're missing 2 small things. first, need restart force layout node positions updated, , need update node
you're using inside tick
handler function:
node.on("click", function(d) { graph.nodes.push({ "name":"3" }); node = update(); force.start(); });
complete demo here.
very helpful! Here you will get all kind of solution like
ReplyDeletedlink australia
D-link Tech Support
d link router password