Published
Edited
Sep 29, 2020
1 fork
Importers
Insert cell
Insert cell
chart = histogram(data, options)
Insert cell
Insert cell
data = yielding_random_sample(4000, 100)
Insert cell
options = ({
bar_color: 'darkgrey',
num_bins: 100,
chart_height: 150,
chart_width: width / 1.5,
margin: {top: 10, right: 10, bottom: 30, left: 30},
})
Insert cell
Insert cell
Insert cell
histogram = (data, options={}) => {
const {
num_bins = Math.pow(data.length, 1/3),
bar_color = 'steelblue',
chart_width = width,
chart_height = 300,
margin = {top: 20, right: 20, bottom: 30, left: 40},
} = options;
const x = d3.scaleLinear()
.domain(d3.extent(data)).nice()
.range([margin.left, chart_width - margin.right]);
const bins = d3.histogram()
.domain(x.domain())
.thresholds(num_bins)
(data);
const y = d3.scaleLinear()
.domain([0, d3.max(bins, d => d.length)]).nice()
.range([chart_height - margin.bottom, margin.top]);
const xAxis = g => g
.attr("transform", `translate(0,${chart_height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(chart_width / 80 ).tickSizeOuter(0))
.call(g => g.append("text")
.attr("x", chart_width - margin.right)
.attr("y", -4)
.attr("fill", "currentColor")
.attr("font-weight", "bold")
.attr("text-anchor", "end")
.text(data.x));
const yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).ticks(chart_height / 60))
.call(g => g.select(".domain").remove())
.call(g => g.select(".tick:last-of-type text").clone()
.attr("x", 4)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text(data.y));

const svg = d3.create("svg")
.attr("width", chart_width)
.attr("height", chart_height);
svg.append("g")
.attr("fill", bar_color)
.selectAll("rect")
.data(bins)
.join("rect")
.attr("x", d => x(d.x0))
.attr("width", d => Math.max(1, x(d.x1) - x(d.x0) - 2))
.attr("y", d => y(d.length))
.attr("height", d => y(0) - y(d.length));

svg.append("g")
.call(xAxis);
svg.append("g")
.call(yAxis);
return svg.node();
}
Insert cell
random_sample = (values=1000, extent=1) => Array(values).fill(extent).map(v => Math.random()*v);
Insert cell
function* yielding_random_sample(values=100, extent=1) {
const a = [];
for (let i = 0; i < values; ++i) {
a.push(Math.random() * extent);
yield a;
}
}
Insert cell
d3 = require("d3@6")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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