Public
Edited
Jan 22, 2024
Insert cell
Insert cell
html`<div id="map" style="width: 100%;"></div>`
Insert cell
world_json = FileAttachment("world.json")
Insert cell
trajectory = FileAttachment('points38.json').json()
Insert cell
groupedData = d3.group(trajectory, d=>d.id)
Insert cell
expanded = Array.from(groupedData, ([key, series]) => {
const values = [];
for (let i = 0; i < series.length; i++) {
let point = [series[i].lat, series[i].lon];
values.push(point);
}
return [key, values];
})
Insert cell
lineData = expanded[0][2]
Insert cell
bufferedLine = geo.bufferLine(lineData, 0.01, "degrees");
Insert cell
{
let this_map = document.getElementById("map");
this_map.innerHTML = "";
let width = d3.select("#map").node().getBoundingClientRect().width + 4;
let height = 500 + 4;
const sensitivity = 75;

let projection = d3
.geoOrthographic()
.scale(250)
.center([0, 0])
.rotate([-5, 0])
.translate([width / 2, height / 2]);

const initialScale = projection.scale();
let path = d3.geoPath().projection(projection);

let svg = d3
.select("#map")
.append("svg")
.attr("width", width)
.attr("height", height);

let globe = svg
.append("circle")
.attr("fill", "lightblue")
// .attr("stroke", "#000")
// .attr("stroke-width", "0")
.attr("cx", width / 2)
.attr("cy", height / 2)
.attr("r", initialScale);

let data = await world_json.json();
svg
.append("g")
.attr("class", "countries")
.selectAll("path")
.data(data.features)
.enter()
.append("path")
.attr("class", (d) => "country_" + d.properties.name.replace(" ", "_"))
.attr("d", path)
.attr("fill", "white")
.style("stroke", "white")
.style("stroke-width", 0.3);
// .style("opacity",0.8)

svg
.append("circle")
.attr("fill", "none")
.attr("stroke", "#000")
.attr("stroke-width", "1")
.attr("cx", width / 2)
.attr("cy", height / 2)
.attr("r", initialScale);

// svg
// .call(
// d3.drag().on("drag", () => {
// const rotate = projection.rotate();
// const k = sensitivity / projection.scale();
// projection.rotate([
// rotate[0] + d3.event.dx * k,
// rotate[1] - d3.event.dy * k
// ]);
// path = d3.geoPath().projection(projection);
// svg.selectAll("path").attr("d", path);
// })
// );

//Optional rotate
d3.timer(function (elapsed) {
const rotate = projection.rotate();
const k = sensitivity / projection.scale();
projection.rotate([rotate[0] - 1 * k, rotate[1]]);
path = d3.geoPath().projection(projection);
svg.selectAll("path").attr("d", path);
}, 200);
}
Insert cell
d3 = require("d3@6")
Insert cell
geo = require("geotoolbox@2")
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