From 722ac778926708dd4fb11a626c2d5fb49a207448 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Mon, 28 Sep 2026 15:25:26 +0000 Subject: [PATCH] Join the set charts on a key both sides actually carry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both set charts reported "not drawn: 2,104". The join read g.country, and on these rows country is the country's NAME while the neighbour table keys on ISO 3166 alpha-3, so the pair never matched — and because the rop3 half is absent from these rows too, nothing matched at all. Measured against the shipped tables with real names and real codes: the name path resolves 0 of 12,379 rows as written, and 6,850 once the ISO code is used. It survived my own verification because I measured the join with the province table standing in for the dashboard's rows, and those rows carry iso3 rather than country. The stand-in satisfied the key I had chosen, so the measurement confirmed the code against a shape the real caller does not have. A proxy has to match the caller in the fields the code reads, or it is only testing itself. Three keys now, strongest first. Slug is the only one that is a single field on both sides and unique by construction, since the table's build refuses to emit two rows sharing one; rop3 with the ISO code is a compound key these rows may not carry; name with the ISO code depends on two sources spelling a people the same way, so it stays the last resort rather than the first guess. A row carrying only a name is still better joined than dropped. The slug column is not in the table yet. Each key is indexed only when its field is present, so today the slug map is empty and every lookup falls through — verified against the shipped table: 0 slug keys, no entry keyed on a missing value, and a slug lookup returns undefined rather than colliding. That makes this safe to land before or after the column arrives. --- .../gospel-internet/src/nearRows.js | 32 +++++++++++++++++-- public/dx-maps/doxa-maps-spa/manifest.json | 4 +-- .../gospel-internet/board/board/index.html | 2 +- .../dx-maps/gospel-internet/board/index.html | 2 +- .../board/india-china/index.html | 2 +- .../board/language-tree/index.html | 2 +- .../board/platforms/index.html | 2 +- .../board/project-700/index.html | 2 +- .../gospel-internet/board/zero/index.html | 2 +- .../gospel-internet/gospel-internet.js | 2 +- public/dx-maps/manifest.json | 4 +-- 11 files changed, 42 insertions(+), 14 deletions(-) diff --git a/plugin-designs/gospel-internet/src/nearRows.js b/plugin-designs/gospel-internet/src/nearRows.js index 677789b04..d9df90105 100644 --- a/plugin-designs/gospel-internet/src/nearRows.js +++ b/plugin-designs/gospel-internet/src/nearRows.js @@ -35,13 +35,18 @@ export function loadNearRows(cfg = {}) { const ix = Object.fromEntries(d.cols.map((c, i) => [c, i])) const dec = (r, c) => (c in ix ? (d.dict[c] ? d.dict[c][r[ix[c]]] : r[ix[c]]) : undefined) const rows = d.rows.map((r) => ({ + slug: dec(r, 'slug') ?? null, name: dec(r, 'name'), iso3: dec(r, 'iso3'), rop3: dec(r, 'rop3') ?? null, reached: dec(r, 'reached') === 1, ring: dec(r, 'ring'), ringNb: dec(r, 'ringNb'), })) // Both keys, so a caller can prefer rop3 and still fall back to the name pair. + // Three keys, strongest first. Each is added only when the table carries it, so a table + // without the column simply yields no entries of that kind rather than an entry keyed on + // undefined — which would match every row missing the field. const byKey = new Map() for (let i = 0; i < rows.length; i++) { const r = rows[i] + if (r.slug) byKey.set(`s:${r.slug}`, i) byKey.set(`n:${String(r.name).toLowerCase()}|${String(r.iso3).toUpperCase()}`, i) if (r.rop3) byKey.set(`r:${r.rop3}|${String(r.iso3).toUpperCase()}`, i) } @@ -50,9 +55,32 @@ export function loadNearRows(cfg = {}) { return pending } -/** The row index for a dashboard row, rop3 first. Returns -1 when it does not join. */ +/** + * The row index for a dashboard row, rop3 first. Returns -1 when it does not join. + * + * ⚠ THE COUNTRY KEY IS `iso3`, NOT `country`. This read `g.country` and shipped: on these rows + * `country` is the country's NAME ("Malaysia") while the table keys on ISO 3166 alpha-3 ("MYS"), + * so the pair never matched and the rop3 path never fired either — the Driver saw + * "not drawn: 2,104" on both set charts. + * + * It survived my own check because I measured the join with the PROVINCE table standing in for + * the dashboard's rows, and those rows carry `iso3` rather than `country`. The stand-in satisfied + * the key I had chosen, so the measurement confirmed the code against a shape the real caller does + * not have. A proxy has to match the caller in the FIELDS THE CODE READS, or it is testing itself. + * + * `country` is still accepted as a last resort, because a row that carries only the name is better + * joined than dropped — but it is tried after the ISO code, never instead of it. + */ export function indexFor(byKey, g) { - const c = String(g?.country ?? '').toUpperCase() + const c = String(g?.iso3 ?? g?.country ?? '').toUpperCase() + // SLUG FIRST: the only key that is one field on both sides and unique by construction — the + // table's build refuses to emit two rows sharing one. rop3 + iso3 is a compound key that these + // rows may not carry; name + iso3 depends on two sources spelling a people the same way. + // Inert until the table ships the column, so this is safe to land in either order. + if (g?.slug) { + const hit = byKey.get(`s:${g.slug}`) + if (hit != null) return hit + } if (g?.rop3) { const hit = byKey.get(`r:${g.rop3}|${c}`) if (hit != null) return hit diff --git a/public/dx-maps/doxa-maps-spa/manifest.json b/public/dx-maps/doxa-maps-spa/manifest.json index aa12aad4e..8570f494d 100644 --- a/public/dx-maps/doxa-maps-spa/manifest.json +++ b/public/dx-maps/doxa-maps-spa/manifest.json @@ -615,7 +615,7 @@ "bundle": "gospel-internet", "scriptUrl": "./gospel-internet/gospel-internet.js", "output": "dx-maps/gospel-internet/gospel-internet.js", - "integrity": "sha384-LEx6FMflv8Qjg3AaMhUj4Fhm/O0R29R0lYWbJHNu8N/hfiQqObV1j0ALFcTN4P4q", + "integrity": "sha384-emOnf4+T85x22PfTxGEduNT850NJ0GZb2xOerkdXmPgA9/2YOZn5HsaDRiAu7hhL", "elements": [ "gospel-internet-board" ], @@ -635,7 +635,7 @@ "scriptUrl": "./gospel-internet/gospel-internet.js", "embed": { "iframe": "", - "script": "\n\n\n\n" + "script": "\n\n\n\n" }, "instances": [ { diff --git a/public/dx-maps/gospel-internet/board/board/index.html b/public/dx-maps/gospel-internet/board/board/index.html index 6c59a28fa..8944aa8da 100644 --- a/public/dx-maps/gospel-internet/board/board/index.html +++ b/public/dx-maps/gospel-internet/board/board/index.html @@ -36,7 +36,7 @@ - + - + - + - + - + - + - + \n\n" + "script": "\n\n\n\n" }, "instances": [ {