Skip to content

Bar chart

Compare amounts across periods with grouped or stacked bars and a plan line, with a marker for a period still in progress.

Revenue by month
WhenRevenue
April 2026€980
May 2026€1,150
June 2026€1,210
July 2026€1,040
August 2026€1,320
September 2026€1,260

<script setup lang="ts">import { UiBarChart, useUiT } from 'grani' const { n } = useUiT() const eur = (v: number) => n(v, { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }) const MONTHS = ['2026-04', '2026-05', '2026-06', '2026-07', '2026-08', '2026-09'] const REVENUE = [980, 1150, 1210, 1040, 1320, 1260]</script> <template>  <UiBarChart    :x="MONTHS"    :series="[{ key: 'revenue', label: 'Revenue', values: REVENUE }]"    :format="eur"    :highlight="5"    :legend="false"    ariaLabel="Revenue by month"  /></template>

Also called column chart, histogram.

Usage

<UiBarChart  :x="x"  :series="series"  :aria-label="ariaLabel"/>

With GraniResolver in the Vite config, a template needs no import: set it up once.

API

Name · typeDefaultDescription
Data
x*DateValue[]The periods: one date each, 2026-09 a month, 2026-09-24 a day; text that is not a date stays as it is.
series*BarSeries[]The series, in the order they take the chart colors, five at most; each is key, label and values.
Behavior
grainmonth | day | weekday | week= "month""month"What one period stands for: the labels and the tooltip read the dates by it; weekday names a day of one week, "Tue".
formatChartFormat= "number""number"How values read in the legend, the tooltip and the table; money writes the currency code after the digits, 1,234.00 USD. The axis prints compact figures without the unit.
yAxisboolean= truetrueThe value axis with its grid; off for a chart that only shows a shape.
legendboolean= truetrueThe legend with each series' total, a press shows one series alone.
highlightnumber | number[]The period in light, or several (the months that met a plan); the others go quiet.
stackboolean= falsefalseThe series stand one on another, the parts of a whole; without it they stand side by side.
labelsnone | value= "none""none"value prints the value over each period: the bar's, a stack's sum, or the tallest of bars side by side.
marks{ at: number; label: string; }[]= [][]Lines of reference across the plot, each at a value with a label: [{ at: 1100, label: 'Plan' }].
tooltipTotal{ label: string; of: string[]; }A sum of some series under them in the tooltip and the table: { label: 'Revenue', of: ['orders', 'events'] }.
partialboolean= falsefalseThe newest period with data is still going: its bar is hatched, its tooltip and table say so, and the empty periods after it are to come.
Look
heightnumber= 200200The height in pixels, the time axis included; the legend is below it.
Form and access
ariaLabel*stringWhat the chart shows, for a screen reader: "Revenue by month".

Anything else lands on the root element: native attributes, aria-*, data-testid.

When to use another component

When you needTake
A flow over timeArea chart
The parts of a whole at one momentDonut chart
A trend with no axes beside a numberSparkline bar
The card with its title, headline and data statesChart card around it