Published
Edited
Feb 2, 2021
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
linearInterpolator = interpolateCatmullRom([0, 0.5, 1])
Insert cell
d3.quantize(linearInterpolator, 11).map(d => +d.toFixed(3))
Insert cell
Insert cell
Insert cell
Insert cell
convexInterpolator = interpolateCatmullRom([0, 0.1, 0.4, 1])
Insert cell
d3.quantize(convexInterpolator, 11).map(d => +d.toFixed(3))
Insert cell
Insert cell
Insert cell
bumpyInterpolator = interpolateCatmullRom([0, 0.5, 1, 0.5, 0, 0.5, 1])
Insert cell
d3.quantize(bumpyInterpolator, 11).map(d => +d.toFixed(3))
Insert cell
Insert cell
chart([
["random", interpolateCatmullRom(Array.from({ length: 40 }, Math.random))]
])
Insert cell
Insert cell
gps = ({
type: "LineString",
coordinates:[
[-4.34440,55.84040], [-4.33269,55.83727], [-4.33019,55.83633],
[-4.32485,55.83599], [-4.31886,55.83803], [-4.31525,55.83937],
[-4.30817,55.84074], [-4.30378,55.84262], [-4.30016,55.84460]
]
})
Insert cell
Insert cell
map(gps, { type: "MultiPoint", coordinates: gps.coordinates }) // map() is defined in the Annex
Insert cell
Insert cell
spline = {
const n = 40,
location = interpolateCatmullRom(gps.coordinates);

return {
type: "LineString",
coordinates: d3.quantize(location, n)
};
}
Insert cell
map(spline, { type: "MultiPoint", coordinates: gps.coordinates })
Insert cell
Insert cell
height = 380
Insert cell
projection = d3.geoMercator().fitExtent([[20, 0], [width - 20, height]], gps)
Insert cell
function map(line, points) {
const context = DOM.context2d(width, height),
path = d3.geoPath(projection).context(context);
context.beginPath();
path(line);
context.lineWidth = 3;
context.stroke();

context.beginPath();
path(points);
context.lineWidth = 3;
context.fillStyle = "white";
context.fill();
context.stroke();
return context.canvas;
}
Insert cell
function chart(interpolators) {
const samples = 300,
w = Math.min(width, 600),
h = 250,
chart = d3
.create("svg")
.attr("width", w)
.attr("height", h),
x = d3.scaleLinear().range([w * 0.05, w * 0.875]),
y = d3.scaleLinear().range([h * 0.9, h * 0.05]),
line = d3
.line()
.x((_, i) => x(i / samples))
.y(y);

let l = 0;

for (const [name, interpolator] of interpolators) draw(interpolator, name);

chart
.append("g")
.attr("transform", `translate(0,${y(0)})`)
.call(d3.axisBottom(x))
.append("text")
.attr("transform", `translate(${x(1)}, -5)`)
.attr("fill", "black")
.attr("font-style", "italic")
.text("t");

chart
.append("g")
.attr("transform", `translate(${x(0)},0)`)
.call(d3.axisLeft(y))
.append("text")
.attr("transform", `translate(5, ${y(1) + 5})`)
.attr("text-anchor", "start")
.attr("fill", "black")
.attr("font-style", "italic")
.text("value");

return chart.node();

function draw(interpolator, name) {
chart
.append("path")
.attr("fill", "none")
.attr("stroke", color(name))
.attr("d", line(d3.quantize(interpolator, 1 + samples)));

chart
.append("text")
.style("font-family", "sans-serif")
.style("font-size", "12px")
.attr("text-anchor", "end")
.text(name)
.attr("fill", color(name))
.attr("dx", w - 1)
.attr("dy", 16 * (0.6 + l++));
}
}
Insert cell
color = d3.scaleOrdinal(d3.schemeSet1)
Insert cell
d3 = require("d3@6")
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