Loopfour
Dashboards

Dashboard Components

The components every dashboard, chat chart, and share page renders, and the settings that control them.

Every dashboard widget, every chart the copilot draws in chat, and every public share page render through one component library. A widget stores a JSON spec that lists components and binds each figure to a query on one of your tables. The copilot writes the spec for you; you can also edit it as JSON.

There is no visual settings panel. Ask the copilot ("show negatives in brackets", "make the chart taller") or edit the widget JSON.

Components

ComponentUse it for
MetricA KPI tile: value, delta against a comparison period, optional sparkline and target bar
BarChartComparisons by category or period; stacked, horizontal, or signed (negatives below zero)
LineChartTrends over time, with comparison, budget, and forecast series
AreaChartCumulative or stacked trends over time
ComboChartBars and lines on one chart, with an optional right axis
PieChartShare of a total, as a donut with at most 5 slices plus Other
BarListRankings: top customers, vendors, or spend categories
WaterfallChartBridges: MRR movements, cash bridge, budget-to-actual walk
DataTableRow-level tables and statement layouts with subtotals and totals
PivotTableCross-tabs with row groups, subtotals, and totals
VarianceTableBudget vs actual with variance and variance percent
CohortHeatmapRetention or revenue by cohort and period
DateRangeFilterPeriod presets (MTD, QTD, YTD, fiscal) and a compare toggle
SearchInput, SelectFilters that other components read
Stack, Grid, Card, Heading, Text, Badge, Callout, ButtonLayout and text

Every titled figure has the same header:

  • Title, with an info icon when definition is set.
  • One muted line: period, currency, and basis (for example Jan–Sep 2026 · USD · Accrual), plus the comparison period when compare is on.
  • as of HH:MM for the last load, and a Stale chip when the figure shows the last good result after a failed load.
  • Actions: Export CSV, and Open data (not shown on public share pages).

Header props: subtitle, definition, basis, showAsOf, actions (export, open).

Number formats

A format is a legacy string (currency, compact_currency, percent, number) or an object:

FieldValues
kindcurrency, percent, pp, number, integer, months, days, ratio
currencyISO-4217 code, for example EUR
scaleauto ($1.24M), none (exact), thousands, millions, billions
decimals0 to 4
negativeminus (-$1,200) or parentheses (($1,200))
signDisplayauto or always

Missing values show —. A percent change on a zero base shows N/M. KPI tiles and chart axes use compact scale; tables show exact values.

Colors

Specs name color tokens, never hex values:

  • Series: series-1 to series-8 (chart-1 to chart-5 still work).
  • Status: positive, negative, neutral, warning. Use these for deltas, variances, and thresholds. A series can use them only with role: 'variance'.
  • Roles: compare (gray, dashed) and forecast (dashed after the forecast start).

thresholds color a value when it matches a rule: { op: 'lt'|'lte'|'gt'|'gte'|'between', value, value2?, color, label? }, at most 8.

Dashboard settings

Each dashboard has one set of display defaults. A component format overrides them field by field.

SettingValuesDefault
localeBCP-47 tag, for example en-GBen-US
currencyISO-4217 codeUSD
negativeminus or parenthesesminus
fiscalYearStartMonth1 to 121
densitycompact or comfortablecompact

The currency setting changes display only. It does not convert amounts.

A published dashboard shows live data to anyone with the link. The public page does not receive table IDs, filter values, or queries. Each figure asks the server for its data by widget, and the server runs only the queries stored in that widget. Results are cached for 60 seconds, and the page refreshes every 5 minutes. Revoking the link stops all public loads.

Adding a component

For contributors adding a component to the library:

  1. Add the props schema and description to the catalog group in packages/json-render/src/schemas/components/, and register it in catalog.ts. Reuse the shared settings vocabulary (numberFormat, colorToken, thresholds, header props) instead of new enums.
  2. List any prop that holds data in FIGURE_PROPS (check.ts) so specs with static figures are rejected, and add lint rules in lint.ts when the component has usage rules.
  3. Add the Studio component under packages/json-render/src/react/components/ and register it in registry.tsx. Use Panel, EmptyState, LoadError, and the format context so headers, states, and numbers stay consistent.
  4. Add a rule to the catalog prompt (prompt.ts) only when the model needs guidance, and keep the prompt-budget test green.
  5. Add table-driven tests for the schema, lint rules, and component.

On this page