From 04ac124cb70bbfc6a3b06c06ca40d817106afc67 Mon Sep 17 00:00:00 2001
From: Doxa Maps
Date: Mon, 28 Sep 2026 16:09:15 +0000
Subject: [PATCH] Mount the ring legend, and dim the rings it is not talking
about
---
.../src/components/GiCenteredSet.vue | 23 ++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/plugin-designs/gospel-internet/src/components/GiCenteredSet.vue b/plugin-designs/gospel-internet/src/components/GiCenteredSet.vue
index 4ac1875ae..e40af1379 100644
--- a/plugin-designs/gospel-internet/src/components/GiCenteredSet.vue
+++ b/plugin-designs/gospel-internet/src/components/GiCenteredSet.vue
@@ -24,10 +24,14 @@ import { useBoardState } from '../useBoard.js'
import { useGiT } from '../useGiT.js'
import { loadNearRows, indexFor } from '../nearRows.js'
import { layoutCenteredSet, ringTally, inwardArrow, ringRadii } from '../centeredSet.js'
+import GiRingLegend from './GiRingLegend.vue'
const T = useGiT()
const board = useBoardState()
const near = ref(null)
+// Which ring the reader has asked about. null = none; the chart dims the others rather than
+// hiding them, because a ring with no dots left would read as a ring with no groups.
+const activeRing = ref(null)
const failed = ref('')
onMounted(async () => {
@@ -55,8 +59,14 @@ const prepared = computed(() => {
const layout = computed(() => layoutCenteredSet(prepared.value.groups, { innerR: 30, ringGap: 22 }))
const tally = computed(() => ringTally(layout.value))
const radii = computed(() => ringRadii({ innerR: 30, ringGap: 22 }))
+// The arrow carries its group's ring so the dimming can tell them apart. inwardArrow returns
+// geometry and the neighbour it names, not the ring — reading a.ring off it would have been
+// undefined for every arrow, and `undefined !== activeRing` is true, so selecting any ring
+// would have dimmed EVERY arrow rather than all but one. Attached here, where the group is
+// still in hand, instead of widening the shared module regions is promoting to library.
const arrows = computed(() => layout.value.placed
- .map((p) => inwardArrow(p, { innerR: 30 })).filter(Boolean).slice(0, 400))
+ .map((p) => { const a = inwardArrow(p, { innerR: 30 }); return a && { ...a, ring: p.ring } })
+ .filter(Boolean).slice(0, 400))
const fmt = (n) => (Number(n) || 0).toLocaleString()
useShadowStyles(
@@ -64,6 +74,7 @@ useShadowStyles(
'.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}' +
+ '.gcs-dim{opacity:.12}' +
'.gcs-dot{fill:#6d766e}.gcs-cross{stroke:#3b463d;stroke-width:3;stroke-linecap:square}' +
'.gcs-cap{margin-block-start:8px;color:#3b463d;font-size:13px;text-align:center;max-width:52ch}' +
'.gcs-warn{color:#6d766e;font-size:12px;margin-block-start:4px;max-width:52ch;text-align:center}',
@@ -81,8 +92,12 @@ useShadowStyles(
@@ -90,6 +105,8 @@ useShadowStyles(
{{ T('gospelInternet.centered.caption', 'Each group sits at its distance from a reached neighbour; arrows point at the one that places it.') }}
{{ fmt(tally.placed) }}
+
{{ T('gospelInternet.centered.reached', 'Already reached, so at the centre:') }} {{ fmt(tally.centre) }}. {{ T('gospelInternet.centered.unplaced', 'No relation found, so not placed:') }} {{ fmt(tally.unplaced) }}.