Published
Edited
Dec 4, 2020
5 stars
Insert cell
Insert cell
viewof d = distribution()
Insert cell
d
Insert cell
function distribution({
n = 10,
d = Array.from({ length: n }, Math.random),
height = 100,
width = 600
} = {}) {
const value = d;

const x = d3
.scaleLinear()
.domain([0, n])
.range([0, width]);

const y = d3
.scaleLinear()
.domain([0, 1])
.range([height, 0])
.clamp(true);

const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("width", width);

svg
.append("line")
.attr("x1", x(0))
.attr("x2", x(n))
.attr("y1", y(0))
.attr("y2", y(0))
.attr("stroke", "#000");

const rect = svg
.selectAll("rect")
.data({ length: n })
.join("rect")
.attr("x", (_, i) => x(i))
.attr("width", width / n - 2);

function update() {
normalize(value);
rect.attr("y", (_, i) => y(value[i]));
rect.attr("height", (_, i) => Math.abs(-y(value[i]) + y(0)));
svg.node().dispatchEvent(new CustomEvent('input'));
}

update();

const drag = d3
.drag()
.subject(event => Math.floor(x.invert(event.x)))
.on("drag", event => {
value[event.subject] = y.invert(event.y);
update();
});

svg.call(drag);

return Object.assign(svg.node(), { value });

function normalize(D) {
const sum = D.reduce((a, b) => a + b),
sum1 = sum ? 1 / sum : 1;
for (let i = 0; i < D.length; i++) D[i] *= sum1;
}
}
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