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
Post a Comment