Published
Edited
Apr 7, 2022
1 star
Insert cell
Insert cell
//d3 = require("d3@7.4.0")
d3 = require("d3@7.4.1")
Insert cell
cars = require('@observablehq/cars')
Insert cell
Insert cell
baseHisto("Cylinders")
Insert cell
baseHisto("Year")
Insert cell
baseHisto("Miles_per_Gallon")
Insert cell
baseHisto("Displacement")
Insert cell
baseHisto("Horsepower")
Insert cell
baseHisto("Weight_in_lbs")
Insert cell
baseHisto("Acceleration")
Insert cell
// pass in the column name to create the histogram
function baseHisto(col) {
const histoWidth = width / 4;
const histoHeight = 450 / 4;
const margin = ({top: 10, right: 20, bottom: 50, left: 80})

const svg = d3.create('svg')
.attr('width', histoWidth + margin.left + margin.right)
.attr('height', histoHeight + margin.top + margin.bottom);

const g = svg.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);

// create x scale
const x = d3.scaleLinear()
.range([0, histoWidth])
.domain(d3.extent(cars, d => d[col])).nice();
// compute bins for histogram
// https://www.d3-graph-gallery.com/graph/histogram_basic.html
// https://observablehq.com/@d3/d3-bin
const histogram = d3.bin()
.value(d => d[col]) // specify the values used for the histogram
.domain(x.domain()); // domain is same as x-axis
const bins = histogram(cars);

// create y scale
const y = d3.scaleLinear()
.range([histoHeight, 0])
.domain([0, d3.max(bins, d => d.length)]).nice(); // need to know bins first
// create and add axes
const xAxis = d3.axisBottom(x);
const xAxisGroup = g.append("g")
.attr("transform", `translate(0, ${histoHeight})`);
xAxisGroup.append("text")
.attr("x", 0)
.attr("y", 33)
.attr("fill", "black")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
.text(col);
xAxisGroup.call(xAxis);
const yAxis = d3.axisLeft(y).ticks(3);
const yAxisGroup = g.append("g").call(yAxis)
// add grid lines
.call(g => g.selectAll('.tick line')
.clone()
.attr('stroke', '#d3d3d3')
.attr('x1', 0)
.attr('x2', histoWidth))

// https://observablehq.com/@ehs219/d3-histogram
let barsGroup = g.append("g");

// draw bars
barsGroup.selectAll("rect")
.data(bins)
.join("rect")
.attr("fill", "steelblue")
.attr("x", d => x(d.x0) + 1) // +1 allows for some space between the bars
.attr("width", d => x(d.x1) - x(d.x0) - 1) // -1 adds space between the bars
.attr("y", d => y(d.length))
.attr("height", d => histoHeight - y(d.length));
return svg.node();
}
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