I have a dynamic array to show a line graph with several lines. Example:
var data =
[[{x:2005, y:100}, {x:2007, y:96.5}, {x:2009, y:100.3}, {x:2011, y:102.3}],
[{x:2005, y:100}, {x:2007, y:105}, {x:2009, y:102}, {x:2011, y:104}]]
This part of my script will draw the lines:
graph.selectAll("path.line")
.data(data)
.enter().append("path")
.attr("class", "line")
.style("stroke", function(d, i) { return d3.rgb(z(i)); })
.style("stroke-width", 2)
.attr("d", d3.svg.line()
.y(function(d) { return y(d.y); })
.x(function(d,i) { return x(i); }));
(The script I'm using is based on .linegraph/linegraph.js)
My problem: the data array is dynamic, I don't know beforehand what's in it. Sometimes the y value for 2005 will be null:
var data =
[[{x:2005, y:100}, {x:2007, y:96.5}, {x:2009, y:100.3}, {x:2011, y:102.3}],
[{x:2005, y:null}, {x:2007, y:105}, {x:2009, y:102}, {x:2011, y:104}]]
How can I make the second line ignore the first object, and start at 2007?
Based on answer 1 this is what I have now, still showing the whole line:
data =
[[{x:2005, y:100}, {x:2007, y:96.5}, {x:2009, y:100.3}, {x:2011, y:102.3}],
[{x:2005, y:null}, {x:2007, y:105}, {x:2009, y:102}, {x:2011, y:104}]];
var validatedInput = function(inptArray) {
return inptArray.filter(function(obj) {
return obj.y != null;
});
};
graph.selectAll("path.line")
.data(data, validatedInput)
.enter().append("path")
.attr("class", "line")
.style("stroke", function(d, i) { return d3.rgb(z(i)); })
.style("stroke-width", 2)
.attr("d", d3.svg.line()
.y(function(d) { return y(d.y); })
.x(function(d,i) { return x(i); }));
I have a dynamic array to show a line graph with several lines. Example:
var data =
[[{x:2005, y:100}, {x:2007, y:96.5}, {x:2009, y:100.3}, {x:2011, y:102.3}],
[{x:2005, y:100}, {x:2007, y:105}, {x:2009, y:102}, {x:2011, y:104}]]
This part of my script will draw the lines:
graph.selectAll("path.line")
.data(data)
.enter().append("path")
.attr("class", "line")
.style("stroke", function(d, i) { return d3.rgb(z(i)); })
.style("stroke-width", 2)
.attr("d", d3.svg.line()
.y(function(d) { return y(d.y); })
.x(function(d,i) { return x(i); }));
(The script I'm using is based on http://cgit.drupalcode/d3/tree/libraries/d3.linegraph/linegraph.js)
My problem: the data array is dynamic, I don't know beforehand what's in it. Sometimes the y value for 2005 will be null:
var data =
[[{x:2005, y:100}, {x:2007, y:96.5}, {x:2009, y:100.3}, {x:2011, y:102.3}],
[{x:2005, y:null}, {x:2007, y:105}, {x:2009, y:102}, {x:2011, y:104}]]
How can I make the second line ignore the first object, and start at 2007?
Based on answer 1 this is what I have now, still showing the whole line:
data =
[[{x:2005, y:100}, {x:2007, y:96.5}, {x:2009, y:100.3}, {x:2011, y:102.3}],
[{x:2005, y:null}, {x:2007, y:105}, {x:2009, y:102}, {x:2011, y:104}]];
var validatedInput = function(inptArray) {
return inptArray.filter(function(obj) {
return obj.y != null;
});
};
graph.selectAll("path.line")
.data(data, validatedInput)
.enter().append("path")
.attr("class", "line")
.style("stroke", function(d, i) { return d3.rgb(z(i)); })
.style("stroke-width", 2)
.attr("d", d3.svg.line()
.y(function(d) { return y(d.y); })
.x(function(d,i) { return x(i); }));
Share
Improve this question
edited Jul 23, 2014 at 8:50
eindgebruiker
asked Jul 20, 2014 at 22:45
eindgebruikereindgebruiker
1611 gold badge2 silver badges6 bronze badges
2 Answers
Reset to default 8In the end I solved this myself, based on the solution here. The trick is to remove the empty values as late as possible, so the positions of all values (points) on the canvas are preserved.
graph.selectAll("path.line")
.data(data)
.enter().append("path")
.attr("class", "line")
.style("stroke", function(d, i) { return d3.rgb(z(i)); })
.style("stroke-width", 2)
.attr("d", d3.svg.line()
.y(function(d) { return y(d.y); })
.defined(function(d) { return d.y; }) // Omit empty values.
.x(function(d,i) { return x(i); }));
This will work for empty values at the start and end of a line.
This should do it:
.data(data, function(inptArray) {
return inptArray.filter(function(obj) {
return obj.y != null;
})
});
it would be better though to write it like this:
var validatedInput = function(inptArray) {
return inptArray.filter(function(obj) {
return obj.y != null;
});
.data(data, validatedInput);
Or you can just format your data object before given it to D3:
var data = data.map(function(obj){
return obj.filter(function(obj) {
return obj.y != null;
})
})