{
const width = 500;
const height = 125;
const margin = { top: 5, right: 5, bottom: 20, left: 25 };
const minX = 1971;
const maxX = 2021;
var x = d3
.scaleTime()
.domain([minX, maxX])
.rangeRound([0, width - margin.left]);
var y = d3.scaleLinear().range([height - margin.bottom, margin.top]);
const oneTickPerYear = x.ticks(maxX - minX);
var histogram = d3
.bin()
.value(d => d)
.domain(x.domain())
.thresholds(oneTickPerYear);
const bins = histogram(data);
y.domain([0, d3.max(bins, d => d.length)]);
const svg = d3.create('svg').attr('viewBox', [0, 0, width, height]);
const makeTheBarAppearInTheMiddleOfTheTick = -2.5;
const weDoNotWantTheBarToBeTheFullWidthOfTheColumn = 3;
svg
.append('g')
.selectAll('rect')
.data(bins)
.enter()
.append('rect')
.attr('class', 'bar')
.attr('x', makeTheBarAppearInTheMiddleOfTheTick)
.attr('transform', d => {
return `translate(${x(d.x0)},${y(d.length)})`;
})
.attr('width', d => {
return x(d.x1) - x(d.x0) - weDoNotWantTheBarToBeTheFullWidthOfTheColumn;
})
.attr('height', d => {
return height - margin.bottom - y(d.length);
});
const dataUniqs = d3.union(data);
const tickValuesForAxis = [...dataUniqs].map((d, i) => {
return d;
});
svg
.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(
d3
.axisBottom(x)
.tickValues(tickValuesForAxis)
.tickFormat((d, i) => {
var r = d;
if (r >= 2000) r -= 2000;
if (r > 1900) r -= 1900;
if (r < 10) r = "0" + r;
return '’' + r;
})
);
return svg.node();
}