d3.js - check if d3.select or d3.selectAll -
i have method on reusable chart can passed selection , return value if passed d3.select('#id')
selection or array of values if passed d3.selectall('.class')
selection. i'm interrogating passed argument context._groups[0] instanceof nodelist
, feels little fragile using undocumented property, may change in future versions. there more built in way of determining if selection comes select
or selectall
?
selection.size()
not here, tells result of selection, not how called.
edit: here's context of use. i'm using mike bostock's reusable chart pattern , instance includes method getting/setting label donut.
to me, api usage follows principle of least astonishment, it's how expect result returned.
var donut = app.rotatingdonut(); // set label 1 element d3.select('#donut1.donut') .call(donut.label, 'donut 1') d3.select('#donut2.donut') .call(donut.label, 'donut 2') // set label multiple elements d3.selectall('.donut.group-1') .call(donut.label, 'group 1 donuts') // label 1 donut var donutonelabel = d3.select('#donut1').call(donut.label) // donutonelabel === 'donut 1' // label multiple donuts var donutlables = d3.selectall('.donut').call(donut.label) // donutlabels === ['donut 1', 'donut 2', 'group 1 donuts', 'group 1 donuts']
and internal method definition:
app.rotatingdonut = function() { var label = d3.local(); function donut() {} donut.label = function(context, value) { var returnarray; var islist = context._groups[0] instanceof nodelist; if (typeof value === 'undefined' ) { // getter returnarray = context.nodes() .map(function (node) {return label.get(node);}); return islist ? returnarray : returnarray[0]; } // settter context.each(function() {label.set(this, value);}); // allows method chaining return donut; }; return donut }
well, question here @ s.o. doesn't have answer (it has happened before).
that seems case of question of yours: "is there more built in way of determining if selection comes select or selectall?". no.
to prove that, let's see source code d3.select
, d3.selectall
(important: not selection.select
, selection.selectall
, different each other).
first, d3.select:
export default function(selector) { return typeof selector === "string" ? new selection([[document.queryselector(selector)]], [document.documentelement]) : new selection([[selector]], root); }
now, d3.selectall:
export default function(selector) { return typeof selector === "string" ? new selection([document.queryselectorall(selector)], [document.documentelement]) : new selection([selector == null ? [] : selector], root); }
as can see, have two differences here:
d3.selectall
acceptsnull
. not you.d3.selectall
usesqueryselectorall
, whiled3.select
usesqueryselector
.
that second difference 1 suits you, know now, since queryselectorall:
returns list of elements within document (using depth-first pre-order traversal of document's nodes) match specified group of selectors. object returned nodelist. (emphasis mine)
and queryselector only...:
returns first element within document matches specified selector, or group of selectors.
therefore, undocumented (and hacky, since using _groups
, not idea) selection._groups[0] instanceof nodelist
using right seems way tell selection created d3.select
selection created d3.selectall
.
Comments
Post a Comment