This is a example for basic line chart using D3. We are using the newest version of D3, version 4. As for all visualizations, we can break down this work into a checklist.
Read through the code below to see where each part of the checklist is completed.
forked from pstuffa's block: D3 v4 Line Chart
forked from gordlea's block: D3 v5 Line Chart
xxxxxxxxxx
<meta charset="utf-8">
<style type="text/css">
svg {
font-family: Arial;
font-size: 12px;
}
.data .dataLine {
fill: none;
stroke: black;
stroke-width: 1;
stroke-opacity: 0.2;
}
.data path.dataLine.highlight {
stroke: orange;
stroke-width: 2;
stroke-opacity: 1;
}
.data text {
fill-opacity: 0.2;
}
.data text.highlight {
fill: orange;
fill-opacity: 1;
}
.ticks text {
text-anchor: end;
}
.dotted {
stroke: black;
stroke-opacity: 0.2;
stroke-width: 1px;
stroke-dasharray: 5,5;
}
.solid {
stroke: black;
stroke-opacity: 0.7;
stroke-width: 1px;
}
.dates {
text-anchor: middle;
}
</style>
<body>
</body>
<!-- Load in the d3 library -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
const margin = {top: 50, right: 100, bottom: 50, left: 50}
, width = 600 - margin.left - margin.right // Use the window's width
, height = 400 - margin.top - margin.bottom; // Use the window's height
// The number of datapoints
const n = 6;
const xScale = d3.scaleLinear()
.domain([0, n-1]) // input
.range([0, width]); // output
const yScale = d3.scaleLinear()
.domain([0, 1]) // input
.range([height, 0]); // output
const line = d3.line()
.x((d, i) => xScale(i))
.y(d => yScale(d.y))
.curve(d3.curveMonotoneX)
const dataset = [
{ name: 'Danmark', values: d3.range(n).map(() => ({"y": d3.randomUniform(1)() }))},
{ name: 'Finland', values: d3.range(n).map(() => ({"y": d3.randomUniform(1)() }))},
{ name: 'Sverige', values: d3.range(n).map(() => ({"y": d3.randomUniform(1)() }))},
{ name: 'Norge', values: d3.range(n).map(() => ({"y": d3.randomUniform(1)() }))},
];
dataset[0].values[0].y = 0;
dataset[1].values[0].y = 0;
dataset[1].values[1].y = 0;
dataset[2].values[0].y = 0;
dataset[2].values[1].y = 0;
dataset[3].values[0].y = 0;
dataset[3].values[1].y = 0;
dataset[3].values[2].y = 0;
const svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
const dataGroup = svg.append('g').classed('data', true);
dataGroup.selectAll("path")
.data(dataset)
.join('path')
.classed('dataLine', true)
.classed('highlight', d => d.name === 'Sverige')
.attr("d", d => line(d.values));
dataGroup.selectAll(".name")
.data(dataset)
.join('text')
.classed('name', true)
.classed('highlight', d => d.name === 'Sverige')
.attr('x', xScale.range()[1] + 8)
.attr('y', d => yScale(d.values[d.values.length - 1].y))
.text(d =>
`${d.name} ${new Intl.NumberFormat('sv-SE').format(d.values[d.values.length - 1].y)}`)
/********* ticks *********/
const ticksGroup = svg.append('g').classed('ticks', true)
// bottom line
ticksGroup.append('line').classed('dotted', true)
.attr('x1', 0)
.attr('x2', xScale.range()[1])
.attr('y1', yScale.range()[0])
.attr('y2', yScale.range()[0])
ticksGroup.append("text")
.attr('x', -8)
.attr('y', yScale.range()[0])
.attr('dy', '0.33em')
.text('0')
// middle line
ticksGroup.append('line').classed('dotted', true)
.attr('x1', 0)
.attr('x2', xScale.range()[1])
.attr('y1', yScale.range()[0]/2)
.attr('y2', yScale.range()[0]/2)
ticksGroup.append("text")
.attr('x', -8)
.attr('y', yScale.range()[0]/2)
.attr('dy', '0.33em')
.text(Math.round(yScale.domain()[1]) / 2)
// top line
ticksGroup.append('line').classed('dotted', true)
.attr('x1', 0)
.attr('x2', xScale.range()[1])
.attr('y1', yScale.range()[1])
.attr('y2', yScale.range()[1])
ticksGroup.append("text")
.attr('x', -8)
.attr('y', yScale.range()[1])
.attr('dy', '0.33em')
.text(Math.round(yScale.domain()[1]))
/********* dates *********/
const datesGroup = svg.append('g').classed('dates', true)
// left line
datesGroup.append('line').classed('solid', true)
.attr('x1', 0)
.attr('x2', 0)
.attr('y1', yScale.range()[0] + 8)
.attr('y2', yScale.range()[1] - 8)
datesGroup.append("text")
.attr('x', 0)
.attr('y', yScale.range()[1] - 8)
.attr('dy', '-1em')
.text('2020-01-01')
// right line
datesGroup.append('line').classed('solid', true)
.attr('x1', xScale.range()[1])
.attr('x2', xScale.range()[1])
.attr('y1', yScale.range()[0] + 8)
.attr('y2', yScale.range()[1] - 8)
datesGroup.append("text")
.attr('x', xScale.range()[1])
.attr('y', yScale.range()[1] - 8)
.attr('dy', '-1em')
.text('Idag')
</script>
https://d3js.org/d3.v5.min.js