Published
Edited
Nov 3, 2020
9 forks
28 stars
Also listed in…
d3-tile
d3-zoom
Insert cell
Insert cell
map = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

const projection = d3.geoMercator()
.scale(1 / (2 * Math.PI))
.translate([0, 0]);

const render = d3.geoPath(projection);

const tile = d3.tile()
.extent([[0, 0], [width, height]])
.tileSize(512);

const zoom = d3.zoom()
.scaleExtent([1 << 10, 1 << 15])
.extent([[0, 0], [width, height]])
.on("zoom", ({transform}) => zoomed(transform));

let image = svg.append("g")
.attr("pointer-events", "none")
.selectAll("image");

const path = svg.append("path")
.attr("pointer-events", "none")
.attr("fill", "none")
.attr("stroke", "red")
.attr("stroke-linecap", "round")
.attr("stroke-linejoin", "round");

svg
.call(zoom)
.call(zoom.transform, d3.zoomIdentity
.translate(width / 2, height / 2)
.scale(-initialScale)
.translate(...projection(initialCenter))
.scale(-1));

function zoomed(transform) {
const tiles = tile(transform);

image = image.data(tiles, d => d).join("image")
.attr("xlink:href", d => url(...d))
.attr("x", ([x]) => (x + tiles.translate[0]) * tiles.scale)
.attr("y", ([, y]) => (y + tiles.translate[1]) * tiles.scale)
.attr("width", tiles.scale)
.attr("height", tiles.scale);

projection
.scale(transform.k / (2 * Math.PI))
.translate([transform.x, transform.y]);

path.attr("d", render(feature));
}

return svg.node();
}
Insert cell
url = (x, y, z) => `https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/${z}/${x}/${y}${devicePixelRatio > 1 ? "@2x" : ""}?access_token=pk.eyJ1IjoibWJvc3RvY2siLCJhIjoiY2s5ZWRlbTM4MDE0eDNocWJ2aXR2amNmeiJ9.LEyjnNDr_BrxRmI4UDyJAQ`
Insert cell
height = 600
Insert cell
initialCenter = [-98 - 35 / 60, 39 + 50 / 60]
Insert cell
initialScale = 1 << 12
Insert cell
feature = d3.json("https://cdn.jsdelivr.net/npm/us-atlas@3/states-10m.json").then(topology => topojson.feature(topology, topology.objects.states))
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3@6", "d3-tile@1")
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