1

I'm going through this example of a force based layout.

http://bl.ocks.org/sathomas/774d02a21dc1c714def8 The layout is defined as

force = d3.layout.force()
    .size([width, height])
    .nodes(dataNodes)
    .links(dataLinks);

Later in the code though the author iterates through the link array with this call

force.linkStrength(function(link) {
    if (link.className === 'red')  return 0.1;
    return 1;
});

How does the author know that function(link) will iterate over the link array and not the node array?

Jivan
  • 21,522
  • 15
  • 80
  • 131
canyon289
  • 3,355
  • 4
  • 33
  • 41

1 Answers1

1

Because when you write this:

force = d3.layout.force()
    .size([width, height])
    .nodes(dataNodes)
    .links(dataLinks);

You're doing what is called a method chaining. d3.js is known to use them a lot and each method chaining (with this framework at least) returns an object, depending of the method you call. With this particular code, it acts this way:

  1. Set the size of the force object and return the force object
  2. Set the nodes of the force object and return the nodes property of force
  3. Set the links of the nodes object, and return the links property of nodes

So, each method chaining that you add returns something different. At the end of all the method calls, the whole thing will be considered as returning the return value of your last call, and it will assign it to the variable at the left of the = operator. Here, your force variable.

It's exactly as if you wrote:

force = d3.layout.force()
force = force.size([width, height])
force = force.nodes(dataNodes)
force = force.links(dataLinks)

When, later on, you iterate over your force variable, you necessarily iterate over the links array, because that's what you assigned to force.

Tip 1: The tricky part is that here, and generally in d3.js, each method does not return the same objects. Both d3.layout.force() and size() return the actual force object, whereas nodes() returns the nodes object and links() returns the links object. It's cascading method chaining. Each element of the chain is called on the object returned by the previous method call.

Tip 2: you can understand from this that it's not necessarily the best fit to name this variable force.

There's also a cool explanation that goes into further details from Scott Murray.

Community
  • 1
  • 1
Jivan
  • 21,522
  • 15
  • 80
  • 131