Reputation: 161
I am trying to understand javascript code by getting my hands dirty.. My background is mostly python and C++.
So I was going thru this code here
http://bl.ocks.org/mbostock/1021841
var force = d3.layout.force()
.nodes(nodes)
.links([])
.size([w, h])
.start();
I am guessing that "." represents a method.. but to which object? and I am having hard time understanding this convoluted function (method??)
force.on("tick", function(e) {
// Push different nodes in different directions for clustering.
var k = 6 * e.alpha;
nodes.forEach(function(o, i) {
o.y += i & 1 ? k : -k;
o.x += i & 2 ? k : -k;
});
Can someone break it down to me in simpler language. Thanks
Upvotes: 1
Views: 437
Reputation: 234795
This code:
var force = d3.layout.force()
.nodes(nodes)
.links([])
.size([w, h])
.start();
should be read in basically the same you would read it if it were C++ (except for the var
keyword; in C++ you'd have to declare a particular type for force
). Like C++, white space is (mostly) insignificant. Each .
indicates a property access. (Unlike C++, JavaScript objects don't distinguish fields from methods; everything is a property. If it's a function property, then it can be called by following the name with parentheses—with function arguments in the parentheses if appropriate.) So what's going on here is:
d3.layout
- access the layout
property of d3
..force()
- invoke the force
function that is a property of d3.layout
. Inside force
, d3.layout
would be available as the keyword this
..nodes(nodes)
- invoke the nodes
function that is a property of whatever object was returned by the call to force()
(perhaps d3.layout
, perhaps something else).finally assigning to force
the value returned by start()
.
Regarding the second piece of code:
force.on("tick", function(e) {
// Push different nodes in different directions for clustering.
var k = 6 * e.alpha;
nodes.forEach(function(o, i) {
o.y += i & 1 ? k : -k;
o.x += i & 2 ? k : -k;
});
Here we see an example (two, actually) of an anonymous function
. Based on usual JavaScript conventions, the on
function of force
is probably used to register an event hander—in this case for the "tick"
event. The event handler is the anonymous function:
function(e) {
// Push different nodes in different directions for clustering.
var k = 6 * e.alpha;
nodes.forEach(function(o, i) {
o.y += i & 1 ? k : -k;
o.x += i & 2 ? k : -k;
}
For purposes of explanation, let's call this function "outer". It takes an argument which I would guess is an object containing the properties of the tick event. In the body of outer, we see another anonymous function: the argument to nodes.forEach
. Let's call this second anonymous function "inner". The forEach
function here is most likely the standard forEach
iterator function that is a property of all JavaScript arrays; it takes a function as an argument and invokes the function on every element of the array in sequence, passing the array element and the element index. Inner is actually an example of a closure: the function body references variable k
which is defined as a local variable of outer.
JavaScript is in some ways just like C++ and in some ways fundamentally different. Unless you know where the similarities end and the differences begin, your C++ background can lead you seriously astray in your coding (and code reading) efforts. I highly recommend the introductory paper "A re-introduction to JavaScript". It covers all the major features of the language and should help clarify just how C++ and JavaScript are similar and how they are different.
Upvotes: 3
Reputation: 707218
This:
var force = d3.layout.force()
.nodes(nodes)
.links([])
.size([w, h])
.start();
Is the same as this:
var force = d3.layout.force().nodes(nodes).links([]).size([w, h]).start();
The value of the variable force
will be the return value from the last method in the chain (in this case .start()
).
This is called method chaining. Each successive function is called as a method on the return value of the function before it.
So, the method .nodes(nodes)
is called on the object that is returned from d3.layout.force()
and the method .links([])
is called on the object returned from .nodes(nodes)
and so on.
Upvotes: 1