18

Every D3js beginner must be going through this thought, I am pretty much sure about it.

I have been around this thing for few hours now!!!!But I don't know how to use it and what is the difference between them?

function(d){return d}

function(d,i){return d and some more custom code}

for Example--->

var data = [4, 8, 15, 16, 23, 42];

    Function(d):::::

    chart.selectAll("div")
         .data(data)
         .enter().append("div")
         .style("width", function(d) { return d * 10 + "px"; })
         .text(function(d) { return d; });

    ------------------------------------------------------------------------------------

 Function(d*i):::::

    chart.selectAll("rect")
        .data(data)
        .enter().append("rect")
        .attr("y", function(d, i) { return i * 20; })
        .attr("width", x)
        .attr("height", 20);
6
  • Well, they're doing different things? If you don't tell us about the context in which they're used (a call example), we won't be able to explain much?
    – Bergi
    Commented Jun 27, 2013 at 12:58
  • I am jsut asking a general question!!! Just a small basic explanation with example will do. I have been going through programs where i see this much often.So just basic general explanation will do!!!
    – user2412575
    Commented Jun 27, 2013 at 13:00
  • Well, the general answer is that the second function does more than the first. If you don't tell us where in some programs you have seen this, we can't do better (or have to guess like nnnnn below)
    – Bergi
    Commented Jun 27, 2013 at 13:03
  • ok,I will edit my question!!!!
    – user2412575
    Commented Jun 27, 2013 at 13:04
  • 1
    Have you read the .attr documentation? "If value is a constant, then all elements are given the same attribute value; otherwise, if value is a function, then the function is evaluated for each selected element (in order), being passed the current datum d and the current index i, with the this context as the current DOM element." Commented Jun 27, 2013 at 13:29

3 Answers 3

14

Your example is a good illustrator of the difference between the two.

In the first example, only d is used. d represents the data associated with a given selection. In this case, an array of selected div elements is created, one for each element in the data array:

chart.selectAll("div")
     .data(data)
     .enter()
     .append("div")

This not only creates an array of div elements, but associates data with each of those elements. This is done on a one-to-one basis, with each div corresponding to a single element in the data array. One is associated with '4', one with '8', and so on.

If I then go on to use .text(function(d){...}) on the array of selections, d will refer to the data associated with each selected div, so if I use the following method on my selections:

.text(function(d) { return d; });

Each of my divs will have text added, the value of which is d, or the data associated with the element.

When an array of selections is created, they are also given an index in the array. In your example, this corresponds to the position of their data in the data array. If your function requests both d and i, then i will correspond to this index. Going back to our divs, the div associated with '4' will have an index of '0', '8' will have an index of '1', and so on.

It's also important to note that the character used in the variable requested doesn't matter. The first variable in the function call is always the data, and the second is the index. If i used a method like

.text(function(cat,moose){ return( "data is: " + cat + " index is: " + moose)})

cat will correspond to the data of the selection, and moose will correspond to the index.

0
6

I hope that this example can help you. This is a complete web page where you can start playing:

<!doctype html>
<meta charset="utf-8">
<title>my first d3</title>
<body>

<script>
  var data=[10,20,30,40];

  var lis = d3.select("body")
              .append("ul")
              .selectAll("li")
              .data(data)

  lis.enter()
     .append("li")
     .text(function(d,i){ return "item n° "+i+" has value: "+d})
</script>

Basically d is the value of the data, and i is his index. You can take a look of this example here: http://jsfiddle.net/M8nK8/

0
1

If you're talking about the callback functions you would pass to methods like .attr(), then the function is called for each item in the current selection, where the i gives you the index of the current item, but depending on what you're doing you might not care about the index. So although D3.js will always call your function with both arguments, if you don't actually need the second argument in a particular case your function need not declare it explicitly.

JavaScript lets you call any function with any number of arguments regardless of how many were explicitly included in the function declaration. If you call a function with fewer arguments than were defined the leftovers will get the value undefined. If you call a function with more arguments than were defined you can still access the additional ones from within the function by using the arguments object - or you can ignore them.

(Note: you should have a lowercase f in function().)