javascript - Circle Pack Layout D3 - remove add nodes on new data -
i have situation want users browse 3 different data sets using circle pack layout. using bostock's zoomable circle packing.
i have added 3 options additionally loads data , creates new nodes. here chartid passed these elements.
function changedataset(chartid) { console.log(chartid); //console.log(nodes);
//add new chart data depending on selected option if(chartid === "plevels") { root = json.parse(newkmap_slevels); focus = root; nodes = pack.nodes(root); } else if (chartid === "pduration") { root = json.parse(newkmap_sduration); focus = root; nodes = pack.nodes(root); } else { root = json.parse(newkmap_stype); focus = root; nodes = pack.nodes(root); } refresh();
}
then have refresh function, not understnading how remove existting nodes, , add new ones based on new data set. showing transition animations nice also.
currently trying remove , recreate initial elements, chart goes blank when that.
var refresh = function() { //var nodes = pack.nodes(root); var duration = 10; console.log(nodes); d3.select("#conf_knowledge_map").selectall("g") .remove(); svg .attr("width", diameter) .attr("height", diameter) .append("g") .attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")"); circle = svg.selectall("circle") .data(nodes) .enter().append("circle") .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; }) .style("fill", function(d) { return d.children ? color(d.depth) : null; }) .on("click", function(d) { if (focus !== d) zoom(d), d3.event.stoppropagation(); }); text = svg.selectall("text") .data(nodes) .enter().append("text") .attr("class", "label") .style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; }) .style("display", function(d) { return d.parent === root ? "inline" : "none"; }) .text(function(d) { //console.log(d); if( d.size ) { return d.name + ":" + d.size; } else return d.name; }); }
so question how can remove , create new nodes on click?
update
i able remove nodes , add new nodes based on new data, on click zoom layout messed up. transform function not applied new nodes somehow.
var refresh = function() { svg.selectall(".node").remove(); svg.selectall(".label").remove(); var nodes = pack.nodes(root); focus = root; circle = svg.selectall("circle") .data(nodes) .enter() .append("circle") .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; }) .attr("r", function(d) { return d.r;}) .attr("cx", function(d) { console.log(d); // if(d.depth === 0) // return 0; // else // return d.x - (diameter/2); return d.x; }) .attr("cy", function(d) { return d.y; }) // .attr("transform", "translate(" + "x" + "," + "y" + ")") .style("fill", function(d) { return d.children ? color(d.depth) : null; }) .on("click", function(d) { // d.x = d.x - (diameter/2); // d.y = d.y - (diameter/2); if (focus !== d) zoom(d), d3.event.stoppropagation(); }); text = svg.selectall("text") .data(nodes) .enter().append("text") .attr("class", "label") .attr("x", function(d) {return d.x - (diameter/2);}) .attr("y", function(d) {return d.y - (diameter/2);}) .style("fill-opacity", function(d) { return d.parent === root ? 1 : 0; }) .style("display", function(d) { return d.parent === root ? "inline" : "none"; }) // .attr("transform", "translate(" + "x" + "," + "y" + ")") .text(function(d) { //console.log(d); if( d.size ) { return d.name + ":" + d.size; } else return d.name; }); }
how can transform new nodes in place , zoom work properly?
update 2 transform working after attaching 'g' element circles, , showing nodes , text correctly. problem zoom not work when click on circles!!
circle = svg.selectall("circle") .data(nodes) .enter() .append("circle") .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; }) .attr("r", function(d) { return d.r;}) .attr("cx", function(d) { if(d.depth === 0) return 0; else return d.x - (diameter/2); }) .attr("cy", function(d) { if(d.depth === 0) return 0; else return d.y - (diameter/2); }) .style("fill", function(d) { return d.children ? color(d.depth) : null;}) .on("click", function(d) { if (focus !== d) zoom(d); d3.event.stoppropagation(); }) .append("g") .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) ;
how make zoom work??
it happens making mistake of simultaneously creating 3 independent circle pack layouts, mixed statements 1 after other. problematic when have select svg sections, different elements getting selected , wrongly attached different events.
so decided separate 3 implementations , create 3 layouts 1 after other, after each 1 finished. way kept section selection , attaching events etc, separate , load them , when required.
Comments
Post a Comment