Skip to content

Instantly share code, notes, and snippets.

@sabrinamochi
Last active July 10, 2019 05:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sabrinamochi/f10e6bf76a39281f9c38a80b78ba0f2e to your computer and use it in GitHub Desktop.
Save sabrinamochi/f10e6bf76a39281f9c38a80b78ba0f2e to your computer and use it in GitHub Desktop.
CO2 Line Chart
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
#dangerNotice {
position: absolute;
top: 250px;
left: 75px;
}
#dangerNotice p {
font-size: 12px;
color: red;
font-family: Arial, Helvetica, sans-serif;
opacity: 0.8;
}
.focus-text {
color: gray;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
opacity: 0;
}
.circle {
stroke-width: 2px;
stroke-opacity: 0;
}
.safeLevel {
stroke: red;
stroke-dasharray: 2, 3;
stroke-width: :1;
opacity: 0.8;
}
.danger-line {
stroke: red;
fill: none;
stroke-width: 2px;
}
.line {
stroke: teal;
fill: none;
stroke-width: 2px;
}
.source {
position: absolute;
top: 450px;
left: 65px;
font-size: 10px;
}
.title,
.subtitle {
position: relative;
left: 55px;
}
</style>
<title>CO2 line chart</title>
<script type="text/javascript" src='https://d3js.org/d3.v5.min.js'></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1 class='title'>Monthly Average Values of CO<sub>2</sub> (ppm) </h1>
<p class='subtitle'>measured at the Mauna Loa Observatory in Hawaii</p>
<p class='source'>(source: https://bit.ly/2JKNRhB)</p>
<div id='dangerNotice' class='hidden'>
<p>Over 350 ppm</p>
</div>
<script type="text/javascript">
var w = 1000;
var h = 350;
var padding = 30;
var rowConverter = function(d) {
return {
date: new Date(+d.year, (+d.month - 1)),
average: parseFloat(d.average)
};
};
//declare a variable 'dataset' globally
d3.csv('https://raw.githubusercontent.com/alignedleft/d3-book/master/chapter_11/mauna_loa_co2_monthly_averages.csv', rowConverter).then(function(data) {
dataset = data;
console.table(dataset, ['date', 'average']);
xScale = d3.scaleTime()
.domain([
d3.min(dataset, function(d) {
return d.date;
}),
d3.max(dataset, function(d) {
return d.date;
})
])
.range([padding * 2, w - padding * 2]);
yScale = d3.scaleLinear()
.domain([300, d3.max(dataset, function(d) {
return d.average;
})])
.range([h - padding * 2, padding]);
xAxis = d3.axisBottom()
.scale(xScale)
.ticks(10);
yAxis = d3.axisLeft()
.scale(yScale)
.ticks(10)
// define a line generator
var line = d3.line()
.defined(function(d) {
return d.average >= 0 && d.average <= 350;
})
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.average);
});
var dangerLine = d3.line()
.defined(function(d) {
return d.average >= 350;
})
.x(function(d) {
return xScale(d.date);
})
.y(function(d) {
return yScale(d.average);
});
var 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);
})
var dangerArea = d3.area()
.defined(function(d) {
return d.average >= 350;
})
.x(function(d) {
return xScale(d.date);
})
.y0(function(d) {
return yScale(350);
})
.y1(function(d) {
return yScale(d.average);
})
var bisect = d3.bisector(function(d) {
return d.date
}).left;
var svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h);
svg.append('path')
.datum(dataset)
.attr('class', 'line')
.attr('d', line);
svg.append('path')
.datum(dataset)
.attr('class', 'danger-line')
.attr('d', dangerLine);
svg.append('rect')
.attr('fill', 'none')
.attr('width', w)
.attr('height', h)
.style('pointer-events', 'all')
.on('mouseover', mouseover)
.on('mousemove', mousemove);
svg.append('line')
.attr('class', 'safeLevel')
.attr('x1', padding * 2)
.attr('y1', yScale(350))
.attr('x2', w - padding * 2)
.attr('y2', yScale(350));
svg.append('g')
.attr('class', 'xaxis')
.attr('transform', 'translate(0,' + (h - padding * 2) + ')')
.call(xAxis);
svg.append('g')
.attr('class', 'yaxis')
.attr('transform', 'translate(' + padding * 2 + ', 0 )')
.call(yAxis);
var focus = svg.append('circle')
.attr('class', 'circle')
.attr('r', 3)
var focusText = svg.append('text')
.attr('class', 'focus-text')
function mouseover() {
focus.style('stroke-opacity', 1);
focusText.style('opacity', 1);
}
function mousemove() {
var x0 = xScale.invert(d3.mouse(this)[0]);
var i = bisect(dataset, x0, 1);
var selectedData = dataset[i];
focus.attr('stroke', function() {
if (+selectedData.average >= 350) {
return 'red';
} else {
return 'teal';
}
})
.attr('fill', function() {
if (+selectedData.average >= 350) {
return 'red';
} else {
return 'teal';
}
})
.attr('cx', xScale(selectedData.date))
.attr('cy', yScale(selectedData.average));
focusText.attr('x', xScale(selectedData.date))
.attr('y', yScale(selectedData.average) + 30)
.text(selectedData.average);
};
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment