score:4

Accepted answer

The object arc created by d3.svg.arc() is a function itself, which takes the data object attached to the pieSlice as a parameter and returns the path directions string.

So writing this:

.attr("d", function(d, i){
       return arc; 
})

is equivalent to writing:

.attr("d", function(d, i){
       return function(d2, i2){
              /* Do stuff here */
       }; 
})

Now there are times in d3 code where you do want one function to return another function -- but this isn't one of those times! D3 is expecting your function to return a string for the attribute value, and so the arc function gets converted to a string, and that gets set as the attribute value. And of course your browser doesn't know how to draw a path from directions like "function n(){var n=t.apply...." etc., so it throws an error.

In contrast, when you write

.attr("d", arc )

d3 checks the value you gave it (arc), sees that it is a function, and calls it for each element with the appropriate data and index, and the arc function returns the appropriate path directions string.

If you did need to use your own function, you would then need to call the arc function with the data value and index as arguments. This might happen if the pie data was stored in a sub-property of your data object instead of being the data object as a whole.

.attr("d", function(d,i) {

      /* calculate something here */

      return arc(d.pieData); //return the *result* of the arc function
                             // NOT the function itself!

 })

I honestly can't thing of any case where you'd have to do it this way for pie data (because you can just change the accessor functions on the arc object instead), but you often see this structure for line graphs, where you have to grab the sub-array of datapoints to pass to the line-drawing function.


Related Query

More Query from same tag