Mount the ring legend, and dim the rings it is not talking about
This commit is contained in:
parent
f49c81cec6
commit
04ac124cb7
1 changed files with 20 additions and 3 deletions
|
|
@ -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(
|
|||
<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" />
|
||||
<line v-for="(a, i) in arrows" :key="i" class="gcs-arrow" :x1="a.x1" :y1="a.y1" :x2="a.x2" :y2="a.y2" />
|
||||
<circle v-for="p in layout.placed" :key="p.id" class="gcs-dot" :cx="p.x" :cy="p.y" r="1.8" />
|
||||
<line v-for="(a, i) in arrows" :key="i" class="gcs-arrow"
|
||||
:class="{ 'gcs-dim': activeRing != null && a.ring !== activeRing }"
|
||||
:x1="a.x1" :y1="a.y1" :x2="a.x2" :y2="a.y2" />
|
||||
<circle v-for="p in layout.placed" :key="p.id" class="gcs-dot"
|
||||
:class="{ 'gcs-dim': activeRing != null && p.ring !== activeRing }"
|
||||
:cx="p.x" :cy="p.y" r="1.8" />
|
||||
<line class="gcs-cross" x1="0" y1="-13" x2="0" y2="13" />
|
||||
<line class="gcs-cross" x1="-9" y1="-4" x2="9" y2="-4" />
|
||||
</svg>
|
||||
|
|
@ -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.') }}
|
||||
<b dir="ltr">{{ fmt(tally.placed) }}</b>
|
||||
</p>
|
||||
<GiRingLegend :groups="prepared.groups" :unmatched="prepared.unmatched"
|
||||
:active-ring="activeRing" @select="activeRing = $event" />
|
||||
<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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue