Public
Edited
Oct 25, 2022
Insert cell
Insert cell
Insert cell
Insert cell
tileImg = fetchImage(
`https://a.tiles.mapbox.com/v4/mapbox.terrain-rgb/${location}.png?access_token=${mapboxToken}`
)
Insert cell
tileIm2g = {
const img = fetchImage(
`https://a.tiles.mapbox.com/v4/mapbox.terrain-rgb/11/1707/843.png?access_token=${mapboxToken}`
);
console.log(img);
return img;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof maxError = html`<input type=range value=10 min=5 max=200 step=0.1 style="width: 100%; max-width: 640px">`
Insert cell
Insert cell
Insert cell
renderer.domElement
Insert cell
{
const size = Math.min(width, 640);
const ratio = size / tileSize;
const ctx = DOM.context2d(size, size, 2);

ctx.fillStyle = "white";
ctx.fillRect(0, 0, tileSize, tileSize);

ctx.globalAlpha = 0.4;
ctx.drawImage(terrainViz, 0, 0, size, size);
ctx.globalAlpha = 1;

ctx.lineWidth = 0.5;
ctx.beginPath();

function split(ax, ay, bx, by, cx, cy) {
const mx = (ax + bx) >> 1;
const my = (ay + by) >> 1;

if (
Math.abs(ax - cx) + Math.abs(ay - cy) > 1 &&
errors[my * (tileSize + 1) + mx] > maxError
) {
ctx.moveTo(mx * ratio, my * ratio);
ctx.lineTo(cx * ratio, cy * ratio);
split(cx, cy, ax, ay, mx, my);
split(bx, by, cx, cy, mx, my);
}
}

ctx.moveTo(0, 0);
ctx.lineTo(ratio * tileSize, ratio * tileSize);

split(0, 0, tileSize, tileSize, tileSize, 0);
split(tileSize, tileSize, 0, 0, 0, tileSize);
ctx.stroke();
return ctx.canvas;
}
Insert cell
viewof replay = html`<button>Replay animation</button>`
Insert cell
{
replay;
await visibility();
const size = Math.min(width, 512);
const ratio = size / tileSize;
const ctx = DOM.context2d(size, size, 2);

ctx.fillStyle = "white";
ctx.fillRect(0, 0, size, size);

ctx.globalAlpha = 0.5;
ctx.drawImage(terrainViz, 0, 0, size, size);
ctx.globalAlpha = 1;

function drawLine(ax, ay, bx, by, color) {
ctx.beginPath();
ctx.moveTo(ax * ratio, ay * ratio);
ctx.lineTo(bx * ratio, by * ratio);
ctx.strokeStyle = color;
ctx.stroke();
}

function* split(ax, ay, bx, by, cx, cy) {
const mx = (ax + bx) >> 1;
const my = (ay + by) >> 1;

if (
Math.abs(ax - cx) + Math.abs(ay - cy) > 1 &&
errors[my * (tileSize + 1) + mx] > 100
) {
drawLine(mx, my, cx, cy, "red");
yield ctx.canvas;
yield* split(cx, cy, ax, ay, mx, my);
yield* split(bx, by, cx, cy, mx, my);
drawLine(mx, my, cx, cy, "black");
}
}

drawLine(0, 0, tileSize, tileSize, "red");
yield* split(0, 0, tileSize, tileSize, tileSize, 0, 0);
yield* split(tileSize, tileSize, 0, 0, 0, tileSize, 0);
drawLine(0, 0, tileSize, tileSize, "black");
}
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