Pplr Data Maps: tab and legend labels follow a language change instead of keeping the one they started with

This commit is contained in:
Doxa Maps 2026-09-28 12:59:12 +00:00
parent 439bea6754
commit 55cc694fdd
3 changed files with 19 additions and 13 deletions

View file

@ -1,6 +1,7 @@
<script setup>
import { dataUrl, glFor, exposeMap, whenGeojsonDrawn, setProjectionFor } from '../utils/pplrData.js'
import { usePplrT } from '../composables/usePplrT.js'
import { useOptionalT } from '@map/composables/useOptionalT.js'
import { tStatic } from '@map/i18n/index.js'
/**
* pplr-language-families.vue — PG pins colored by PPLR ethnolinguistic family.
@ -33,6 +34,7 @@ const mapboxToken = inject('mapboxToken')
const mapContainer = ref(null)
const profileRoot = ref(null) // FullscreenControl target — fullscreens .profile so chrome stays visible
const t = usePplrT()
const tShared = useOptionalT() // unqualified: tabs.* is a shared area
const status = ref(t('pplr.status.loading'))
const PIN_LAYER = 'lf-pins'
@ -119,14 +121,15 @@ const familyPops = ref({}) // famKey → total population
const hasPop = ref(false)
const famLangGroups = ref({}) // famKey → { count, pop, langs: LangGroup[] }
const LANG_TABS = [
{ id: 'family', label: tStatic('tabs.family'),
// computed + the reactive shared-key t: tStatic reads a window global, so a computed over it would freeze too
const LANG_TABS = computed(() => [
{ id: 'family', label: tShared('tabs.family'),
info: 'PPLR\'s ethnolinguistic family classification (per assets/data/pplr-geoid-family.json). Note: PPLR groups Arabic under "Arab (Arabic)" rather than the broader linguistic family "Afro-Asiatic", and splits other Afro-Asiatic peoples into "Hausa-Chadic", "Cushitic", "Sudanic", etc.' },
{ id: 'language', label: tStatic('tabs.language'),
{ id: 'language', label: tShared('tabs.language'),
info: 'A distinct language (e.g. Arabic, Hindi, Punjabi). Identified by 3-character ROL code (ISO 639-3).' },
{ id: 'variant', label: tStatic('tabs.dialect'),
{ id: 'variant', label: tShared('tabs.dialect'),
info: 'A regional or social variety of a language (e.g. "Punjabi, Western", "Arabic, Egyptian"). Comma-separated names group as variants under a root language.' },
]
])
const LANG_KIND_LABELS = { family: 'Lang Family', language: 'Language', variant: 'Variant', dialect: 'Dialect' }

View file

@ -1,6 +1,7 @@
<script setup>
import { dataUrl, glFor, exposeMap, setProjectionFor } from '../utils/pplrData.js'
import { usePplrT } from '../composables/usePplrT.js'
import { useOptionalT } from '@map/composables/useOptionalT.js'
import { tStatic } from '@map/i18n/index.js'
/**
* pplr-rop-tree.vue — ROP hierarchy: Affinity Bloc → Cluster → People Group → PGIC.
@ -30,6 +31,7 @@ const mapboxToken = inject('mapboxToken')
const mapContainer = ref(null)
const profileRoot = ref(null) // FullscreenControl target — fullscreens the .profile so chrome stays visible
const t = usePplrT()
const tShared = useOptionalT() // unqualified: tabs.* is a shared area
const status = ref(t('pplr.status.loading'))
const PIN_LAYER = 'rop-pins'
@ -95,17 +97,18 @@ const BASEMAPS = [
// SemanticTreeLegend renders the first 3 generations inline; the 4th (PGIC / 21k items)
// is handled by a separate floating panel (too many nodes for the inline tree).
// Short tab labels keep all 4 chips on a single row. The "i" tooltip carries the full meaning.
const ROP_TABS = [
{ id: 'affinity', label: tStatic('tabs.bloc'),
// computed + the reactive shared-key t: tStatic reads a window global, so a computed over it would freeze too
const ROP_TABS = computed(() => [
{ id: 'affinity', label: tShared('tabs.bloc'),
info: 'Affinity Bloc — top-level grouping of related people groups (e.g. Arab Peoples). 17 blocs total.' },
{ id: 'cluster', label: tStatic('tabs.cluster'),
{ id: 'cluster', label: tShared('tabs.cluster'),
info: 'People Cluster — subdivision within an Affinity Bloc (e.g. Maghrebi Arab inside Arab Peoples). 292 clusters.' },
{ id: 'rop25', label: 'ROP25',
info: 'People Group level — a distinct ethnolinguistic identity (e.g. Algerian Arab). ~13k groups.' },
{ id: 'rop3xc', label: tStatic('tabs.pgic'),
{ id: 'rop3xc', label: tShared('tabs.pgic'),
topLimit: 200,
info: 'ROP3 × Country (PGIC) — same ethnolinguistic group in a specific country (e.g. Algerian Arab in France). 21k records. Showing top 200 by population — use the geocoder to find the rest.' },
]
])
// Build the ropTree ONCE from the now-loaded data (called from onMounted after pg-points
// + pgicLookup are ready). Avoids the previous behavior where the computed re-allocated

View file

@ -12,7 +12,7 @@
* The 5 sample PGs from rosetta-sample.json are highlighted with larger pins.
* Click any pin → popup with full Rosetta table.
*/
import { inject, onMounted, onBeforeUnmount, ref } from 'vue'
import { inject, onMounted, onBeforeUnmount, ref, computed } from 'vue'
import { glFor, exposeMap, whenGeojsonDrawn } from '../utils/pplrData.js'
import { usePplrT } from '../composables/usePplrT.js'
import { tStatic } from '@map/i18n/index.js'
@ -160,13 +160,13 @@ onMounted(async () => {
})
onBeforeUnmount(() => destroy())
const LEGEND = [
const LEGEND = computed(() => [
{ color: '#fbbf24', label: t('pplr.rosetta.legend.all') },
{ color: '#3b82f6', label: 'JP + IMB' },
{ color: '#a78bfa', label: t('pplr.rosetta.legend.imbOnly') },
{ color: '#ec4899', label: t('pplr.rosetta.legend.jpOnly') },
{ color: '#6b7280', label: t('pplr.rosetta.legend.neither') },
]
])
</script>
<template>