Skip to content

Population Mapping: Cell Fill#1500

Open
inviktos wants to merge 11 commits into
Azgaar:masterfrom
inviktos:master
Open

Population Mapping: Cell Fill#1500
inviktos wants to merge 11 commits into
Azgaar:masterfrom
inviktos:master

Conversation

@inviktos

Copy link
Copy Markdown

NOTE: I am very inexperienced with coding in this manner and as such have relied upon Codex for a lot of the heavy lifting. Since this change is basically exclusive to the display portion of population and does not modify any map data, potential issues with this fork should not cause any data corruption whatsoever.

This pull request proposes a new population display system that will replace the old population bar display. The maximum cell will have a Value (Within HSV) of 100%, while all other cells are to be colored comparatively. Coloring is conducted on a logarithmic scale such that large-population cells do not dominate and make the rest of the map black. The opacity and filters for this layer are fully customizable, however population will always render above biomes.

@netlify

netlify Bot commented Jun 23, 2026

Copy link
Copy Markdown

Deploy Preview for afmg ready!

Name Link
🔨 Latest commit d3c733d
🔍 Latest deploy log https://app.netlify.com/projects/afmg/deploys/6a39d9eb2003a100080912f9
😎 Deploy Preview https://deploy-preview-1500--afmg.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the legacy population “bar/line” visualization with a new population overlay rendered as filled cell regions colored on a logarithmic scale, aiming to keep population readable across large ranges and ensuring the layer renders above biomes. It also updates layer UI placement and styling/preset support to match the new rendering approach.

Changes:

  • Reworked the population layer rendering to generate filled SVG paths (with coastal stroke handling) and placed the population SVG group above biomes.
  • Updated layer toggles / load behavior so the population layer is detected and re-rendered on load.
  • Adjusted CSS and style preset capture to reflect the new population layer semantics (opacity/filter rather than stroke-centric settings).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/index.html Moves the Population layer toggle location and updates cache-busting query strings for modified assets.
public/modules/ui/style.js Removes population-specific style UI wiring from selectStyleElement to align with the new rendering approach.
public/modules/ui/style-presets.js Updates style preset collection for #population to only persist opacity and filter.
public/modules/ui/layers.js Implements the new population rendering (cell-fill via isolines), updates toggle behavior, and introduces new helper functions.
public/modules/io/load.js Updates population-layer detection on load and triggers a redraw when population content exists.
public/main.js Changes default SVG layer order by inserting #population immediately after #biomes.
public/index.css Updates base SVG styling so #population participates correctly as a filled layer and is clipped/masked consistently.

Comment on lines 361 to 370
function togglePopulation(event) {
if (!population.selectAll("line").size()) {
if (!population.selectAll("path, line").size()) {
turnButtonOn("togglePopulation");
drawPopulation();
if (event && isCtrlClick(event)) editStyle("population");
} else {
if (event && isCtrlClick(event)) return editStyle("population");
turnButtonOff("togglePopulation");

const isD3data = population.select("line").datum();
if (!isD3data) {
// just remove
population.selectAll("line").remove();
} else {
// remove with animation
const hide = d3.transition().duration(1000).ease(d3.easeSinIn);
population
.select("#rural")
.selectAll("line")
.transition(hide)
.attr("y2", d => d[1])
.remove();
population
.select("#urban")
.selectAll("line")
.transition(hide)
.delay(1000)
.attr("y2", d => d[1])
.remove();
}
population.selectAll("*").remove();
}
population.selectAll("line").remove();
TIME && console.time("drawPopulation");

biomes.node().after(population.node());
Comment on lines +440 to +447
function getPopulationColor(urbanPopulation, totalPopulation, maxPopulation) {
if (!totalPopulation || !maxPopulation) return "#000000";

const urbanShare = urbanPopulation / totalPopulation;
const hue = 240 + 120 * urbanShare;
const value = (Math.log1p(totalPopulation) / Math.log1p(maxPopulation)) ** 1.5;
return hsvToHex(hue, 1, value);
}
Comment on lines +404 to +412
const colors = new Array(cells.i.length);
for (const cellId of cells.i) {
if (cells.h[cellId] < 20) continue;
colors[cellId] = getPopulationColor(urban[cellId], total[cellId], maxPopulation);
}

population
.select("#rural")
.selectAll("line")
.data(rural)
.enter()
.append("line")
.attr("x1", d => d[0])
.attr("y1", d => d[1])
.attr("x2", d => d[0])
.attr("y2", d => d[1])
.transition(show)
.attr("y2", d => d[2]);
const isolines = getIsolines(pack, cellId => colors[cellId] || null, { fill: true, waterGap: true });
const populationShapes = Object.entries(isolines).map(([color, { fill, waterGap }], index) => {
const closedFill = closeSvgPathRings(fill);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants