admin管理员组文章数量:1429648
I'm creating some static SVG elements with d3.js and they share a lot of properties.
var c1 = svg.append('circle').attr('r',20);
var c2 = svg.append('circle').attr('r',40);
...
I want to group these together to set other attributes. I thought that I could use push, i.e.
var circles = svg.append('circle').attr('r',20);
circles.push( svg.append('circle').attr('r',40));
...
circles.attr('stroke','black').attr('stroke-width',2);
but that errors ("this.setAttribute is not a function")
d3 is all about sets of stuff, and it's all about arrays, so I thought this work work? Is there a way?
(I know I could do a data join but I'm wondering about a more generic case of manipulating several things at once)
I'm creating some static SVG elements with d3.js and they share a lot of properties.
var c1 = svg.append('circle').attr('r',20);
var c2 = svg.append('circle').attr('r',40);
...
I want to group these together to set other attributes. I thought that I could use push, i.e.
var circles = svg.append('circle').attr('r',20);
circles.push( svg.append('circle').attr('r',40));
...
circles.attr('stroke','black').attr('stroke-width',2);
but that errors ("this.setAttribute is not a function")
d3 is all about sets of stuff, and it's all about arrays, so I thought this work work? Is there a way?
(I know I could do a data join but I'm wondering about a more generic case of manipulating several things at once)
Share Improve this question asked Oct 23, 2014 at 9:16 artfulrobotartfulrobot 21.5k12 gold badges62 silver badges92 bronze badges 3-
No need for an array, just do a selection after you're done adding all the elements:
var circles = svg.selectAll("circles");
. – Lars Kotthoff Commented Oct 23, 2014 at 9:40 - Thanks, but if I have to use a selector I need to provide selectable identifiers/grouping info on each node and assume a mon parent (or do a full search on whole document as which is inefficient). There must be a way to append a given node/d3 object to an existing selection... – artfulrobot Commented Oct 23, 2014 at 10:21
- 1 Not without hacking it (the API doesn't provide a function for this). This case usually doesn't arise because when you're using D3's data matching you don't need to dynamically "grow" a selection. – Lars Kotthoff Commented Oct 23, 2014 at 10:31
2 Answers
Reset to default 3If you want to do things this way, you need to know how a d3.selection
differs from an Array
.
Mike Bostock wrote up a good explanation of the topic HERE.
Here are the important bits:
You were probably told that selections are arrays of DOM elements. False. For one, selections are a subclass of array; this subclass provides methods to manipulate selected elements, such as setting attributes and styles.
...
Another reason selections aren’t literally arrays of elements is that they are arrays of arrays of elements: a selection is an array of groups, and each group is an array of elements.
So, it turns out the Array that you want to .push
to is actually nested within the Array-subclass that represents the selection. If your selection is stored in the variable circles
you can access the actual Array of elements as circles[0]
.
Another important thing to note: the inner Array holds the actual DOM element reference, not a selection of it. To get the element reference from a selection containing a single element, simply call .node()
on the selection.
You could start by creating an empty selection:
var circles = d3.selectAll('.empty');
That's a nice, semantic way to do it assuming you don't have anything classed "empty" on your page.
Then you can .push
the .node
of each circle selection that you .append
directly into circles[0]
:
circles[0].push(svg.append('circle').attr('r',40).node());
Do this as many times as you want, and then you can set styles/attributes for all of your circles by calling standard selection methods on circles
:
circles
.attr('stroke', 'black')
.attr('stroke-width', 2)
HERE is a demo.
I think an alternative way is to select by multiple classes, e.g.,
d3.selectAll(".class1,.class2").attr('...', '...')...
We can simply assign two selections with different classes or the same class (if you needn't treat them separately).
本文标签: javascriptHow to combine two d3 objects into one for bulk operationsStack Overflow
版权声明:本文标题:javascript - How to combine two d3 objects into one for bulk operations - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745536349a2662289.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论