function make_map(cities) {
const context = DOM.context2d(w, h),
canvas = context.canvas,
path = d3.geoPath().context(context),
geopath = d3.geoPath(projection).context(context);
cities = move_centers(cities, projection);
const best = place_labels(cities);
cities = best.cities;
context.font = font;
context.fillStyle = "#eee";
context.fillRect(0, 0, w, w);
context.fillStyle = "#fff";
context.beginPath();
geopath(world);
context.fill();
context.strokeStyle = "#eee";
context.stroke();
context.fillStyle = "#000";
context.beginPath();
cities.forEach(c => {
path.pointRadius(pointRadius(c));
path({
type: "Point",
coordinates: [c.x, c.y]
});
});
context.fill();
if (debug) {
context.fillText(`${best.i} iterations (score: ${best.score | 0})`, 10, 10);
}
cities.forEach(c => {
if (c.label) {
context.textBaseline = c.baseline;
context.textAlign = c.anchor;
context.fillStyle = positions[c.pos].fill || "black";
context.fillText(c.label, c.lx, c.ly);
}
if (debug) {
if (!c.label) {
context.textBaseline = c.baseline;
context.textAlign = c.anchor;
context.fillStyle = "orange";
context.fillText(c.label || c.properties.name, c.lx, c.ly);
}
context.beginPath();
context.moveTo(c.dimensions.x, c.dimensions.y);
context.lineTo(c.dimensions.x + c.dimensions.width, c.dimensions.y);
context.lineTo(
c.dimensions.x + c.dimensions.width,
c.dimensions.y + c.dimensions.height
);
context.lineTo(c.dimensions.x, c.dimensions.y + c.dimensions.height);
context.lineTo(c.dimensions.x, c.dimensions.y);
context.strokeStyle = c.label ? "green" : "orange";
context.stroke();
}
});
return canvas;
}