Reputation: 147
It says method chaining in D3.js performs several actions in single line of code. But i am not sure how much it cares about performance while executing.
For example, By method chaining ,we would like to put the code like below:
var data =[10,20,30,40]
wrap.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x",function(d, j) {return scale(j); })
.attr("y",function(d,i){ return (h-d)})
.attr("width",scale.rangeBand())
.attr("height",function(d,i){ return (d)})
.style("fill","red");
In the above code,it will generate 4 rectangles, then for each 4 rectangles we are setting the attribute "x","y","width","height".
No.of rectangles ---> 4 No.of attributes("x","y","width","height") ---> 4 No.of iteration for each attribute ---> 4 (sine 4 rectangles) No.of iteration for 4 attributes ---> 4*4=16 times
Is it really necessary of such number of iterations?Is it fast performance?
Normally we do like this,
wrap.forEach(function(d,i){
d.setAttribute("x", scale(i))
d.setAttribute("y",(h-d))
d.setAttribute("width",w)
d.setAttribute("height",h)
})
In the above method ,No.of iterations used --> 4
So whats the advantage of d3.js method chaining and selection.daa with the above mentioned conventional approach Please clarify me??
Upvotes: 2
Views: 698
Reputation: 31
I was thinking about this today.
I think there is a fundamental problem with chaining. Namely, you cannot partition data into different shapes that easily. And, if you could, you can't assume similar attributes chained from different shapes. A square and a circle say, have different attributes to define their size and location.
But, assigned from this conflict, which is not resolved by symbols, there remains the question, which you have asked, "Is it an efficient representation?"
It make the code look nice. But, in fact each one is a function call that can go down a deep stack for anything to happen. And, that's slow.
So, one begins to think of an alternative similar to your loop. Or, perhaps the attributes can be gathered and assigned in one last shot - almost a compilation.
Don't forget that JavaScript is interpreted.
It is easy to get deceived into thinking that JavaSript will provide the efficiency you are looking for in certain applications. Of course, a tired user clicking on this and that would not notice the difference. But, there is the animation and the interaction of working parts when changes cascade in some way. Certain applications really need the efficiency.
Even the forEach that you are using can be suspect. I was working with a younger programmer last year, using D3. And, there was some part of one of our displays that ran woefully slowly. (A tired used would have certainly been awoken into a tizzy.) We took it out of the forEach and ran it in a regular "for" loop construct. Then, the same code ran with incredible speed. So, there are parts of JavaScript that are not as ready for prime time as you might think.
It is probably better to use many of the new constructs that are making their way into the language for many parts of an application. But, when it counts, you might wait for some update and use more optimized parts of the language.
I am fairly sure that d3 is not optimal in setting attributes. And, now I am trying to think of some better representation than chaining.
Upvotes: 2
Reputation: 4904
Remember the act of iterating itself is negligible. If the cost of setting an attribute was 1 you are comparing 16 * 1 with 4 * 4. Therefore it's not really a big problem. The chaining is a matter of concision.
Using Big O notation to analyse the algorithms, both are O(n).
Upvotes: 0