Reputation: 4592
I'm trying to follow this tutorial to produce a simple line chart for my data in JSON format:
[{"Machine":"S2","Data":[{"Percentage":0,"Week":33,"Year":2014,"Monday":"11/08/14","Items":0},{"Percentage":0,"Week":34,"Year":2014,"Monday":"18/08/14","Items":0},{"Percentage":0,"Week":35,"Year":2014,"Monday":"25/08/14","Items":0},{"Percentage":0,"Week":36,"Year":2014,"Monday":"01/09/14","Items":0},{"Percentage":1.141848548192784,"Week":37,"Year":2014,"Monday":"08/09/14","Items":2},{"Percentage":58.264732011508123,"Week":38,"Year":2014,"Monday":"15/09/14","Items":4},{"Percentage":0,"Week":39,"Year":2014,"Monday":"22/09/14","Items":0}]},{"Machine":"S3","Data":[{"Percentage":0,"Week":33,"Year":2014,"Monday":"11/08/14","Items":0},{"Percentage":0,"Week":34,"Year":2014,"Monday":"18/08/14","Items":0},{"Percentage":0,"Week":35,"Year":2014,"Monday":"25/08/14","Items":0},{"Percentage":0,"Week":36,"Year":2014,"Monday":"01/09/14","Items":0},{"Percentage":7.7532100624144213,"Week":37,"Year":2014,"Monday":"08/09/14","Items":15},{"Percentage":0,"Week":38,"Year":2014,"Monday":"15/09/14","Items":0},{"Percentage":0,"Week":39,"Year":2014,"Monday":"22/09/14","Items":0}]}]
This is the code I have produced:
function CreateOeeChart(json)
{
// Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 30, left: 50},
width = 600 - margin.left - margin.right,
height = 270 - margin.top - margin.bottom;
// Parse the date / time - this is causing me problems
var parseDate = d3.time.format("%d/%m/%Y").parse;
// Set the ranges
var x = d3.time.scale().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(5);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
// Define the line
var line = d3.svg.line()
.x( function(d) { return x(d.Monday); })
.y( function(d) { return y(d.Percentage); });
// Adds the svg canvas
var svg = d3.select("#oeeChart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Modify date data
jsonString.forEach(function (d) {
d.Data.forEach(function (v) {
v.Monday = parseDate(v.Monday);
});
});
// Scale the range of the data
x.domain(d3.extent(jsonString, function (d) {
d.Data.forEach(function (v) {
return v.Monday;
});
}));
y.domain([0, 100]);
// Loop through the json object and use line function to draw the lines
jsonString.forEach( function (d) {
svg.append("path")
.attr("class", "line")
.attr("d", line(d.Data));
});
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
}
When I try to append path
jsonString.forEach( function (d) {
svg.append("path")
.attr("class", "line")
.attr("d", line(d.Data));
I get the "Invalid value for path attribute..." error. Why is that?
Upvotes: 1
Views: 249
Reputation: 109232
With a nested structure like this, you can't use d3.extent
directly to determine the domain. You have to get the min and max for each individual nested array and then the overall min and max:
var min = d3.min(jsonString, function (d) {
return d3.min(d.Data, function (v) {
return v.Monday;
});
});
var max = d3.max(jsonString, function (d) {
return d3.max(d.Data, function (v) {
return v.Monday;
});
});
x.domain([min, max]);
Complete demo here. Alternatively, you could squash the array of arrays of dates into a single-level array and then get the extent from that.
Upvotes: 2