Public
Edited
May 19, 2023
Insert cell
Insert cell
Insert cell
{
replay;
const height = 400;
const bound = d3.create("svg").attr("viewBox", [0, 0, width, height]);
yield bound.node();

const scaleX = d3.scaleLinear(
d3.extent(aapl, (d) => d.Date),
[10, width - 10]
);
const scaleY = d3.scaleLinear(
d3.extent(aapl, (d) => d.Close),
[height - 10, 10]
);

const path = bound
.append("path")
.classed("path", true)
.datum(aapl)
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", 1.5)
.attr(
"d",
d3
.line()
.x((d) => scaleX(d.Date))
.y((d) => scaleY(d.Close))
)
.transition()
.duration(8000)
.attrTween("stroke-dasharray", function () {
const length = this.getTotalLength();
return function (t) {
const interpolatedValue = d3.interpolate(0, length)(t);
return `0,${length}`, `${interpolatedValue},${length}`;
};
})
.attrTween("stroke-dashoffset", function () {
const length = this.getTotalLength();
const lengthPct = length * 0.1;
return function (t) {
const interpolatedValue = d3.interpolate(0, length)(t);
if (interpolatedValue > lengthPct) {
// Trigger the stroke-dashoffset animation
const dashOffset = length * -1;
d3.select(this)
.attr("stroke-dashoffset", dashOffset)
.transition()
.duration(8000)
.attrTween("stroke-dashoffset", function () {
return d3.interpolate(0, dashOffset);
});
}
};
});
}
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