Commit b34bf9c4 authored by Rodrigo Tapia-McClung's avatar Rodrigo Tapia-McClung

Update to arrow functions

parent 9bd35625
......@@ -101,10 +101,11 @@ const summarizeData = (allData, indicator) => {
.rollup( v => { return indicator == "costa" || indicator == "df" ? d3.mean(v, v => v.value) : d3.sum(v, v => v.value) })
.entries(data2)
// map "key" and "value" from d3.nest().rollup() to date and value
.map( group => { return {
date: new Date(group.key),
value: group.value
}
.map( group => {
return {
date: new Date(group.key),
value: group.value
}
})
});
// order data[i].values.date
......@@ -112,7 +113,7 @@ const summarizeData = (allData, indicator) => {
return data;
}
function makeIndicatorGraph() {
const makeIndicatorGraph = () => {
let data = [],
width = 450,
......@@ -141,7 +142,7 @@ function makeIndicatorGraph() {
legendContainer = "legendZone",
updateData;
function chart(selection) {
const chart = selection => {
// get data ranges using values from displayName
minDate = d3.min(data[0].values, d => {
return d[displayName];
......@@ -152,7 +153,7 @@ function makeIndicatorGraph() {
});
maxDate = d3.timeDay.offset(maxDate, 15) // get next month to get correct x-axis alignment
selection.each(function () {
selection.each( () => {
// add graph svg to selected container on webpage
let areaSVG = selection
......@@ -233,28 +234,178 @@ function makeIndicatorGraph() {
//console.log("data: ", data.map(d => d.values));
let maxDomain = d3.max(data.map(d => d.values).flat().map(d => d.value));
yLine.domain([0, maxDomain]).nice();
//yLine.domain([0, d3.max(data[0].values, d => d.value)]).nice();
// add axes
let xaxis = g.select(".x.axis");
xaxis.call(
d3.axisBottom(xLine)
// .ticks(d3.timeMonth.every(1))
// .tickFormat(d3.timeFormat("%b '%y"))
)
.selectAll("text")
//.attr("y", 0)
//.attr("x", 9)
.attr("y", 15)
.attr("x", 0)
.attr("dy", ".35em")
.attr("font-size", "12px")
//.attr("transform", "rotate(90)")
//.style("text-anchor", "start");
.style("text-anchor", "middle")
.style("fill", "#b2b2b2");
// format x-axis lines for minor and major ticks
//TODO: check this line to separate years starting in Jan. Maybe it is not needed
xaxis.selectAll("g.tick line")
.attr("y2", d => { // d is the tick value
if (d3.timeFormat("%m")(d) == "01") //if it is Jan
return -height - 6;
else
return 6;
})
.attr("transform", d => { // d is the tick value
if (d3.timeFormat("%m")(d) == "01") //if it is Jan
return "translate(0,6)";
})
.attr("class", d => { // d is the tick value
if (d3.timeFormat("%m")(d) == "01") //if it is Jan
return "yearTick";
});
let yaxis = g.select(".y.axis");
yaxis.transition()
.duration(500)
.call(d3.axisLeft(yLine)
/*.tickFormat(d3.format(".2s"))*/
);
// color axis labels
g.selectAll(".y.axis g.tick text")
.style("fill", "#b2b2b2"); // function (d,i) {return (i%2)?"red":"blue";})
let title = selection.select(".title.label");
title.text(chart.title())
.style("fill", "#b2b2b2");
selection.select(".title.label")
.append("tspan")
.attr("class", "far")
.html(" \uf059")
//.style("color", "#b2b2b2")
.style("cursor", "pointer")
.on("click", () => { // when clicking ? display modal with information about indicator
$("#explainIndicatorModal").on("show.bs.modal", () => {
let indicatorName = indicatorsNames[indicators.indexOf(id)]
$("#explainIndicatorModal").find("#explainIndicatorModalTitle").text(indicatorName);
$("#explainIndicatorModal").find(".modal-body").html(indicatorVars[id].explanation);
});
$("#explainIndicatorModal").modal();
});
// update chart
updateData = () => {
let time = map.timeDimension.getCurrentTime();
// update data ranges using values from displayName and lineVariables
minDate = d3.min(data[0].values, d => {
return d[displayName];
});
minDate = d3.timeDay.offset(minDate, -15) // get previous month to get correct x-axis alignment
maxDate = d3.max(data[0].values, d => {
return d[displayName];
});
maxDate = d3.timeDay.offset(maxDate, 15) // get next month to get correct x-axis alignment
// update axes' domain
xLine.domain([minDate, maxDate])
//.nice()
//.nice(d3.timeMonth)
.range([0, width - margin.left - margin.right - 30])
.clamp(true);
//yLine.domain(d3.extent(data, function(d) { return d[lineVariables[0]]; }))
//yLine.domain([0, d3.max(data, function(d) { return d[lineVariables[0]]; })]).nice()
// Calculate min and max values of data to define chart y-axis domain
//let minDomain = d3.min(data.map(d => d.values).flat().map(d => d.value));
let maxDomain = d3.max(data.map(d => d.values).flat().map(d => d.value));
yLine.domain([0, maxDomain]).nice();
//yLine.domain([0, d3.max(data[0].values, d => d.value)]).nice();
yLine.domain([0, maxDomain])
//yLine.domain([0, d3.max(data[0].values, d => d.value)]).nice()
.range([height - margin.left - margin.right, 0 + 35])
.nice();
// filter data to only use the ones needed for current time
let filteredData = [];
data.forEach((d, i) => {
filteredData.push({
name: d.name,
values: []
});
d.values.filter(v => {
if (v.date <= new Date(time)) {
filteredData[i].values.push(v);
}
});
});
// update axes
let g = selection.select(".lineChart");
// add axes
// update axis line with no ticks
let xaxis = g.select(".x.axis");
xaxis.call(
xaxis.transition()
.duration(500)
.call(
d3.axisBottom(xLine)
// .ticks(d3.timeMonth.every(1))
// .tickFormat(d3.timeFormat("%b '%y"))
.ticks(0)
.tickSize(0)
);
// update axis ticks - one for each month
let xaxisTicks = g.select(".x.axis-ticks");
let monthsInGraph = [];
userDates.forEach(d => {
monthsInGraph.push(new Date(d));
});
xaxisTicks.transition()
.duration(500)
.call(
d3.axisBottom(xLine)
.tickValues(monthsInGraph)
.tickFormat("")
);
// update axis month labels depending on how many months there are
let xaxisLabels = g.select(".x.axis-month-labels");
// FIXME: check how this displays ticks when there are many months/years
// this fix gives up to 10 ticks
// maybe need to set up more conditions
let numberOfTicks = monthsInGraph.length < 6 ? d3.timeMonth.every(1) : 6;
xaxisLabels.transition().duration(500)
.call(
d3.axisBottom(xLine)
.ticks(numberOfTicks)
.tickFormat(d3.timeFormat("%b"))
)
.selectAll("text")
//.attr("y", 0)
//.attr("x", 9)
.attr("y", 15)
.attr("x", 0)
.attr("dy", ".35em")
.attr("font-size", "12px")
//.attr("transform", "rotate(90)")
//.style("text-anchor", "start");
.style("text-anchor", "middle")
.style("fill", "#b2b2b2");
.style("fill", "#b2b2b2")
.attr("font-size", "12px");
// update axis year labels depending on how many months there are
let xaxisYearLabels = g.select(".x.axis-year-labels");
xaxisYearLabels.transition().duration(500)
.call(
d3.axisBottom(xLine)
.ticks(numberOfTicks)
.tickFormat(d3.timeFormat("'%y"))
)
.selectAll("text")
.style("fill", "#b2b2b2")
.attr("font-size", "12px");
// format x-axis lines for minor and major ticks
//TODO: check this line to separate years starting in Jan. Maybe it is not needed
......@@ -278,248 +429,95 @@ function makeIndicatorGraph() {
yaxis.transition()
.duration(500)
.call(d3.axisLeft(yLine)
/*.tickFormat(d3.format(".2s"))*/
);
.tickFormat(yAxisFormat));
// color axis labels
g.selectAll(".y.axis g.tick text")
.style("fill", "#b2b2b2"); // function (d,i) {return (i%2)?"red":"blue";})
let title = selection.select(".title.label");
title.text(chart.title())
.style("fill", "#b2b2b2");
selection.select(".title.label")
.append("tspan")
.attr("class", "far")
.html(" \uf059")
//.style("color", "#b2b2b2")
.style("cursor", "pointer")
.on("click", () => { // when clicking ? display modal with information about indicator
$("#explainIndicatorModal").on("show.bs.modal", () => {
let indicatorName = indicatorsNames[indicators.indexOf(id)]
$("#explainIndicatorModal").find("#explainIndicatorModalTitle").text(indicatorName);
$("#explainIndicatorModal").find(".modal-body").html(indicatorVars[id].explanation);
});
$("#explainIndicatorModal").modal();
});
//});
// update chart
updateData = function () {
let time = map.timeDimension.getCurrentTime();
// update data ranges using values from displayName and lineVariables
minDate = d3.min(data[0].values, d => {
return d[displayName];
});
minDate = d3.timeDay.offset(minDate, -15) // get previous month to get correct x-axis alignment
maxDate = d3.max(data[0].values, d => {
return d[displayName];
});
maxDate = d3.timeDay.offset(maxDate, 15) // get next month to get correct x-axis alignment
// update axes' domain
xLine.domain([minDate, maxDate])
//.nice()
//.nice(d3.timeMonth)
.range([0, width - margin.left - margin.right - 30])
.clamp(true);
//yLine.domain(d3.extent(data, function(d) { return d[lineVariables[0]]; }))
//yLine.domain([0, d3.max(data, function(d) { return d[lineVariables[0]]; })]).nice()
// Calculate min and max values of data to define chart y-axis domain
//let minDomain = d3.min(data.map(d => d.values).flat().map(d => d.value));
let maxDomain = d3.max(data.map(d => d.values).flat().map(d => d.value));
yLine.domain([0, maxDomain])
//yLine.domain([0, d3.max(data[0].values, d => d.value)]).nice()
.range([height - margin.left - margin.right, 0 + 35])
.nice();
// filter data to only use the ones needed for current time
let filteredData = [];
data.forEach((d, i) => {
filteredData.push({
name: d.name,
values: []
});
d.values.filter(v => {
if (v.date <= new Date(time)) {
filteredData[i].values.push(v);
}
});
// define line
let line = d3.line()
.defined(d => d)
.curve(d3.curveMonotoneX)
.x(d => xLine(d.date))
.y(d => yLine(d.value));
// get lines
let lines = g.select(".lines");
lines.selectAll("path.line")
.data(filteredData)
.join("path") // handle enter, update, and exit automagically
.attr("stroke", (d, i) => {
return i == 0 ? defaultLineColor : lineColors(i - 1);
})
// update axes
let g = selection.select(".lineChart");
// update axis line with no ticks
let xaxis = g.select(".x.axis");
xaxis.transition()
.duration(500)
.call(
d3.axisBottom(xLine)
.ticks(0)
.tickSize(0)
);
// update axis ticks - one for each month
let xaxisTicks = g.select(".x.axis-ticks");
let monthsInGraph = [];
userDates.forEach(d => {
monthsInGraph.push(new Date(d));
});
xaxisTicks.transition()
.duration(500)
.call(
d3.axisBottom(xLine)
.tickValues(monthsInGraph)
.tickFormat("")
);
// update axis month labels depending on how many months there are
let xaxisLabels = g.select(".x.axis-month-labels");
// FIXME: check how this displays ticks when there are many months/years
// this fix gives up to 10 ticks
// maybe need to set up more conditions
let numberOfTicks = monthsInGraph.length < 6 ? d3.timeMonth.every(1) : 6;
xaxisLabels.transition().duration(500)
.call(
d3.axisBottom(xLine)
.ticks(numberOfTicks)
.tickFormat(d3.timeFormat("%b"))
)
.selectAll("text")
.style("fill", "#b2b2b2")
.attr("font-size", "12px");
// update axis year labels depending on how many months there are
let xaxisYearLabels = g.select(".x.axis-year-labels");
xaxisYearLabels.transition().duration(500)
.call(
d3.axisBottom(xLine)
.ticks(numberOfTicks)
.tickFormat(d3.timeFormat("'%y"))
)
.selectAll("text")
.style("fill", "#b2b2b2")
.attr("font-size", "12px");
// format x-axis lines for minor and major ticks
//TODO: check this line to separate years starting in Jan. Maybe it is not needed
xaxis.selectAll("g.tick line")
.attr("y2", d => { // d is the tick value
if (d3.timeFormat("%m")(d) == "01") //if it is Jan
return -height - 6;
else
return 6;
})
.attr("transform", d => { // d is the tick value
if (d3.timeFormat("%m")(d) == "01") //if it is Jan
return "translate(0,6)";
.attr("class", "line")
.attr("fill", "none")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", d => line(d.values))
// get circles
let circles = g.select(".circles"),
tooltip = d3.select(".tooltip");
//tooltipFormat = d3.timeFormat("%b "%y"),
//tooltipFormat = d3.format(",.2f")
//tooltipFormat = d3.format(",.3s");
circles.selectAll("g") // using nested data, so need to make a g to contain stuff
.data(filteredData)
.join( // handle enter, update, and exit separately for overall g circle containers
enter => enter
.append("g")
.attr("class", d => d.name)
.attr("stroke", (d, i) => {
return i == 0 ? defaultPointColor : pointColors(i - 1);
})
.attr("class", d => { // d is the tick value
if (d3.timeFormat("%m")(d) == "01") //if it is Jan
return "yearTick";
});
let yaxis = g.select(".y.axis");
yaxis.transition()
.duration(500)
.call(d3.axisLeft(yLine)
.tickFormat(yAxisFormat));
// color axis labels
g.selectAll(".y.axis g.tick text")
.style("fill", "#b2b2b2");
// define line
let line = d3.line()
.defined(d => d)
.curve(d3.curveMonotoneX)
.x(d => xLine(d.date))
.y(d => yLine(d.value));
// get lines
let lines = g.select(".lines");
lines.selectAll("path.line")
.data(filteredData)
.join("path") // handle enter, update, and exit automagically
.attr("fill", (d, i) => {
return i == 0 ? defaultPointColor : pointColors(i - 1);
}),
update => update
.attr("class", d => d.name)
.attr("stroke", (d, i) => {
return i == 0 ? defaultLineColor : lineColors(i - 1);
return i == 0 ? defaultPointColor : pointColors(i - 1);
})
.attr("class", "line")
.attr("fill", "none")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", d => line(d.values))
// get circles
let circles = g.select(".circles"),
tooltip = d3.select(".tooltip");
//tooltipFormat = d3.timeFormat("%b "%y"),
//tooltipFormat = d3.format(",.2f")
//tooltipFormat = d3.format(",.3s");
circles.selectAll("g") // using nested data, so need to make a g to contain stuff
.data(filteredData)
.join( // handle enter, update, and exit separately for overall g circle containers
enter => enter
.append("g")
.attr("class", d => d.name)
.attr("stroke", (d, i) => {
return i == 0 ? defaultPointColor : pointColors(i - 1);
})
.attr("fill", (d, i) => {
return i == 0 ? defaultPointColor : pointColors(i - 1);
}),
update => update
.attr("class", d => d.name)
.attr("stroke", (d, i) => {
return i == 0 ? defaultPointColor : pointColors(i - 1);
})
.attr("fill", (d, i) => {
return i == 0 ? defaultPointColor : pointColors(i - 1);
}),
exit => exit.remove()
)
// nested join
.selectAll("circle").data(d => d.values) // access internal values array for circles here
.join( // handle enter, update, and exit separately for circles
enter => enter
.append("circle")
.attr("class", "circle")
.attr("r", 2.5)
.attr("cx", d => xLine(d.date))
.attr("cy", d => yLine(d.value))
.on("mouseover", d => {
tooltip.html(`${tooltipFormat(d.value)} ${tooltipUnits}`);
let tpWidth = tooltip.node().offsetWidth; // to center tooltip
tooltip.style("left", `${d3.event.pageX - tpWidth / 2}px`)
.style("top", `${d3.event.pageY - 23}px`)
.style("font-family", "Consolas, courier")
.style("font-size", "10pt")
.transition()
.duration(200)
.style("opacity", .9);
})
.on("mouseout", () => {
tooltip.transition()
.duration(500)
.style("opacity", 0);
}),
update => update
.attr("cx", d => xLine(d.date))
.attr("cy", d => yLine(d.value)),
exit => exit.remove()
);
}
});
//});
.attr("fill", (d, i) => {
return i == 0 ? defaultPointColor : pointColors(i - 1);
}),
exit => exit.remove()
)
// nested join
.selectAll("circle").data(d => d.values) // access internal values array for circles here
.join( // handle enter, update, and exit separately for circles
enter => enter
.append("circle")
.attr("class", "circle")
.attr("r", 2.5)
.attr("cx", d => xLine(d.date))
.attr("cy", d => yLine(d.value))
.on("mouseover", d => {
tooltip.html(`${tooltipFormat(d.value)} ${tooltipUnits}`);
let tpWidth = tooltip.node().offsetWidth; // to center tooltip
tooltip.style("left", `${d3.event.pageX - tpWidth / 2}px`)
.style("top", `${d3.event.pageY - 23}px`)
.style("font-family", "Consolas, courier")
.style("font-size", "10pt")
.transition()
.duration(200)
.style("opacity", .9);
})
.on("mouseout", () => {
tooltip.transition()
.duration(500)
.style("opacity", 0);
}),
update => update
.attr("cx", d => xLine(d.date))
.attr("cy", d => yLine(d.value)),
exit => exit.remove()
);
}
});
}
chart.width = function(value) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment