Published
Edited
Aug 11, 2020
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
canvasMap = {
const context = DOM.context2d(width, height);
const path = d3.geoPath(projection, context);
// draw globe background
context.beginPath(), path(sphere), context.fillStyle = "#000", context.fill();
// draw graticule
// context.beginPath(), path(graticule), context.strokeStyle = "rgba(255, 255, 255, 0.2)", context.stroke();
// draw land
context.beginPath(), path(land), context.fillStyle = "rgb(37, 49, 70)", context.fill();
// draw timezones
// context.beginPath(), path(mesh), context.strokeStyle = "rgba(255, 255, 255, 0.2)", context.stroke();

// draw daylight
context.beginPath(), path(day), context.fillStyle = "rgba(255, 255, 255, 0.1)", context.fill();
return context.canvas;
}
Insert cell
Insert cell
svgMap = html`<svg viewBox="0 0 ${width} ${height}" stroke-linejoin="round">
<path d="${path(sphere)}" fill="#000" />
<path d="${path(graticule)}" stroke="#fff" stroke-opacity="0.05" />
<path d="${path(land)}" fill="rgb(37, 49, 70)" />
<path d="${path(day)}" fill="#fff" fill-opacity="0.1" />
</svg>`
Insert cell
Insert cell
svgChart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
// sort by longitude
locations.sort((x, y) => x.long - y.long)
// draw globe surface
svg.append("path")
.datum(sphere)
.attr("fill", "#000")
.attr("d", path);
// draw land
svg.append("path")
.datum(land)
.attr("fill", "rgb(37, 49, 70)")
.attr("d", path);
// draw daylight
svg.append("path")
.datum(day)
.attr("fill", "rgba(255, 255, 255, 0.1")
.attr("d", path);
// draw locations based on lat/long
svg.append("g").selectAll("circle")
.data(locations)
.enter()
.append("circle")
.attr("fill", "#fff")
.attr("r", 2)
.attr("cx", (d) => coords(d)[0])
.attr("cy", (d) => coords(d)[1])
// draw Voronoi grid
svg.append("g").selectAll("path")
.data(voronoi.polygons(locations))
.enter()
.append("path")
.attr("fill", "none")
.attr("stroke", "cyan")
.attr("stroke-opacity", "0.2")
.attr("d", (d) => d ? "M" + d.join("L") + "Z" : null)
return svg.node();
}
Insert cell
Insert cell
height = {
const [[x0, y0], [x1, y1]] = d3.geoPath(projection.fitWidth(width, sphere)).bounds(sphere);
const dy = Math.ceil(y1 - y0), l = Math.min(Math.ceil(x1 - x0), dy);
projection.scale(projection.scale() * (l - 1) / l).precision(0.2);
return dy;
}
Insert cell
path = d3.geoPath(projection)
Insert cell
projection = d3.geoEquirectangular()
Insert cell
sphere = ({type: "Sphere"})
Insert cell
graticule = d3.geoGraticule10()
Insert cell
land = topojson.feature(world, world.objects.land)
Insert cell
world = fetch("https://cdn.jsdelivr.net/npm/world-atlas@2/land-50m.json").then(response => response.json())
Insert cell
Insert cell
sun = {
const now = new Date;
const day = new Date(+now).setUTCHours(0, 0, 0, 0);
const t = solar.century(now);
const longitude = (day - now) / 864e5 * 360 - 180;
return [longitude - solar.equationOfTime(t) / 4, solar.declination(t)];
}
Insert cell
day = d3.geoCircle()
.radius(90)
.center(sun)
()
Insert cell
night = d3.geoCircle()
.radius(90)
.center(antipode(sun))
()
Insert cell
antipode = ([longitude, latitude]) => [longitude + 180, -latitude]
Insert cell
solar = require("solar-calculator")
Insert cell
Insert cell
timezones = d3.json("https://gist.githubusercontent.com/mbostock/f0ae25cf1f057d443ca903277e3eb330/raw/254996390d4e19ef5eb1429103e0138ad08e19d0/timezones.json")
Insert cell
zones = topojson.feature(timezones, timezones.objects.timezones).features
Insert cell
mesh = topojson.mesh(timezones, timezones.objects.timezones)
Insert cell
Insert cell
locations = d3.csvParse(await FileAttachment("locations.csv").text(), d3.autoType)
Insert cell
coords = (d) => projection([d.long, d.lat])
Insert cell
voronoi = d3.voronoi()
.x((d) => coords(d)[0])
.y((d) => coords(d)[1])
.extent([[0, 0], [width, height]])
Insert cell
Insert cell
topojson = require("topojson")
Insert cell
d3 = require("d3@5")
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