Published
Edited
Dec 13, 2020
Insert cell
Insert cell
Insert cell
{
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);

// Get the histogram data together
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]);

// This is the actual histogram svg part.
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);
});

// Build the X axis
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;
// Format the year number
if (r >= 2000) r -= 2000;
if (r > 1900) r -= 1900;
if (r < 10) r = "0" + r;
return '’' + r;
})
);
return svg.node();
}
Insert cell
data = [
2019,
1996,
2019,
2017,
2019,
2017,
2020,
2019,
2020,
2020,
2019,
1995,
2002,
2018,
2019,
2019,
2014,
2018,
2014,
2020,
2019,
2019,
2019,
2020,
2018,
2016,
2017,
2020,
2019,
2006,
2019,
2019,
2010,
2020,
2019,
2020,
2018,
2018,
2014,
1972,
2019,
2019,
1995,
1996,
2016,
2018,
2018,
2016,
2018,
2020,
2019,
2019,
2002,
2015,
2020,
2019,
2020,
2019,
2020,
2020,
2020,
2012,
2018,
2016,
2016,
2019,
2016,
2011,
2019,
2019,
2018,
2019,
2015,
2020,
2019,
2020,
2010,
2018,
2019,
2019,
2019,
2019,
2006,
2001,
1976,
2019,
2020,
2016,
2019,
2019,
2017,
2018,
2018,
2010,
2020,
1998,
2019,
2002,
2020,
2019,
2020,
2019,
2019,
2019,
2019,
1979,
2019,
2007,
2020,
2020,
2012,
2019,
2016,
2019,
2019,
2020,
2020,
2020,
2019,
2019,
2019,
2017,
2017,
2020,
2018,
2019,
2020,
2016,
2019,
2007,
2017,
2017,
2019,
2017,
2019,
1997,
2016,
2020,
2020,
1992,
2020,
2014,
2015,
2019,
1998,
2019,
2016,
2014,
2016,
2002
]
Insert cell
d3 = require("d3@6")
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