web: reach-over-time chart with playhead, slice 5 of M3

Hand-rolled SVG as decided: dashed percent grid, one cumulative curve
per panel in its accent color, end labels via the shared formatPct, and
a playhead line with per-curve dots synced to the global round. The
cumulative-at-round counting moved into lib/reach.ts so the panel stats
and the chart cannot disagree.
This commit is contained in:
Justin Visser 2026-06-10 17:39:21 +02:00
parent e9d57b2082
commit da1d86aba7
4 changed files with 191 additions and 4 deletions

View file

@ -3,6 +3,7 @@ import { computed } from 'vue'
import NetworkView from './NetworkView.vue'
import { useSimStore } from '@/composables/useSimStore'
import { roundPct } from '@/lib/format'
import { reachedCountAtRound } from '@/lib/reach'
import type { PanelSpec } from '@/presets/types'
const props = defineProps<{ panel: PanelSpec; accent: string }>()
@ -16,10 +17,7 @@ const numStudents = computed(() => store.effectiveConfig(props.panel).numStudent
// shows at the current round, reaching the final outcome on the last one.
const reachedCount = computed(() => {
const panelResult = result.value
if (!panelResult) return 0
return panelResult.reachedAtRound.filter(
(reachedAt) => reachedAt >= 0 && reachedAt <= store.state.round,
).length
return panelResult ? reachedCountAtRound(panelResult.reachedAtRound, store.state.round) : 0
})
const reachedPctNow = computed(() => (reachedCount.value / numStudents.value) * 100)
const tone = computed(() =>