function timeSeries() { let xScale, yScale; function chart(selection) { selection.each(function(data) { d3.select(this).append("text").attr("transform", function(d) { return "translate(" + width / 2 + "," + 20 + ")"; }) .text("Cumulative Net Flux of Carbon to the Atmosphere from Land-Use: 1850-2005") .style("fill", "black") .style("font-weight", "bold") .style("font-size", "18px") .style("text-anchor", "middle"); d3.select(this).append("g").attr("transform", function(d) { return "translate(0," + (height - margin.bottom) + ")"; }) .attr("class", "x-axis") .call(d3.axisBottom(xScale).tickFormat(d3.timeFormat("%Y")).ticks(20)) .append("text") .attr("transform", function(d) { return "translate(" + width / 2 + "," + 40 + ")"; }) .text("Year") .style("fill", "black") .style("text-anchor", "middle") .style("font-size", "15px"); d3.select(this).append("g").attr("transform", function(d) { return "translate(" + margin.left + ",0)"; }) .attr("class", "y-axis") .call(d3.axisLeft(yScale)) .append("text") .attr("transform", function(d) { return "translate(" + margin.left + "," + 40 + ")"; }) .text("Flux (Tg C)") .style("fill", "black") .style("text-anchor", "middle") .style("font-size", "15px"); let globalg = d3.select(this).append('g').attr('id', 'globalg') let canadag = d3.select(this).append('g').attr('id', 'canadag'); let chinag = d3.select(this).append('g').attr('id', 'chinag'); let europeg = d3.select(this).append('g').attr('id', 'europeg'); let ussrg = d3.select(this).append('g').attr('id', 'ussrg'); let nafricaMeastg = d3.select(this).append('g').attr('id', 'nafricaMeastg'); let pacdevregg = d3.select(this).append('g').attr('id', 'pacdevregg'); let scamericag = d3.select(this).append('g').attr('id', 'scamericag'); let sseasiag = d3.select(this).append('g').attr('id', 'sseasiag'); let tropafricag = d3.select(this).append('g').attr('id', 'tropafricag'); let usag = d3.select(this).append('g').attr('id', 'usag'); drawpath(globalg, 'cumGlobal', undefined, 'global'); d3.select(this).on("click", function(d) { if (globalMode) { globalMode = false; let max = d3.max(data, function(d) { return [d['cumCanada'], d['cumChina'], d['cumEurope'], d['cumFrmrUSSR'], d['cumNafricaMeast'], d['cumPacDevReg'], d['cumSCAmerica'], d['cumSSEAsia'], d['cumTropAfrica'], d['cumUSA'] ].reduce(function(a, b) { return Math.max(a, b); }); }); let min = d3.min(data, function(d) { return [d['cumCanada'], d['cumChina'], d['cumEurope'], d['cumFrmrUSSR'], d['cumNafricaMeast'], d['cumPacDevReg'], d['cumSCAmerica'], d['cumSSEAsia'], d['cumTropAfrica'], d['cumUSA'] ].reduce(function(a, b) { return Math.min(a, b); }); }); localYScale = [min, max]; yScale.domain(localYScale); d3.select('.y-axis').transition().call(d3.axisLeft(yScale)); d3.selectAll('.global').remove(); updatepath(canadag, 'cumCanada', 'Canada', 'canada'); updatepath(chinag, 'cumChina', 'China', 'china') updatepath(europeg, 'cumEurope', 'Europe', 'europe'); updatepath(ussrg, 'cumFrmrUSSR', 'Former USSR', 'ussr'); updatepath(nafricaMeastg, 'cumNafricaMeast', 'North Africa and Middle East', 'nafrica'); updatepath(pacdevregg, 'cumPacDevReg', 'Pacific Dev. Region', 'pac'); updatepath(scamericag, 'cumSCAmerica', 'South and Central America', 'scamerica'); updatepath(sseasiag, 'cumSSEAsia', 'South and Southeast Asia', 'sseasia'); updatepath(tropafricag, 'cumTropAfrica', 'Tropical Africa', 'tropafrica'); updatepath(usag, 'cumUSA', 'USA', 'usa'); } else { globalMode = true; yScale.domain(globalYScale); d3.select('.y-axis').transition().call(d3.axisLeft(yScale)); updatepath(globalg, 'cumGlobal', undefined, 'global'); d3.selectAll('.canada').remove(); d3.selectAll('.china').remove(); d3.selectAll('.europe').remove(); d3.selectAll('.ussr').remove(); d3.selectAll('.nafrica').remove(); d3.selectAll('.pac').remove(); d3.selectAll('.scamerica').remove(); d3.selectAll('.sseasia').remove(); d3.selectAll('.tropafrica').remove(); d3.selectAll('.usa').remove(); } }); function drawpath(g, reg, regColor, pathclass) { let color = (regColor === undefined) ? 'black' : regionScale(regColor); let path = g.append("path") .data([data]) .attr("class", pathclass) .attr("d", d3.line().x(function(d) { return xScale(d.Year) }).y(function(d) { return yScale(d[reg]); })) .style("fill", "transparent") .style("stroke", color) .style("stroke-width", 2) .attr('stroke-dasharray', function() { return this.getTotalLength() }) .attr("stroke-dashoffset", function() { return this.getTotalLength() }); g.selectAll('circle') .data(data) .enter() .append('circle') .attr('cx', function(d) { return xScale(d.Year); }) .attr('cy', function(d) { return yScale(d[reg]); }) .attr("r", 5) .style("stroke", "transparent") .style("fill", "transparent") .on("mouseover", function(d) { d3.select(this).transition().style("fill", "black"); let m = d3.mouse(d3.select('body').node()); tooltip.style('left', m[0] + 'px').style('top', m[1] + 'px'); d3.select("#tooltip_label").html(d3.timeFormat('%Y')(d.Year) + ': ' + f(d[reg])); tooltip.transition().style("display", null); }) .on("mouseout", function(d) { d3.select(this).transition().style("fill", "transparent"); tooltip.transition().style("display", "none"); }); path.transition() .duration(6000) .attr('stroke-dashoffset', 0) .on('end', function() { let text = (regColor == undefined) ? "Global" : regColor; let label = g.append("text").text(text + ": " + f(data[data.length - 1][reg])).attr("class", pathclass) .attr("x", function(d, i) { return xScale(data[data.length - 1].Year); }) .attr("y", function(d, i) { return yScale(data[data.length - 1][reg]) }) .attr("fill", "black") label.attr('dx', "5").attr('dy', function() { if (regColor === "Europe") return -5 else if (regColor === 'North Africa and Middle East') return 12 else if (regColor === "Canada") return 12 else if (regColor === "Pacific Dev. Region") return 0 else return 10 }); }); } function updatepath(g, reg, regColor, pathclass) { d3.select('.' + pathclass).remove(); g.selectAll('circle').remove(); drawpath(g, reg, regColor, pathclass); } }); } chart.xScale = function(_) { if (!arguments.length) return xScale; xScale = _; return chart; } chart.yScale = function(_) { if (!arguments.length) return yScale; yScale = _; return chart; } return chart; }