Delta
See how much a value changed as a signed percentage, and whether the change is for the better.
Spending
-9.5%, bettervs August
€3,640
in September
| When | Spent |
|---|---|
| October 2025 | €3,420 |
| November 2025 | €3,610 |
| December 2025 | €4,280 |
| January 2026 | €3,180 |
| February 2026 | €3,050 |
| March 2026 | €3,390 |
| April 2026 | €3,520 |
| May 2026 | €3,710 |
| June 2026 | €3,460 |
| July 2026 | €3,890 |
| August 2026 | €4,020 |
| September 2026 | €3,640 |
<script setup lang="ts">import { computed, ref } from 'vue'import { UiChartCard, UiDelta, UiAreaChart, UiRadioGroup, UiRadio, useUiT } from 'grani' const { n } = useUiT() const eur = (v: number) => n(v, { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }) const MONTHS = [ '2025-10', '2025-11', '2025-12', '2026-01', '2026-02', '2026-03', '2026-04', '2026-05', '2026-06', '2026-07', '2026-08', '2026-09',] const BEFORE = [3420, 3610, 4280, 3180, 3050, 3390, 3520, 3710, 3460, 3890, 4020] // Spending: lower is better, so a fall is success and a rise danger (`invert`).const SEPTEMBER = { fell: 3640, rose: 4380, flat: 4021, first: 3640 } as const const state = ref<keyof typeof SEPTEMBER>('fell') const current = computed(() => SEPTEMBER[state.value]) const previous = computed(() => (state.value === 'first' ? null : BEFORE[10]!)) const series = computed(() => [ { key: 'spent', label: 'Spent', values: [...BEFORE, current.value], variant: 'line' as const },])</script> <template> <div class="flex w-full flex-col items-center gap-4"> <UiChartCard title="Spending" :value="current" caption="in September" :format="eur" class="w-full max-w-lg" > <template #actions> <UiDelta :current="current" :previous="previous" invert label="vs August" /> </template> <UiAreaChart :x="MONTHS" :series="series" :format="eur" :y-axis="false" :legend="false" :height="140" ariaLabel="Spending by month" /> </UiChartCard> <UiRadioGroup v-model="state" variant="segmented" aria-label="September against August"> <UiRadio value="fell">Less</UiRadio> <UiRadio value="rose">More</UiRadio> <UiRadio value="flat">No change</UiRadio> <UiRadio value="first">Nothing to compare</UiRadio> </UiRadioGroup> </div></template>
Also called trend indicator, change indicator, percent change.
Usage
<UiDelta :current="current" /> With GraniResolver in the Vite config, a template needs no import: set it up once.
API
| Name · type | Default | Description |
|---|---|---|
| current*number | The value now. | |
| previousnumber | null= null | null | The value it is compared with; null, missing, zero or not finite draws nothing. |
| invertboolean= false | false | Lower is better: a fall is success, growth danger. |
| labelstring= "" | "" | What it is compared with, shown after the badge: "vs August". A screen reader reads it as text after the verdict. |
| sizesm | md= "sm" | "sm" | sm on a chart card's title line, in a row or a cell; md beside a larger heading. |
Anything else lands on the root element: native attributes, aria-*, data-testid.