Education IQ
Embedded in Northwind CRM
N
Northwind CRM
Widget info
Widget info ยท developer handover

Metric Insight (Value Highlight)

One headline metric with its count qualifier, plus a lens ranking (home), cohort distribution and data-table view, switched by the footer toggle.

Live example

the Pupil Premium metric from VALUE_METRICS โ€” fully interactive, try the ๐Ÿ  / Distribution / Data toggle
Student Demographics +1.8pp

Pupil Premium Students

The percentage of pupils eligible for Pupil Premium funding โ€” a marker of a more disadvantaged intake.
39.4%99 of 251 students
Complexity rankingHigher = more challenging context. A higher percentile ranks this organisation nearer "More complex" within the comparison cohort.
64thpercentile

Higher = more challenging context.

Dependencies

Component: app/components/widgets/ValueHighlight.vue

Explicit imports

Imported at the top of the component.

  • LENSES โ€” ~/data/widgetsApp-level config: lens colour and the interpretation line ('Higher = more challenging context') shown on every view. Stays in the app โ€” not API data.
  • ValueMetric (type) โ€” ~/data/widgetsThe input contract โ€” the shape the API response must be mapped into.
  • SemanticColor, WidgetMode (types) โ€” ~/utils/typesColour-token union and the "desktop" | "distribution" | "data" mode union.
  • valenceColor, trendTone โ€” ~/utils/identityLens-aware colouring: variant mode colours by valence (good/bad), and the delta chip colours by whether the trend direction is favourable for this lens.

Auto-imported components (Nuxt)

No import lines โ€” Nuxt resolves these from app/components/widgets/parts/ (flat names, pathPrefix: false). A port to another stack must import them explicitly.

  • WidgetShell โ€” widgets/parts/WidgetShell.vueShared chrome: family header, definition tooltip, delta chip, and the home/Distribution/Data mode toggle in the footer.
  • Headline โ€” widgets/parts/Headline.vueThe big value plus its qualifier โ€” renders "99 of 251 students" (or a per-pupil figure) beside the headline.
  • RankingPanel โ€” widgets/parts/RankingPanel.vueHome view: the tinted '64th percentile' lens ranking panel.
  • PercentileLine โ€” widgets/parts/PercentileLine.vueDistribution view: the percentile read-out line above the histogram.
  • Histogram โ€” widgets/parts/Histogram.vueDistribution view: the cohort distribution bars with this organisation's position marked.
  • DataGrid โ€” widgets/parts/DataGrid.vueData view: the cohort / value / percentile table (also renders the interpretation line on that view).

Framework APIs

Auto-imported by Nuxt; from 'vue' in a plain Vue build.

  • ref, computed โ€” vueInternal state only โ€” the active mode and the resolved comparison cohort. None of it needs the API.

Input contract โ€” metric: ValueMetric

Defined in app/data/widgets.ts. The API response for this widget maps to exactly this shape.

FieldTypeNotes
idstringStable id so a page-config slot can reference this metric.
namestringWidget title, e.g. "Pupil Premium Students".
familyFamilyKeyData family ("demographics", "financial"โ€ฆ) โ€” drives the header identity and colours.
lensLensKeyHow to read a high value ("complexity", "success"โ€ฆ) โ€” drives the ranking colour, interpretation line and trend valence.
definitionstringPlain-English definition shown in the header tooltip.
valuestringThe headline figure, pre-formatted: "39.4%", "ยฃ7.42m", "+0.31".
qualifierstring?Count-of-cohort sub-text beside the value, per client feedback: "99 of 251 students", "6 of 54 staff". The first token renders emphasised.
perPupilstring?Alternative qualifier for money metrics โ€” renders as "ยฃ6.84k / pupil". Takes precedence over qualifier.
trend"up" | "down" | "flat"Direction of travel โ€” the arrow in the header chip.
deltastringFormatted change, e.g. "+1.8pp". Coloured by whether the direction is favourable for the lens.
neighbourhoods[].keystringCohort key, e.g. "national-all" โ€” matched against the page's section-level cohort filter.
neighbourhoods[].labelstringCohort label, e.g. "National ยท All schools".
neighbourhoods[].percentilenumberThis organisation's percentile within that cohort (0โ€“100) โ€” drives the ranking panel, distribution marker and data table.
neighbourhoods[].distnumber[]The cohort's distribution as 10 bucket weights (relative heights, any scale) for the histogram.

Props & events

PropTypeNotes
metricValueMetricThe payload (required) โ€” see the contract.
neighbourhoodstring?Key of the cohort to show, usually from a section-level "Compared with" filter shared by every widget in the row. Defaults to the metric's first neighbourhood.
advancedboolean?Default true. False = the simplified card: headline only, no ranking panel, no mode toggle.
variantboolean?Default false. True = hide the lens identity and colour by valence instead (used in the Widget Lab's simplified row).
drillableboolean?Default false. Marks the widget as having a drill-through; it emits "drill" when triggered. (The footer "More" link was removed per client feedback, so currently nothing triggers it.)

Wiring it to the API

  • Replace the mock payload โ€” the widget takes one `metric: ValueMetric` prop. In the prototype it's fed from VALUE_METRICS in ~/data/widgets.ts; the API should return one ValueMetric object per card.
  • All figures arrive pre-formatted as strings (value "39.4%", delta "+1.8pp", qualifier "99 of 251 students") โ€” the component renders them verbatim and never parses them. Formatting is the API/mapping layer's job.
  • neighbourhoods carries one entry per comparison cohort, each with the organisation's percentile and the cohort's 10-bucket distribution. The three views (ranking, distribution, data) are all derived client-side from this one array โ€” no further API calls after load.
  • The neighbourhood prop selects which cohort is displayed; pages share one section-level filter across a row of these widgets, so the API should return the same cohort keys for every metric on a page.
  • LENSES is app configuration, not API data โ€” the payload only names its family and lens keys.
  • The widget emits a single optional "drill" event (only when drillable is set); there is currently no visible trigger for it.