Reputation: 437
Why does the following work:
var line = d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
var path = d3.select("#frame")
.append("path")
.attr("class", "line")
.attr("d", line(nodes.data()))
But if I directly integrate the function without declaring it first like this it doesn't work (It doesn't draw the line). Why is that? What do I have to change for it to work?
var path = d3.select("#frame")
.append("path")
.attr("class", "line")
.attr(
"d",
function() {
d3.line()
.x(function() { return nodes.data().x })
.y(function() { return nodes.data().y });
}
);
Upvotes: 0
Views: 577
Reputation: 1591
The code
var line = d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
is creating a line generator. A line generator is a function. If you call this function and pass it your data array, then it returns the a string for the "d" attribute of an SVG path, which defines the shape of the line.
The line generator needs to know how to get the x and y coordinates for a given element in your data array. This is defined by the functions that you pass to line.x()
and line.y()
. These functions get called individually for each element in your data array.
In your code, function(d) { return d.x; }
and function(d) { return d.y; }
will be called on each element in the data array in order to get the x and y coordinates for that element. The argument to these functions, d
, is a single element from your data array. It is not the entire data array.
If you don't want to define the line generator in a separate variable, then you could do the following:
var path = d3.select("#frame")
.append("path")
.attr("class", "line")
.attr("d", d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })(nodes.data())
);
This replaces line
in your first block of code with the entire line generator.
Your code doesn't work for two reasons. First, your line generator is
d3.line()
.x(function() { return nodes.data().x })
.y(function() { return nodes.data().y })
The functions that you are passing to x()
and y()
do not work correctly. These functions should define how to get the x and y coordinates for a single element in your data array, like function(d) { return d.x; }
. The argument, d
, is one element from your data array.
Second, in the code that you have, the line generator is never called on your data array. You don't need to put the line generator inside of another function, but if you did then it would look like this:
function() {
return d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })(nodes.data());
}
But there's no need for this outer function. You can just do what I showed above.
Upvotes: 4