Stop the ring legend pushing the centered-set chart off the page
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions

The legend was stacked below the chart in a centred column. On its own it is
taller than the pane — a 360px card with a nine-cell grid and four footer lines —
so the figure was pushed out of view entirely and the panel overflowed its host:
the legend covered the row beneath it and the caption drew over the page tabs.
The chart was not visible at all at 1440x900.

It is now a row: figure left, legend right, which is also the side placement the
legend was asked for. Every flex child takes min-height and min-width 0, because
a flex item's default minimum is its content size — without that an item never
shrinks below its natural height and the container overflows however little room
it has. That default is what turned a tall card into an unbounded one. Under
900px it returns to a column and scrolls rather than clipping.

Both charts now clear the centre tab strip, which is absolutely positioned near
the top and was covering the top of the bounded set's dots and all of the
centered set's caption. The bounded set also takes overflow:hidden, so a tall
caption can never do to it what the legend did to its neighbour.

Nothing about the counts changes. The page reads 2,082 placed where a slug-only
join predicts 2,074: the difference is the name-and-country fallback recovering
eight of the sixteen groups the neighbour table carries no slug for, and both
readings still sum to the full 2,107.
This commit is contained in:
Doxa Maps 2026-09-28 16:44:22 +00:00
parent bf08bc4464
commit 21ebb4f264
12 changed files with 53 additions and 30 deletions

View file

@ -68,7 +68,11 @@ const tally = computed(() => boundedSetTally(layout.value))
const fmt = (n) => formatCount(Number(n) || 0)
useShadowStyles(
'.gbs{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#f3f3f1}' +
// padding-block-start clears the centre tab strip (absolutely positioned at top:10px), which
// was overlapping the top of the dot cloud by about 20px. overflow:hidden so a tall caption
// can never push the figure out of its pane the way the legend did on the centered set.
'.gbs{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;' +
'justify-content:center;padding:46px 10px 10px;box-sizing:border-box;overflow:hidden;background:#f3f3f1}' +
'.gbs svg{max-width:100%;max-height:100%}' +
'.gbs-ring{fill:none;stroke:#3b463d;stroke-width:1.5}' +
'.gbs-in{fill:#92b195}.gbs-out{fill:#6d766e;opacity:.65}' +

View file

@ -77,7 +77,22 @@ const arrows = computed(() => layout.value.placed
const fmt = (n) => formatCount(Number(n) || 0)
useShadowStyles(
'.gcs{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#f3f3f1}' +
// ROW, NOT COLUMN, and overflow hidden. Stacked in a centred column the legend — a 360px card
// with a 3x3 grid of 44px cells and four footer lines — is taller than the pane on its own, so
// the chart was pushed out of view entirely and the whole panel overflowed its host: rega saw
// the legend covering the row below and the caption drawn over the page tabs.
// Every child gets min-height/min-width 0, because a flex item's default minimum is its CONTENT
// size — without it an item never shrinks below its natural height and the container overflows
// however little room it has.
// padding-block-start clears the centre tab strip, which is absolutely positioned at top:10px
// and was covering the top of both charts.
'.gcs{position:absolute;inset:0;display:flex;flex-direction:row;align-items:stretch;gap:10px;' +
'padding:46px 10px 10px;box-sizing:border-box;overflow:hidden;background:#f3f3f1}' +
'.gcs-fig{flex:1 1 auto;min-width:0;min-height:0;display:flex;flex-direction:column;' +
'align-items:center;justify-content:center;overflow:hidden}' +
'.gcs-aside{flex:0 0 auto;min-height:0;overflow:auto;display:flex;align-items:flex-start}' +
'@media (max-width:900px){.gcs{flex-direction:column;overflow:auto}' +
'.gcs-aside{overflow:visible;align-self:stretch}}' +
'.gcs svg{max-width:100%;max-height:100%}' +
'.gcs-ring{fill:none;stroke:#d1d4cd;stroke-width:1}' +
'.gcs-arrow{stroke:#92b195;stroke-width:.6;opacity:.5}' +
@ -96,6 +111,7 @@ useShadowStyles(
<span class="gcs-warn" dir="ltr">{{ failed }}</span>
</p>
<template v-else>
<div class="gcs-fig">
<svg viewBox="-300 -300 600 600" role="img"
:aria-label="T('gospelInternet.centered.aria', 'Centered set: unreached groups placed by closeness to a reached neighbour, arrows pointing inward')">
<circle v-for="r in radii" :key="r.ring" class="gcs-ring" cx="0" cy="0" :r="r.r" />
@ -112,8 +128,11 @@ useShadowStyles(
{{ T('gospelInternet.centered.caption', 'Each group sits at its distance from a reached neighbour; arrows point at the one that places it.') }}
<b dir="ltr">{{ fmt(tally.placed) }}</b>
</p>
<GiRingLegend :groups="prepared.groups" :unmatched="prepared.unmatched"
:active-ring="activeRing" @select="activeRing = $event" />
</div>
<div class="gcs-aside">
<GiRingLegend :groups="prepared.groups" :unmatched="prepared.unmatched"
:active-ring="activeRing" @select="activeRing = $event" />
</div>
<p v-if="tally.centre || tally.unplaced || prepared.unmatched" class="gcs-warn">
<span v-if="tally.centre">{{ T('gospelInternet.centered.reached', 'Already reached, so at the centre:') }} <b dir="ltr">{{ fmt(tally.centre) }}</b>. </span>
<span v-if="tally.unplaced">{{ T('gospelInternet.centered.unplaced', 'No relation found, so not placed:') }} <b dir="ltr">{{ fmt(tally.unplaced) }}</b>. </span>

View file

@ -615,7 +615,7 @@
"bundle": "gospel-internet",
"scriptUrl": "./gospel-internet/gospel-internet.js",
"output": "dx-maps/gospel-internet/gospel-internet.js",
"integrity": "sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf",
"integrity": "sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65",
"elements": [
"gospel-internet-board"
],
@ -635,7 +635,7 @@
"scriptUrl": "./gospel-internet/gospel-internet.js",
"embed": {
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
},
"instances": [
{

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
<script src="../../gospel-internet.js" integrity="sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
<script src="../gospel-internet.js" integrity="sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf" crossorigin="anonymous"></script>
<script src="../gospel-internet.js" integrity="sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
<script src="../../gospel-internet.js" integrity="sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
<script src="../../gospel-internet.js" integrity="sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
<script src="../../gospel-internet.js" integrity="sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
<script src="../../gospel-internet.js" integrity="sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -36,7 +36,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
<script src="../../gospel-internet.js" integrity="sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf" crossorigin="anonymous"></script>
<script src="../../gospel-internet.js" integrity="sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -615,7 +615,7 @@
"bundle": "gospel-internet",
"scriptUrl": "./gospel-internet/gospel-internet.js",
"output": "dx-maps/gospel-internet/gospel-internet.js",
"integrity": "sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf",
"integrity": "sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65",
"elements": [
"gospel-internet-board"
],
@ -635,7 +635,7 @@
"scriptUrl": "./gospel-internet/gospel-internet.js",
"embed": {
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-ra2hMdet/tufipbCflH8yhJFy3o9FpuYhjOoCMmv+PQpxW0qabvX60QRST119oUf\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-sQo87qaiJTahP8Ssy3OmftpidxywGQ+cLmfp4QLWQfLBaHuBRcpiRM1yQpf/QL65\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
},
"instances": [
{