Published
Edited
Apr 22, 2020
Insert cell
md`# Using Paths (Chapter 11)`
Insert cell
Insert cell
dataset = d3.csv("https://raw.githubusercontent.com/scotthmurray/d3-book/master/chapter_11/mauna_loa_co2_monthly_averages.csv", row_conv)
Insert cell
Insert cell
xScale = d3.scaleTime()
.domain(d3.extent(dataset, d => d.date))
.range([margin.left, width - margin.right]);
Insert cell
yScale = d3.scaleLinear()
.domain([d3.min(dataset, function(d) {if (d.average >= 0) return d.average}), d3.max(dataset, d => d.average)]).nice()
.range([height - margin.bottom, margin.top]);
Insert cell
xAxis = g => g
.attr("transform", `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(xScale).ticks(width/80).tickSizeOuter(0));
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left}, 0)`)
.call(d3.axisLeft(yScale).tickSizeOuter(0))
.call(g => g.select(".domain").remove());
Insert cell
Insert cell
line = d3.line()
.defined(function(d) { return d.average >= 0; })
.x(function(d) {return xScale(d.date); })
.y(function(d) {return yScale(d.average); })
Insert cell
line_chart = {

const svg = d3.select(DOM.svg(width, height));
svg.append("path")
.datum(dataset)
.attr("fill", "none")
.attr("stroke", "orange")
.attr("stroke-width", 2)
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("d", line);
//Draw 350 ppm line
svg.append("line")
.attr("fill", "none")
.attr("stroke", "red")
.attr("stroke-dasharray", 3)
.attr("stroke-width", 0.5)
.attr("x1", margin.left)
.attr("x2", width - margin.right)
.attr("y1", yScale(350))
.attr("y2", yScale(350));
//Label 350 ppm line
svg.append("text")
.attr("class", "dangerLabel")
.attr("x", margin.left + 20)
.attr("y", yScale(350) - 7)
.text("350 ppm “safe” level")
.attr("font-size", "12px")
.attr("fill", "red");
svg.append("g")
.call(xAxis);
svg.append("g")
.call(yAxis);
return svg.node();
}
Insert cell
Insert cell
area = d3.area()
.defined(function(d) { return d.average >= 0; })
.x(function(d) { return xScale(d.date); })
.y0(function() { return yScale.range()[0]; })
.y1(function(d) { return yScale(d.average); });
Insert cell
dangerArea = d3.area()
.defined(function(d) { return d.average >= 350; })
.x(function(d) { return xScale(d.date); })
.y0(function() { return yScale(350); })
.y1(function(d) { return yScale(d.average); });
Insert cell
area_chart = {

const svg = d3.select(DOM.svg(width, height));
svg.append("path")
.datum(dataset)
.attr("fill", "teal")
.attr("stroke", "none")
.attr("d", area);
svg.append("path")
.datum(dataset)
.attr("fill", "red")
.attr("stroke", "none")
.attr("d", dangerArea);
//Draw 350 ppm line
svg.append("line")
.attr("fill", "none")
.attr("stroke", "red")
.attr("stroke-dasharray", 3)
.attr("stroke-width", 0.5)
.attr("x1", margin.left)
.attr("x2", width - margin.right)
.attr("y1", yScale(350))
.attr("y2", yScale(350));
//Label 350 ppm line
svg.append("text")
.attr("class", "dangerLabel")
.attr("x", margin.left + 20)
.attr("y", yScale(350) - 7)
.text("350 ppm “safe” level")
.attr("font-size", "12px")
.attr("fill", "red");
svg.append("g")
.call(xAxis);
svg.append("g")
.call(yAxis);
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
margin = ({top: 30, right: 40, bottom: 30, left: 30})
Insert cell
row_conv = function(d) {
return {
date: new Date(+d.year, (+d.month - 1)), //Make a new Date object for each year + month
average: parseFloat(d.average) //Convert from string to float
};
}
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more