Metric
A single SQL-driven key figure: a label, a value, and an optional delta. Measured in the browser, so every number is live.
Total flowers…
<Metric label="Total flowers" data="db.iris" value="count(*)" />Format the value
valueFormat takes a d3-format spec, or a function when the spec language can't express it.
Avg petal length…
<Metric
label="Avg petal length"
data="db.iris"
value="avg(petal_length)"
valueFormat="{.2f} cm"
/>Filters and a delta
filters compose a WHERE before the measure. A delta adds a second figure beneath the value. Positive is a green ▲, negative a red ▼.
Setosa……
Virginica……
<Columns cols={2}>
<Metric
label="Setosa"
data="db.iris"
value="count(*)"
filters={[{ column: "species", operator: "=", value: "setosa" }]}
delta="12.4"
deltaFormat="{.1f}% vs last run"
/>
<Metric
label="Virginica"
data="db.iris"
value="count(*)"
filters={[{ column: "species", operator: "=", value: "virginica" }]}
delta="-8.3"
deltaFormat="{.1f}% vs last run"
/>
</Columns>The query escape hatch
For what the measure model can't express, pass a full query: its first scalar is the value.
Petal : sepal ratio…
<Metric
label="Petal : sepal ratio"
query="SELECT avg(petal_length) / avg(sepal_length) FROM db.iris"
valueFormat="{.2f}"
/>Props
| Prop | Type | Notes |
|---|---|---|
label | string | Plain text, not interpolated. |
data | relation | Relation the value is measured from; use query for full SQL. |
query | string | Full SQL whose first scalar is the value; mutually exclusive with data. |
value | SQL expr | Measure over the source, e.g. sum(amount). |
filters | Filter[] | { column, operator, value } predicates ANDed into a WHERE. |
valueFormat | d3-format spec | (v) => string | How the value renders. |
delta | measure | SELECT | Second figure below the value, resolved independently. |
deltaFormat | d3-format spec | (v) => string | How the delta renders. |
render | (ctx) => ReactNode | Escape hatch: draw the value area yourself; label + delta still wrap it. |
Expressions in value, query, and filters values support {{binding}} interpolation against the surrounding BindingProvider.
Installation
Metric ships in @n6k.io/ui/components. Nothing to install. Register the namespace once in src/app/mdx-components.tsx and the tag resolves in both .mdx and page.py pages:
import * as n6k from "@n6k.io/ui/components";
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...n6k, // Metric, and every other n6k component
...components,
} as unknown as MDXComponents;
}