map = () => {
const wrapper = d3.create("div")
.style("width", `${mapwidth}px`)
.style("height", `${mapheight}px`)
.style("position", "relative");
wrapper.append("style").html(css);
const canvas = wrapper.append("canvas")
.style("position", "absolute");
canvas.node().width = mapwidth;
canvas.node().height = mapheight;
const context = canvas.node().getContext("2d");
const path = d3.geoPath(projection, context);
context.beginPath();
path(statesOuter);
context.fillStyle = scheme.rangeOuter;
context.fill();
context.beginPath();
path(statesOuter);
context.clip();
range.features.forEach(feature => {
context.beginPath();
path(feature);
context.fillStyle = scheme.rangeInner;
context.fill();
});
context.beginPath();
path(statesInner);
context.strokeStyle = scheme.statesInner;
context.lineJoin = "round";
context.lineWidth = 0.5;
context.stroke();
data.forEach(d => {
context.beginPath();
path(square(d));
context.fillStyle = color(d);
context.fill();
});
path.context(null);
const svg = wrapper.append("svg")
.style("position", "absolute")
.attr("width", mapwidth)
.attr("height", mapheight);
svg.append("path")
.datum(statesOuter)
.attr("d", path)
.attr("fill", "none")
.attr("stroke", scheme.statesOuter)
.attr("stroke-linejoin", "round")
.attr("stroke-width", 0.5);
const citiesG = svg.selectAll(".city")
.data(cities)
.join("g")
.attr("class", d => `city ${d.pos} ${toSlugCase(d.name)}`)
.attr("transform", d => `translate(${projection([d.lon, d.lat])})`);
citiesG.append("circle")
.attr("class", "circle-bg")
.attr("r", 3);
citiesG.append("circle")
.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);
return wrapper.node();
}