{
let w = 800;
let h = 500;
let svg = d3
.create("svg")
.attr("width", "100%")
.attr("viewBox", [0, 0, w, h])
.style("border", "solid 1px black");
let [xmin, xmax, ymin, ymax] = [-0.5, 13.5, -0.2, 1.4];
let pad = 20;
let x_scale = d3
.scaleLinear()
.domain([xmin, xmax])
.range([pad, w - pad]);
let y_scale = d3
.scaleLinear()
.domain([ymin, ymax])
.range([h - pad, pad]);
let path = d3
.line()
.x((d) => x_scale(d[0]))
.y((d) => y_scale(d[1]));
let n = 1000;
let lambda = d3.randomUniform(0.5, 1.5)();
let pts = d3.range(n).map(d3.randomExponential(lambda));
let bins = d3.bin().thresholds(20)(pts);
let dx = bins[1].x1 - bins[1].x0;
let normalizer = 1 / (n * dx);
let rect_group = svg
.append("g")
.attr("fill", color)
.attr("stroke", "white")
.attr("stroke-width", 3);
rect_group
.selectAll("rect")
.data(bins)
.join("rect")
.attr("x", (b) => x_scale(b.x0))
.attr("width", (b) => x_scale(b.x1) - x_scale(b.x0))
.attr("y", y_scale(0))
.attr("height", 0);
let f = (x) => lambda * Math.exp(-lambda * x);
let graph = svg
.append("path")
.attr("d", path(d3.range(xmin, xmax, 0.01).map((x) => [x, f(x)])))
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", 3);
svg
.append("g")
.attr("transform", `translate(0, ${y_scale(0)})`)
.call(
d3
.axisBottom(x_scale)
.tickValues([-3, -2, -1, 1, 2, 3])
.tickFormat(d3.format("d"))
.tickSizeOuter(0)
);
svg
.append("g")
.attr("transform", `translate(${x_scale(0)})`)
.call(d3.axisLeft(y_scale).tickValues([0.5, 1, 1.5]).tickSizeOuter(0));
let pt_group = svg.append("g").attr("fill", "black");
pt_group
.selectAll("circle")
.data(pts)
.join("circle")
.attr("cx", (pt) => x_scale(pt))
.attr("cy", y_scale(0))
.attr("r", 4)
.attr("opacity", 0);
Promises.delay(300).then(() =>
pt_group
.selectAll("circle")
.transition()
.duration(600)
.attr("opacity", 0.02)
);
Promises.delay(1300).then(function () {
rect_group
.selectAll("rect")
.transition()
.duration(500)
.attr("y", (b) => y_scale(normalizer * b.length))
.attr("height", (b) => y_scale(0) - y_scale(normalizer * b.length));
});
let length = graph.node().getTotalLength();
graph.attr("stroke-dasharray", [0, length]);
Promises.delay(1800).then(() =>
graph.transition().duration(800).attr("stroke-dasharray", [length, length])
);
return svg.node();
}