Update from source d8c67ca28
This commit is contained in:
parent
51728f96f7
commit
529bd65af5
6 changed files with 121 additions and 115 deletions
|
|
@ -1092,6 +1092,43 @@ function _buildFlatLegendMatchExpr(node, legendType) {
|
|||
}
|
||||
return null
|
||||
}
|
||||
// ─── ONE WRITER FOR THE REGION POLYGONS ──────────────────────────────────────
|
||||
// ★ MEASURED (rega, main 373b7979b): a single WAGF row click produced NINE regions-* paint writes —
|
||||
// fill-opacity, line-color and line-width, three times each inside ~110 ms — because two paths painted
|
||||
// the same highlight from DIFFERENT sources: onSemanticTreeSelect from node.isoCodes, applyDimFilter
|
||||
// from mapLayers.regionIsoMap, each triggering the other through mapStore. Two sources for one visual
|
||||
// is not just wasted work; it is how they drift, and it already cost a debugging cycle when we had to
|
||||
// establish WHICH of them had cleared the highlight.
|
||||
//
|
||||
// ★ AND THE IDLE STATE IS DATA-DRIVEN ON PURPOSE. rega measured the row click compiling a new shader
|
||||
// variant: 5.5 s on MapLibre, 11.1 s on Mapbox (SwiftShader), because that click was the first moment
|
||||
// these three properties stopped being constants. Same defect as the pins, same fix: the idle value is
|
||||
// ['case', ['has', 'iso_3166_1_alpha_3'], x, x] — both branches identical, so not one pixel changes —
|
||||
// and the variant therefore compiles when the layer is ADDED rather than mid-gesture.
|
||||
//
|
||||
// The compare is asked of the MAP, not of a remembered key, so a layer torn down and re-added cannot
|
||||
// leave a skip holding a paint that is no longer there.
|
||||
const REGION_IDLE_FILL = ['case', ['has', 'iso_3166_1_alpha_3'], 0.7, 0.7]
|
||||
const REGION_IDLE_COLOR = ['case', ['has', 'iso_3166_1_alpha_3'], 'rgba(60,60,80,0.35)', 'rgba(60,60,80,0.35)']
|
||||
const REGION_IDLE_WIDTH = ['case', ['has', 'iso_3166_1_alpha_3'], 0.6, 0.6]
|
||||
function paintRegionScope(m, isoCodes) {
|
||||
if (!m || !m.getLayer('regions-fill')) return
|
||||
const list = Array.isArray(isoCodes) ? isoCodes.filter(Boolean) : []
|
||||
const isoArr = ['literal', list]
|
||||
const fill = list.length ? ['case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], 0.85, 0.15] : REGION_IDLE_FILL
|
||||
const color = list.length ? ['case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], '#111827', 'rgba(60,60,80,0.15)'] : REGION_IDLE_COLOR
|
||||
const width = list.length ? ['case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], 2.5, 0.3] : REGION_IDLE_WIDTH
|
||||
const put = (layer, prop, value) => {
|
||||
if (!m.getLayer(layer)) return
|
||||
if (JSON.stringify(m.getPaintProperty(layer, prop)) === JSON.stringify(value)) return
|
||||
m.setPaintProperty(layer, prop, value)
|
||||
}
|
||||
try {
|
||||
put('regions-fill', 'fill-opacity', fill)
|
||||
put('regions-border', 'line-color', color)
|
||||
put('regions-border', 'line-width', width)
|
||||
} catch (_) { /* style still loading — the next paint carries it */ }
|
||||
}
|
||||
function onSemanticTreeSelect(node) {
|
||||
const m = map.value
|
||||
// — uniform legend-row camera: any non-null row click moves
|
||||
|
|
@ -1195,25 +1232,7 @@ function onSemanticTreeSelect(node) {
|
|||
// Mirror region selection into mapStore (for geocoder / external sync).
|
||||
if (id.startsWith('region:')) mapStore.selectRegion?.(id.slice(7))
|
||||
// Highlight matching polygons using isoCodes (alpha-3) on iso_3166_1_alpha_3.
|
||||
if (m && m.getLayer('regions-fill')) {
|
||||
const isoCodes = node.isoCodes || []
|
||||
if (isoCodes.length) {
|
||||
const isoArr = ['literal', isoCodes]
|
||||
m.setPaintProperty('regions-fill', 'fill-opacity', [
|
||||
'case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], 0.85, 0.15
|
||||
])
|
||||
m.setPaintProperty('regions-border', 'line-color', [
|
||||
'case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], '#111827', 'rgba(60,60,80,0.15)'
|
||||
])
|
||||
m.setPaintProperty('regions-border', 'line-width', [
|
||||
'case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], 2.5, 0.3
|
||||
])
|
||||
} else {
|
||||
m.setPaintProperty('regions-fill', 'fill-opacity', 0.7)
|
||||
m.setPaintProperty('regions-border', 'line-color', 'rgba(60,60,80,0.35)')
|
||||
m.setPaintProperty('regions-border', 'line-width', 0.6)
|
||||
}
|
||||
}
|
||||
paintRegionScope(m, node.isoCodes || [])
|
||||
}
|
||||
}
|
||||
// Theme bridge: keep the SemanticTreeLegend in sync with the app's dark-mode
|
||||
|
|
@ -1537,6 +1556,12 @@ async function ensureRegionsLoaded() {
|
|||
const regionsData = await mapData.loadRegionsData?.()
|
||||
if (regionsData && map.value) {
|
||||
mapLayers.addRegionsLayer?.(regionsData, 'doxa-regions')
|
||||
// ★ PRE-WARM HERE, which is the only moment that helps. These layers are added on first visit
|
||||
// to the Regions tab, and rega measured the first ROW click paying 5.5 s (MapLibre) / 11.1 s
|
||||
// (Mapbox) of shader compile because that click was when their paint first became data-driven.
|
||||
// Painting the idle state through paintRegionScope makes it data-driven from the first draw, so
|
||||
// the variant compiles here — where a 6.4 MB GeoJSON is already loading — instead of mid-gesture.
|
||||
paintRegionScope(map.value, [])
|
||||
// Hide regions on non-Doxa-Regions tabs so they don't show through.
|
||||
if (map.value.getLayer('regions-fill') && activeTab.value?.id !== 'doxa-regions') {
|
||||
map.value.setLayoutProperty('regions-fill', 'visibility', 'none')
|
||||
|
|
@ -1733,14 +1758,10 @@ function clearAllHighlights(m) {
|
|||
m.setFilter('language-family-pins', null)
|
||||
_syncHitboxFilter(m, null)
|
||||
mapLayers.syncGlowFilter(null)
|
||||
if (m.getLayer('regions-fill')) {
|
||||
m.setPaintProperty('regions-fill', 'fill-opacity', 0.7)
|
||||
m.setPaintProperty('regions-fill', 'fill-outline-color', null)
|
||||
}
|
||||
if (m.getLayer('regions-border')) {
|
||||
m.setPaintProperty('regions-border', 'line-color', 'rgba(60,60,80,0.35)')
|
||||
m.setPaintProperty('regions-border', 'line-width', 0.6)
|
||||
}
|
||||
// Through the one writer, so "cleared" and "idle" are the same expression rather than two spellings
|
||||
// of it — and so the idle state stays DATA-DRIVEN and the shader variant stays compiled.
|
||||
paintRegionScope(m, [])
|
||||
if (m.getLayer('regions-fill')) m.setPaintProperty('regions-fill', 'fill-outline-color', null)
|
||||
_lastHL.family = _lastHL.language = _lastHL.dialect = _lastHL.region = null
|
||||
_lastHL.prayer = _lastHL.engagement = _lastHL.adoption = null
|
||||
if (uiStore.prayerFilter) uiStore.setPrayerFilter(null)
|
||||
|
|
@ -1860,22 +1881,7 @@ function applyDimFilter(detail) {
|
|||
if (norm(k) === ev) { isoCodes = v; break }
|
||||
}
|
||||
}
|
||||
if (isoCodes.length) {
|
||||
const isoArr = ['literal', isoCodes]
|
||||
m.setPaintProperty('regions-fill', 'fill-opacity', [
|
||||
'case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], 0.85, 0.15
|
||||
])
|
||||
m.setPaintProperty('regions-border', 'line-color', [
|
||||
'case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], '#111827', 'rgba(60,60,80,0.15)'
|
||||
])
|
||||
m.setPaintProperty('regions-border', 'line-width', [
|
||||
'case', ['in', ['get', 'iso_3166_1_alpha_3'], isoArr], 2.5, 0.3
|
||||
])
|
||||
} else {
|
||||
m.setPaintProperty('regions-fill', 'fill-opacity', 0.7)
|
||||
m.setPaintProperty('regions-border', 'line-color', 'rgba(60,60,80,0.35)')
|
||||
m.setPaintProperty('regions-border', 'line-width', 0.6)
|
||||
}
|
||||
paintRegionScope(m, isoCodes)
|
||||
}
|
||||
} else {
|
||||
// Family / language / prayer / engagement / adoption: keep all pins
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@
|
|||
"bundle": "doxa-research-map",
|
||||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"output": "dx-maps/doxa-research-map/doxa-research-map.js",
|
||||
"integrity": "sha384-SgOn8LQR6r32218+9dS9e9ewxB9qBtwCoVph4HLDkGsNCrX2fLf5drETWeO+HnoU",
|
||||
"integrity": "sha384-484w9lFNnAVr+yPbXIGMSP9DZ25gQ9lwdXC5mVig1WKxSTUnVsX0ARlgGZXQuoG9",
|
||||
"elements": [
|
||||
"doxa-research-map"
|
||||
],
|
||||
|
|
@ -395,7 +395,7 @@
|
|||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-research-map/research-map/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=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-SgOn8LQR6r32218+9dS9e9ewxB9qBtwCoVph4HLDkGsNCrX2fLf5drETWeO+HnoU\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
"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=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-484w9lFNnAVr+yPbXIGMSP9DZ25gQ9lwdXC5mVig1WKxSTUnVsX0ARlgGZXQuoG9\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
|
||||
<script src="../doxa-research-map.js" integrity="sha384-SgOn8LQR6r32218+9dS9e9ewxB9qBtwCoVph4HLDkGsNCrX2fLf5drETWeO+HnoU" crossorigin="anonymous"></script>
|
||||
<script src="../doxa-research-map.js" integrity="sha384-484w9lFNnAVr+yPbXIGMSP9DZ25gQ9lwdXC5mVig1WKxSTUnVsX0ARlgGZXQuoG9" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <doxa-research-map> custom element. -->
|
||||
<script src="../../doxa-research-map.js" integrity="sha384-SgOn8LQR6r32218+9dS9e9ewxB9qBtwCoVph4HLDkGsNCrX2fLf5drETWeO+HnoU" crossorigin="anonymous"></script>
|
||||
<script src="../../doxa-research-map.js" integrity="sha384-484w9lFNnAVr+yPbXIGMSP9DZ25gQ9lwdXC5mVig1WKxSTUnVsX0ARlgGZXQuoG9" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@
|
|||
"bundle": "doxa-research-map",
|
||||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"output": "dx-maps/doxa-research-map/doxa-research-map.js",
|
||||
"integrity": "sha384-SgOn8LQR6r32218+9dS9e9ewxB9qBtwCoVph4HLDkGsNCrX2fLf5drETWeO+HnoU",
|
||||
"integrity": "sha384-484w9lFNnAVr+yPbXIGMSP9DZ25gQ9lwdXC5mVig1WKxSTUnVsX0ARlgGZXQuoG9",
|
||||
"elements": [
|
||||
"doxa-research-map"
|
||||
],
|
||||
|
|
@ -395,7 +395,7 @@
|
|||
"scriptUrl": "./doxa-research-map/doxa-research-map.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./doxa-research-map/research-map/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=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-SgOn8LQR6r32218+9dS9e9ewxB9qBtwCoVph4HLDkGsNCrX2fLf5drETWeO+HnoU\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
"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=\"./doxa-research-map/doxa-research-map.js\" integrity=\"sha384-484w9lFNnAVr+yPbXIGMSP9DZ25gQ9lwdXC5mVig1WKxSTUnVsX0ARlgGZXQuoG9\" crossorigin=\"anonymous\"></script>\n<doxa-research-map profile-config='{\"profile\":\"research-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></doxa-research-map>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue