Reputation: 10941
I'm trying to create a multi line chart using d3 and data in a json format. For some reason my code isn't working. I haven't been able to find out where I'm doing wrong. Have searched the web and read a lot of examples, to no avail. I've probably stared me blind on the code.
In the example, I'm only trying to draw two lines, but the number of lines are not known. So I can't hard code it. Does anyone have any tips on where I'm doing wrong?
Jsfiddle link to the code. http://jsfiddle.net/6qrcmsnj/3/
Here is also the code.
var w = 700;
var h = 600;
var pad = 80;
var time_format = d3.time.format("%I:%M:%S");
var gd = example_data(4);
var xScale = d3.time.scale()
.domain(d3.extent(gd[0].data, function(d) { return d[0]; }))
.range([pad, w - pad]);
var yScale = d3.scale.linear()
.domain([0, d3.max(gd[0].data, function(d) { return d[1]; })*2])
.range([h - pad, pad]);
var canvas = d3.select("body")
.append("svg")
.attr("class", "chart")
.attr("width", w)
.attr("height", h);
var xaxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(time_format);
var yaxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var line = d3.svg.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); })
.interpolate("linear");
// Just for a grey background.
canvas.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#E8E8E8");
// Add x-axis.
canvas.append("g")
.attr("class", "axis")
.attr("transform","translate(0," + (h - pad) + ")")
.call(xaxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d) {
return "rotate(-65)"
});
// Add y-axis
canvas.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + pad + ", 0)")
.call(yaxis);
// Add line
canvas.selectAll("path")
.data(gd)
.enter().append("path")
.attr("d", line(gd.data))
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("fill", "none");
function example_data(val) {
if (val == "4") {
return [
{ "label" : "Data_1", "data" : [ [ 1404438592000, 21.09 ], [ 1404438593000, 10.85 ], [ 1404438594000, 15.74 ], [ 1404438595000, 20.86 ], [ 1404438596000, 10.83 ], [ 1404438597000, 8.92 ], [ 1404438598000, 23.68 ], [ 1404438599000, 20.68 ], [ 1404438600000, 14.68 ], [ 1404438601000, 4.65 ]] },
{ "label" : "Data_2", "data" : [ [ 1404438592000, 3.219 ], [ 1404438593000, 1.641 ], [ 1404438594000, 6.68 ], [ 1404438595000, 2.543 ], [ 1404438596000, 8.522 ], [ 1404438597000, 4.616 ], [ 1404438598000, 9.703 ], [ 1404438599000, 3.737 ], [ 1404438600000, 8.752 ], [ 1404438601000, 1.791 ]]}
];
}
}
Upvotes: 1
Views: 541
Reputation: 4721
two changes
.attr("d", line(gd.data))
should be
.attr("d", function (d) { return line(d.data) })
and path first and then add axis. It should work. Basically selectAll('path') picking up path element from axis element.
Upvotes: 1
Reputation: 108567
@LarThoren method will certainly work but with d3
we like to avoid explicit looping. Your version misses two things:
canvas.selectAll(".series") //<-- don't selectAll with "path", there are other paths in the axis and you selection needs to be more specific
.data(gd)
.enter()
.append("path")
.attr("d", function(d){ //<-- gd is out of scope here, you need to use the accessor function
return line(d.data);
})
.attr("class", "series")
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("fill", "none");
Full working code:
var w = 700;
var h = 600;
var pad = 80;
var time_format = d3.time.format("%I:%M:%S");
var gd = example_data(4);
var xScale = d3.time.scale()
.domain(d3.extent(gd[0].data, function(d) { return d[0]; }))
.range([pad, w - pad]);
var yScale = d3.scale.linear()
.domain([0, d3.max(gd[0].data, function(d) { return d[1]; })*2])
.range([h - pad, pad]);
var canvas = d3.select("body")
.append("svg")
.attr("class", "chart")
.attr("width", w)
.attr("height", h);
var xaxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(time_format);
var yaxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var line = d3.svg.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); })
.interpolate("linear");
// Just for a grey background.
canvas.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#E8E8E8");
// Add x-axis.
canvas.append("g")
.attr("class", "axis")
.attr("transform","translate(0," + (h - pad) + ")")
.call(xaxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d) {
return "rotate(-65)"
});
// Add y-axis
canvas.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + pad + ", 0)")
.call(yaxis);
// Add line
canvas.selectAll(".series")
.data(gd)
.enter()
.append("path")
.attr("d", function(d){
return line(d.data);
})
.attr("class", "series")
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("fill", "none");
function example_data(val) {
if (val == "4") {
return [
{ "label" : "Data_1", "data" : [ [ 1404438592000, 21.09 ], [ 1404438593000, 10.85 ], [ 1404438594000, 15.74 ], [ 1404438595000, 20.86 ], [ 1404438596000, 10.83 ], [ 1404438597000, 8.92 ], [ 1404438598000, 23.68 ], [ 1404438599000, 20.68 ], [ 1404438600000, 14.68 ], [ 1404438601000, 4.65 ]] },
{ "label" : "Data_2", "data" : [ [ 1404438592000, 3.219 ], [ 1404438593000, 1.641 ], [ 1404438594000, 6.68 ], [ 1404438595000, 2.543 ], [ 1404438596000, 8.522 ], [ 1404438597000, 4.616 ], [ 1404438598000, 9.703 ], [ 1404438599000, 3.737 ], [ 1404438600000, 8.752 ], [ 1404438601000, 1.791 ]]}
];
}
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Upvotes: 1
Reputation: 553
I copied your jsfiddle to a stack snippet that can be viewed below. Looping through the data creating a line for each post.
for(var i = 0; i < gd.length; i++)
{
canvas.append("path")
.data([gd[i].data])
.attr("d", line).attr("class", "line" + i);
}
var w = 700;
var h = 600;
var pad = 80;
var time_format = d3.time.format("%I:%M:%S");
var gd = example_data(4);
var xScale = d3.time.scale()
.domain(d3.extent(gd[0].data, function(d) {
return d[0];
}))
.range([pad, w - pad]);
var yScale = d3.scale.linear()
.domain([0, d3.max(gd[0].data, function(d) {
return d[1];
}) * 2])
.range([h - pad, pad]);
var canvas = d3.select("body")
.append("svg")
.attr("class", "chart")
.attr("width", w)
.attr("height", h);
var xaxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickFormat(time_format);
var yaxis = d3.svg.axis()
.scale(yScale)
.orient("left");
var line = d3.svg.line()
.x(function(d) {
return xScale(d[0]);
})
.y(function(d) {
return yScale(d[1]);
})
.interpolate("linear");
// Just for a grey background.
canvas.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#E8E8E8");
// Add x-axis.
canvas.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - pad) + ")")
.call(xaxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d) {
return "rotate(-65)"
});
// Add y-axis
canvas.append("g")
.attr("class", "axis")
.attr("transform", "translate(" + pad + ", 0)")
.call(yaxis);
for (var i = 0; i < gd.length; i++) {
// Add line
canvas.append("path")
.data([gd[i].data])
.attr("d", line).attr("class", "line" + i);
}
function example_data(val) {
if (val == "4") {
return [{
"label": "Data_1",
"data": [
[1404438592000, 21.09],
[1404438593000, 10.85],
[1404438594000, 15.74],
[1404438595000, 20.86],
[1404438596000, 10.83],
[1404438597000, 8.92],
[1404438598000, 23.68],
[1404438599000, 20.68],
[1404438600000, 14.68],
[1404438601000, 4.65]
]
}, {
"label": "Data_2",
"data": [
[1404438592000, 3.219],
[1404438593000, 1.641],
[1404438594000, 6.68],
[1404438595000, 2.543],
[1404438596000, 8.522],
[1404438597000, 4.616],
[1404438598000, 9.703],
[1404438599000, 3.737],
[1404438600000, 8.752],
[1404438601000, 1.791]
]
}];
}
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.line0 {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.line1 {
fill: none;
stroke: red;
stroke-width: 1.5px;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
</head>
<body>
</body>
</html>
Upvotes: 1