Choice in D3, jQuery

In a response, Mike posted here , he considers three different ways to apply a change to a consistent item based on an index or a custom filter. I am trying to clarify, I hope, for more people than just me, the actual choice in these decisions.

Therefore, given the document with 6 SVG rectangles with the class .bar , we have these different options and what they return:

d3.select (". bar"):

 [Array[1] 0: rect.[object SVGAnimatedString] length: 1 parentNode: html __proto__: Array[0] 

d3.selectAll ("bar."):

 [Array[6] 0: rect.[object SVGAnimatedString] 1: rect.[object SVGAnimatedString] 2: rect.[object SVGAnimatedString] 3: rect.[object SVGAnimatedString] 4: rect.[object SVGAnimatedString] 5: rect.[object SVGAnimatedString] length: 6 parentNode: html __proto__: Array[0] 

$ ("bar."):

 [ <rect class=​"dataBars" x=​"53.191489361702125" width=​"212.7659574468085" y="4.761904761904762" height=​"11.11111111111111">​</rect>​, <rect class=​"dataBars" x=​"74.46808510638297" width=​"372.3404255319149" y=​"20.634920634920636" height=​"11.11111111111111">​</rect>​, <rect class=​"dataBars" x=​"127.6595744680851" width=​"212.7659574468085" y=​"36.507936507936506" height=​"11.11111111111111">​</rect>,​ <rect class=​"dataBars" x=​"31.914893617021274" width=​"212.7659574468085" y=​"52.38095238095238" height=​"11.11111111111111">​</rect>​, <rect class=​"dataBars" x=​"159.5744680851064" width=​"265.9574468085106" y=​"68.25396825396825" height=​"11.11111111111111">​</rect>​, <rect class=​"dataBars" x=​"234.04255319148936" width=​"138.29787234042553" y=​"84.12698412698413" height=​"11.11111111111111">​</rect>​, ] 

Now that it gets more complicated (at least for me), let's say I want to apply style to the third rectangle, this rectangle can be found using

 d3.selectAll(".bar")[0][2] 

But if we want to use d3.selection.attr() , which returns

 TypeError: Property 'style' of object #<SVGRectElement> is not a function 

But we can wrap this choice

 d3.select(d3.selectAll(".bars rect")[0][2]).style("fill", "red") 

and it will work as expected.

Then, if we want to apply a filter, for example

 filter(function (d) { return d === 5 || d === 15;} 

you should use d3.selectAll(".bar") , and d3.select(d3.selectAll(".bar")) will not work.

I read Mike excellent tutorials and election documentation, but when I think I understand something pops up and it surprises me. So what is the difference between these choices and how can I find out which one to use? Thank you very much and sorry for the long post!

+4
source share
2 answers

In general, you should not access the elements of the return selection by their indices, but rather filter or use a subsegment. This way you can use .attr() and .atyle() without any problems. The reason for this is that D3 does not return a "clean" array of DOM elements (such as jquery), but elements in a shell that supports D3 operations. It still behaves like an array, but if you point to it, you will get a "clean" DOM ​​element. You can also provide a DOM element for d3.select() , and it will generate a wrapper around this element, which allows all D3 materials to be used.

If you look at the documentation for filter() , you will find several usage examples and sub-segments. You can use these methods to get the third element of choice, for example. Using the .filter() function only makes sense if you have attached data to the objects you are filtering, otherwise the subsegment should do what you want.

+3
source

I tried to do this in the past and encountered similar errors. Then I realized that I really did not adhere to the intended API. Secondly, you begin to get access to the selection items by index, you move away from the beaten path.

See nested options

So, if you want to create your third bar, you would do

 d3.selectAll(".bar").style("color", function(d,i) { return i === 2 ? "red" : null; } ) 

And if your choice is one level more nested than this, make it function(d,i,j) and similarly from there. Etc.

+5
source

Source: https://habr.com/ru/post/1493031/


All Articles