map = function*() {
const wrapper = d3.create("div")
.style("width", `${w}px`)
.style("height", `${h}px`)
.style("position", "relative");
wrapper.append("style").html(css);
const canvas = wrapper.append("canvas")
.style("position", "absolute");
canvas.node().width = w;
canvas.node().height = h;
const context = canvas.node().getContext("2d");
path.context(context);
for (let i = 0, l = X.length * Y.length; i < l; i++) {
const lon = X[i % X.length];
const lat = Y[i / X.length | 0];
let w = Math.max(-180, lon - cell_res);
let e = Math.min(180, lon + cell_res);
let n = Math.min(90, lat + cell_res);
let s = Math.max(-90, lat - cell_res);
if (n > 0 && s < 0) {
if (lon > 0) s = 0;
if (lon < 0) n = 0;
}
context.beginPath();
path(feature(n, e, w, s));
const c = colorScale(values[season.toLowerCase()][i] * 10);
context.fillStyle = c;
context.fill();
context.strokeStyle = c;
context.stroke();
if (i % 1e4 === 0) yield wrapper.node();
}
context.fillStyle = "none";
context.beginPath();
path(countriesGeoInner);
context.strokeStyle = "#494949";
context.stroke();
context.beginPath();
path(countriesGeoOuter);
context.strokeStyle = "#2a2a2a";
context.stroke();
const svg = wrapper.append("svg")
.style("overflow", "visible")
.style("position", "absolute")
.attr("width", w)
.attr("height", h);
const center = [w / 2, h / 2];
svg.selectAll("polygon")
.data([0, 1])
.join("polygon")
.attr("fill", "white")
.attr("points", d => [
...swoopy.arc([w / 2, 0], center, 1 - 2 * d),
...swoopy.arc(center, [w / 2, h], 1 - 2 * d),
[d * w, h],
[d * w, 0]
]);
svg.selectAll(".sphere")
.data([0, 1])
.join("circle")
.attr("class", "sphere")
.attr("cx", w / 2)
.attr("cy", d => h / 4 + (h / 2) * d)
.attr("fill", "none")
.attr("r", w / 2)
.attr("stroke", "#494949");
const citiesG = svg.selectAll(".city")
.data(cities)
.join("g")
.attr("class", d => `city ${d.pos}`)
.attr("transform", d => `translate(${projection([d.lon, d.lat])})`);
citiesG.append("circle")
.attr("class", "bg bg-0")
.attr("r", 3);
citiesG.append("circle")
.attr("class", "bg bg-1")
.attr("r", 3);
citiesG.append("circle")
.attr("class", "fg")
.attr("r", 3);
citiesG.append("text")
.attr("class", "bg bg-0")
.text(d => d.name);
citiesG.append("text")
.attr("class", "bg bg-1")
.text(d => d.name);
citiesG.append("text")
.attr("class", "fg")
.text(d => d.name);
yield wrapper.node();
}