I'm using trying to use nest and rollup to create a line chart in d3 v4 to display an average score over a number of days. I've exhausted all the tutorials and stackoverflow answers and no matter what I try, I can't seem to get the line to display.
I've attached the code below, and would be extremely grateful if anyone could help.
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%d/%m");
// append the svg object to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").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 + ")");
// Get the data
d3.csv("csv/formdata.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.scale = +d.scale;
});
var dataNest = d3.nest()
.key(function(d) {return d.date;})
.rollup (function(v) { return {
averagescale: d3.mean(v, function(d) {return d.scale; })
}; })
.entries(data)
console.log(dataNest)
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.averagescale); });
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(dataNest, function(d) { return d.averagescale; })]);
// Add the valueline path.
svg.append("path")
.data(dataNest)
.attr("class", "line")
.attr('d', function(d) { return valueline (d.averagescale); })
// Add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add the Y Axis
svg.append("g")
.call(d3.axisLeft(y));
});
csv looks as below
date,grade,scale
10/05,vs,7
10/05,vs,2
11/05,vs,3
11/05,vs,6
12/05,vs,8
12/05,vs,2
13/05,vs,3
13/05,vs,6
Problem: Since you rolled up.value will hold the averagescale
.
y.domain([0, d3.max(dataNest, function(d) { return d.averagescale; })]);
It should have been:
y.domain([0, d3.max(dataNest, function(d) { return d.value.averagescale; })]);
Subsequently the line function will also need to be changed:
var valueline = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.averagescale); });
It should be:
var valueline = d3.line()
.x(function(d) { return x(new Date(d.key)); })
.y(function(d) { return y(d.value.averagescale); });
working code here