javascript - Can I use selectAll to create new element when elements of same type already exist? -


i want use 2 different data sources add g elements svg. however, end binding second data source existing g elements rather creating new g elements.

here's example

<!doctype html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>  </head> <body>     <div id="body"></div>     <script type="text/javascript">      var canvas_w = 1280 - 80,         canvas_h = 800 - 180;      var svg = d3.select("#body").append("div")         .append("svg:svg")         .attr("width", canvas_w)         .attr("height", canvas_h)         var category_cells = svg.selectall("g")         .data([0, 1, 2])         .enter().append("g")         .attr("class", "category")         .attr("transform", function(d) {console.log(d); return "translate(" + d*100 + ", 0)"; });      category_cells.append("rect")         .attr("y", 0)         .attr("x", 0)         .attr("width", 50)         .attr("height", 50)         .style("fill", "blue");      var cell = svg.selectall("g")         .data([3, 4, 5])         .enter().append("g")         .attr("class", "cell")         .attr("transform", function(d) {console.log(d); return "translate(" + d*100 + ", 0)"; });      cell.append("rect")         .attr("y", 0)         .attr("x", 0)         .attr("width", 50)         .attr("height", 50)         .style("fill", "black");      </script> </body> </html> 

this script displays 3 boxes of class g.category instead of 6 boxes 3 of class g.category , 3 of class g.cell. logs "1 2 3" showing transformation after enter statement g.cell never entered. additionally, if update transformation @ end of script adding

svg.selectall("g.category")     .attr("transform", function(d) {console.log(d); return "translate(" + d*100 + ", 0)"; }); 

the g.category transformation changes reflect data [3 4 5]. it's clear new data overwriting g.category data rather being assigned new g.cell elements, how can prevent happening?

the tutorials , documentation have read talk binding data elements don't yet exist, don't handle case elements of same type exist.

my guess solution lies somewhere in update pattern. documentation there several places can change attributes of various elements.

var update_sel = svg.selectall("g").data(data) update_sel.attr(/* operate on old elements */) update_sel.enter().append("g").attr(/* operate on new elements */) update_sel.attr(/* operate on old , new elements */) update_sel.exit().remove() /* complete enter-update-exit pattern */ 

but doesn't explain how data call changes data binding of old elements.

using selectall() create new elements while preserving existing elements asks how use selectall without nesting elements inside of each other isn't issue facing.

the problem default, d3 uses index match data. is, first datum matches first dom element in selection, second second, , on. in code, you're selecting g elements in both cases, second time code run, data rebound elements , result don't expect.

the solution simple -- select elements classes you've assigned, i.e. use .selectall("g.category") , .selectall("g.class") when creating elements. alternatively, provide key function .data() tell d3 how match elements , data prevent rebinding, imho less intuitive.


Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

datatable - Matlab struct computations -