d3:slope-chart
by Richard Hunter
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<div id="chart"></div>
<a href="https://observablehq.com/@d3/slope-chart/3">source</a>
JavaScript
const data = [{
"1970": 46.9,
"1979": 57.4,
"country": "Sweden"
}, {
"1970": 44,
"1979": 55.8,
"country": "Netherlands"
}, {
"1970": 43.5,
"1979": 52.2,
"country": "Norway"
}, {
"1970": 40.7,
"1979": 39,
"country": "Britain"
}, {
"1970": 39,
"1979": 43.4,
"country": "France"
}, {
"1970": 37.5,
"1979": 42.9,
"country": "Germany"
}, {
"1970": 35.2,
"1979": 43.2,
"country": "Belgium"
}, {
"1970": 35.2,
"1979": 35.8,
"country": "Canada"
}, {
"1970": 34.9,
"1979": 38.2,
"country": "Finland"
}, {
"1970": 30.4,
"1979": 35.7,
"country": "Italy"
}, {
"1970": 30.3,
"1979": 32.5,
"country": "United States"
}, {
"1970": 26.8,
"1979": 30.6,
"country": "Greece"
}, {
"1970": 26.5,
"1979": 33.2,
"country": "Switzerland"
}, {
"1970": 22.5,
"1979": 27.1,
"country": "Spain"
}, {
"1970": 20.7,
"1979": 26.6,
"country": "Japan"
}]
// Specify the chart’s dimensions.
const width = 928;
const height = 600;
const marginTop = 40;
const marginRight = 50;
const marginBottom = 10;
const marginLeft = 50;
const padding = 3;
// Prepare the positional scales.
const x = d3.scalePoint()
.domain([0, 1])
.range([marginLeft, width - marginRight])
.padding(0.5);
const y = d3.scaleLinear()
.domain(d3.extent(data.flatMap(d => [d[1970], d[1979]])))
.range([height - marginBottom, marginTop]);
const line = d3.line()
.x((d, i) => {
return x(i)
})
.y(y);
const formatNumber = y.tickFormat(100);
// Create the container SVG.
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto; font: 10px sans-serif;");
// Append the x axis.
svg.append("g")
.attr("text-anchor", "middle")
.selectAll("g")
.data([0, 1])
.join("g")
.attr("transform", (i) => `translate(${x(i)},20)`)
.call(g => g.append("text").text((i) => i ? 1979 : 1970))
.call(g => g.append("line").attr("y1", 3).attr("y2", 9).attr("stroke", "currentColor"));
// Create a...