elements
Demos UI Feed Discuss Install
Style System
  • Style
  • Themes
  • Behaviors
Forms
  • Button
  • ButtonGroup
  • Checkbox
  • ColorPicker
  • Combobox
  • Field
  • FileUpload
  • Input
  • InputGroup
  • InputOTP
  • Label
  • NativeSelect
  • NumberInput
  • PasswordInput
  • RadioGroup
  • Select
  • Slider
  • Switch
  • TagsInput
  • Textarea
  • Toggle
  • ToggleGroup
Overlays
  • AlertDialog
  • Command
  • ContextMenu
  • Dialog
  • Drawer
  • DropdownMenu
  • HoverCard
  • Menubar
  • NavigationMenu
  • Popover
  • Sheet
  • Toast
  • Tooltip
Display
  • Accordion
  • Alert
  • AspectRatio
  • Avatar
  • Badge
  • Breadcrumb
  • Card
  • Collapsible
  • Empty
  • Item
  • Kbd
  • Pagination
  • Progress
  • Separator
  • Skeleton
  • Spinner
  • Table
  • Tabs
  • Tree
Layout
  • Carousel
  • Resizable
  • ScrollArea
  • Sidebar
Dates
  • Calendar
  • DatePicker
  • DateRangePicker
  • TimePicker
Data
  • AreaChart
  • BarChart
  • Chart
  • DataTable
  • Kanban
  • LineChart
  • PieChart
  • RadarChart
  • RadialChart
  • VirtualList
Chat
  • Attachment
  • Message
  • MessageList
  • PromptInput
Elements UI / Data / BarChart

BarChart

Vertical, horizontal, stacked and grouped bars with tooltip, legend and labels.

Default

One series, rounded bars, a tooltip with no heading and no cursor.

Bar Chart

January - June 2024

JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
Trending up by 5.2% this month
Showing total visitors for the last 6 months
Code
<BarChart data={rows} config={{ desktop: { label: "Desktop", color: "var(--chart-1)" } }}
          x="month" radius={8}
          categoryAxis={{ tickFormatter: (v) => String(v).slice(0, 3) }}
          tooltip={{ hideLabel: true, cursor: false }} />

Usage

import { BarChart } from "@elements/ui/chart-bar";
import type { ChartConfig } from "@elements/ui/chart";

const config: ChartConfig = {
  desktop: { label: "Desktop", color: "var(--chart-1)" },
  mobile: { label: "Mobile", color: "var(--chart-2)" },
};

<BarChart data={rows} {config} x="month" />
<BarChart data={rows} {config} x="month" stack="normal" legend />
<BarChart data={rows} {config} x="month" orientation="horizontal" labels />

Examples

Horizontal

orientation=horizontal puts the categories down the side.

Bar Chart - Horizontal

January - June 2024

JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
Code
<BarChart data={rows} {config} x="month" series={["desktop"]}
          orientation="horizontal" radius={5} margin={{ left: -20 }}
          categoryAxis={{ tickFormatter: (v) => String(v).slice(0, 3) }}
          tooltip={{ hideLabel: true }} />

Multiple

Every series in the config, side by side in each band, with a dashed tooltip indicator.

Bar Chart - Multiple

January - June 2024

JanFebMarAprMayJun
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<BarChart data={rows} {config} x="month" radius={4}
          categoryAxis={{ tickFormatter: (v) => String(v).slice(0, 3) }}
          tooltip={{ indicator: "dashed" }} />

Stacked and legend

stack=normal stacks the series; only the outer ends of a stack are rounded.

Bar Chart - Stacked + Legend

January - June 2024

JanFebMarAprMayJun
  • Desktop
  • Mobile
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<BarChart data={rows} {config} x="month" stack="normal" legend
          categoryAxis={{ tickFormatter: (v) => String(v).slice(0, 3) }} />

Label

A value label above each bar; the top margin leaves room for it.

Bar Chart - Label

January - June 2024

JanFebMarAprMayJun18630523773209214
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
Code
<BarChart data={rows} {config} x="month" series={["desktop"]} radius={8}
          margin={{ top: 20 }} labels={{ position: "top" }}
          tooltip={{ hideLabel: true }} />

Custom label

Two label lists: the month inside each bar and the value past its end.

Bar Chart - Custom Label

January - June 2024

January186February305March237April73May209June214
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
Code
<BarChart data={rows} {config} x="month" orientation="horizontal" radius={4}
          categoryAxis={false} margin={{ right: 16 }}
          labels={[
            { key: "month", position: "insideLeft", series: "desktop", offset: 8, color: "var(--bg)" },
            { position: "right", series: "desktop", offset: 8, color: "var(--ink)" },
          ]}
          series={["desktop"]} tooltip={{ indicator: "line" }} />

Mixed

Each row carries its own fill, so every bar takes its browser's color.

Bar Chart - Mixed

January - June 2024

ChromeSafariFirefoxEdgeOther
Bar chart
BrowserVisitors
Chrome275
Safari200
Firefox187
Edge173
Other90
Code
<!-- each row's fill picks its color: fill: "var(--color-chrome)" -->
<BarChart data={browsers} config={browserConfig} x="browser" orientation="horizontal"
          radius={5} margin={{ left: 0 }}
          categoryAxis={{ tickFormatter: (v) => browserConfig[String(v)].label }}
          tooltip={{ hideLabel: true }} />

Active

active marks one bar (two-way: hover moves it, leaving restores it); activeBar outlines it.

Bar Chart - Active

January - June 2024

ChromeSafariFirefoxEdgeOther
Visitors
187
Bar chart
BrowserVisitors
Chrome275
Safari200
Firefox187
Edge173
Other90
Code
<BarChart data={browsers} config={browserConfig} x="browser" radius={8}
          active={2} activeBar
          categoryAxis={{ tickFormatter: (v) => browserConfig[String(v)].label }}
          tooltip={{ hideLabel: true, cursor: false }} />

Negative

Negative values hang below the zero line; each row's fill picks its color by sign.

Bar Chart - Negative

January - June 2024

JanuaryFebruaryMarchAprilMayJune
Bar chart
MonthVisitors
January186
February205
March-207
April173
May-209
June214
Code
<!-- fill per row: rows.map((r) => ({ ...r, fill: r.visitors > 0 ? "var(--chart-1)" : "var(--chart-2)" })) -->
<BarChart data={rows} config={{ visitors: { label: "Visitors" } }} x="month"
          categoryAxis={false}
          labels={{ key: "month", position: "top" }}
          tooltip={{ hideLabel: true, hideIndicator: true, cursor: false }} />

Interactive

The header switches the series. 91 bars: ticks skip so their labels never overlap.

Bar Chart - Interactive

Showing total visitors for the last 3 months

Apr 3Apr 14Apr 25May 6May 17May 28Jun 8Jun 30
Bar chart
DateDesktop
2024-04-01286
2024-04-02136
2024-04-03267
2024-04-04121
2024-04-05326
2024-04-06204
2024-04-07353
2024-04-08289
2024-04-09359
2024-04-10314
2024-04-11160
2024-04-12466
2024-04-13138
2024-04-14472
2024-04-15258
2024-04-16359
2024-04-17158
2024-04-18268
2024-04-19309
2024-04-20151
2024-04-21231
2024-04-22122
2024-04-23185
2024-04-24278
2024-04-25331
2024-04-26394
2024-04-27144
2024-04-28270
2024-04-29109
2024-04-30362
2024-05-01472
2024-05-02265
2024-05-03266
2024-05-04270
2024-05-05196
2024-05-06387
2024-05-07198
2024-05-08433
2024-05-09461
2024-05-10389
2024-05-11312
2024-05-12219
2024-05-13176
2024-05-14364
2024-05-15197
2024-05-1693
2024-05-17324
2024-05-18126
2024-05-19273
2024-05-20325
2024-05-21140
2024-05-22449
2024-05-23100
2024-05-24373
2024-05-25354
2024-05-26182
2024-05-27157
2024-05-28123
2024-05-29305
2024-05-30427
2024-05-31288
2024-06-01202
2024-06-02116
2024-06-03182
2024-06-04406
2024-06-05156
2024-06-06340
2024-06-07251
2024-06-08281
2024-06-0993
2024-06-10271
2024-06-11225
2024-06-12377
2024-06-13197
2024-06-14121
2024-06-15123
2024-06-16165
2024-06-17102
2024-06-18266
2024-06-19306
2024-06-20301
2024-06-21138
2024-06-22355
2024-06-23453
2024-06-24273
2024-06-25444
2024-06-26289
2024-06-27405
2024-06-28308
2024-06-29344
2024-06-30266
Code
<button e:for={key of ["desktop", "mobile"]} data-active={state.series === key}
        onclick={() => state.series = key}>...</button>

<BarChart data={daily} config={dailyConfig} x="date" series={[state.series]}
          class="chart-demo-wide" margin={{ left: 12, right: 12 }}
          categoryAxis={{ tickFormatter: shortDate, minTickGap: 32 }}
          tooltip={{ nameKey: "views", labelFormatter: (_, row) => longDate(row.date) }} />

Expanded stack

stack=expand stacks each band to 100%; the value axis reads the share.

JanFebMarAprMayJun0%25%50%75%100%
  • Desktop
  • Mobile
  • Other
Bar chart
MonthDesktopMobileOther
January1868045
February305200100
March237120150
April7319050
May209130100
June214140160
Code
<BarChart data={rows} config={{ desktop, mobile, other }} x="month"
          stack="expand" legend valueAxis={{ tickFormatter: (v) => `${Number(v) * 100}%` }} />

Legend toggles

legend toggle makes each legend item a button; hidden is two-way.

JanFebMarAprMayJun
Bar chart
MonthDesktopMobileOther
January1868045
February305200100
March237120150
April7319050
May209130100
June214140160
hidden: none
Code
<BarChart data={rows} {config} x="month" legend={{ toggle: true }}
          hidden={state.hidden} />

Axes and grid

A value axis with its own tick count, tick marks and axis lines, and a full grid.

JanFebMarAprMayJun0150300450
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<BarChart data={rows} {config} x="month"
          valueAxis={{ tickCount: 4, tickFormatter: (v) => `${v}` , axisLine: true }}
          categoryAxis={{ tickLine: true, axisLine: true, tickFormatter: (v) => String(v).slice(0, 3) }}
          grid={{ horizontal: true, vertical: true }} />

Background and tiny values

background draws a track behind each bar; barSize fixes the bar width; minPointSize keeps a near-zero bar visible; animate=false draws at once.

MonTueWedThuFri0255075100
Bar chart
DayGoal
Mon80
Tue0.2
Wed64
Thu92
Fri40
Code
<BarChart data={rows} config={{ goal: { label: "Goal" } }} x="day" radius={8} barSize={28}
          background minPointSize={4} animate={false} categoryAxis={false} grid={false} />

Sign stack, thin bars and margins

stack=sign stacks positives up from zero and negatives down; maxBarSize caps the bar width; margin and tickMargin move the plot and its labels.

JanFebMarAprMayJun
  • Income
  • Refunds
  • Fees
Bar chart
MonthIncomeRefundsFees
January186-40-22
February305-62-30
March237-18-26
April173-90-21
May209-35-28
June214-51-24
Code
<!-- stack="sign": positives stack up from zero, negatives down -->
<BarChart data={rows} {config} x="month" stack="sign" maxBarSize={16}
          margin={{ top: 24, left: 24 }} categoryAxis={{ tickMargin: 20 }} />

Controlled and keyboard

Tab to the chart; arrows move the active bar, Home and End jump, Escape hides the tooltip.

JanFebMarAprMayJun
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
active: -1 changes: 0 clicked: -1
Code
<BarChart data={rows} {config} x="month" active={state.active}
          activeBar onActiveChange={() => state.changes++}
          onItemClick={(i) => state.clicked = i} />

Two axes each way

A right value axis scales mobile alone; a top category axis shows desktop's share of each month.

JanFebMarAprMayJun70%60%66%28%62%60%080160240320050100150200
  • Desktop
  • Mobile
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<!-- mobile on its own axis on the right; a second category axis on top shows the share of desktop -->
<BarChart data={rows} {config} x="month"
          categoryAxis={[{ tickFormatter: shortMonth }, { orientation: "top", key: "share", tickFormatter: (v) => `${v}%` }]}
          valueAxis={[{}, { orientation: "right", series: ["mobile"] }]} />

Silhouette stack

stack silhouette centers each month's stack on zero.

JanFebMarAprMayJun-300-1500150300
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<!-- each month's stack centered on zero -->
<BarChart data={rows} {config} x="month" stack="silhouette" valueAxis />

Tooltip on click

tooltip trigger click: a click on a month shows its tooltip and it stays; a click elsewhere hides it.

JanFebMarAprMayJun
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<!-- a click shows the tooltip and keeps it; hover alone does nothing -->
<BarChart data={rows} {config} x="month" tooltip={{ trigger: "click" }} />

A series left out of the tooltip

tooltipType none on a config entry draws the series and keeps it in the legend, but leaves it out of the tooltip and its announcement.

JanFebMarAprMayJun
  • Desktop
  • Mobile
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<!-- mobile is drawn and in the legend, but not in the tooltip -->
<BarChart data={rows} x="month" legend config={{
  desktop: { label: "Desktop", color: "var(--chart-1)" },
  mobile: { label: "Mobile", color: "var(--chart-2)", tooltipType: "none" },
}} />

Reverse stack order

reverseStackOrder stacks the last series first, so the first sits on top; the legend and tooltip keep series order.

JanFebMarAprMayJun
  • Desktop
  • Mobile
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<!-- desktop stacks on top; legend and tooltip keep series order -->
<BarChart data={rows} {config} x="month" stack="normal" reverseStackOrder legend />

Animation timing

animation sets when the marks start moving, how long they take and their easing: a CSS easing name, a cubic-bezier, spring, or a function of progress.

JanFebMarAprMayJun
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<!-- wait 150ms, then take 900ms to enter or move to new data -->
<BarChart data={rows} {config} x="month"
          animation={{ begin: 150, duration: 900, easing: "linear" }} />

Legend and tooltip types

legendType on a config entry sets that series' legend icon, and none leaves a drawn series out of the legend; tooltipType none leaves it out of the tooltip.

JanFebMarAprMayJun
  • Desktop
  • Mobile
Bar chart
MonthDesktopMobileOther
January1868045
February305200100
March237120150
April7319050
May209130100
June214140160
Code
<!-- desktop's legend icon is a line; mobile is left out of the tooltip, other out of the legend -->
<BarChart data={rows} x="month" legend config={{
  desktop: { label: "Desktop", color: "var(--chart-1)", legendType: "line" },
  mobile: { label: "Mobile", color: "var(--chart-2)", tooltipType: "none" },
  other: { label: "Other", color: "var(--chart-3)", legendType: "none" },
}} />

Data table

Every chart carries its data as a table for screen readers; showTable shows it.

JanFebMarAprMayJun
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
Code
<BarChart data={rows} {config} x="month" showTable={state.table} />

Axis options

Each chart sets one option of the value or category axis: reversed, angle, label, unit, ticks, allowDecimals, interval, mirror, tickSize, tick, allowDataOverflow, niceTicks, size, hide, includeHidden and allowDuplicatedCategory.

valueAxis reversed
JanuaryFebruaryMarchAprilMayJune080160240320
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
categoryAxis reversed
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
categoryAxis angle -45
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
axis label
JanFebMarAprMayJunMonth080160240320Visitors
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
valueAxis unit
JanFebMarAprMayJun0k80k160k240k320k
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
valueAxis ticks
JanFebMarAprMayJun0100250
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
valueAxis allowDecimals false
JanuaryFebruaryMarch0123456
Bar chart
MonthDesktop
January1
February3
March2
categoryAxis interval 1
JanuaryMarchMay
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
valueAxis mirror
JanFebMarAprMayJun080160240320
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
categoryAxis tickSize 12
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
categoryAxis tick false
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
valueAxis allowDataOverflow
JanFebMarAprMayJun050100150200
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
valueAxis niceTicks none
JanFebMarAprMayJun076.25152.5228.75305
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
axis size
JanFebMarAprMayJun080160240320
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
valueAxis hide
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
valueAxis includeHidden
JanFebMarAprMayJun080160240320
Bar chart
MonthDesktopMobile
January18680
February305200
March237120
April73190
May209130
June214140
categoryAxis allowDuplicatedCategory false
JanuaryFebruary
Bar chart
MonthDesktop
January186
January100
February305
Code
<!-- category and value axis options, one per chart -->
<BarChart data={rows} {config} x="month" series={["desktop"]} valueAxis={{ reversed: true }} />
<BarChart ... categoryAxis={{ reversed: true }} />
<BarChart ... categoryAxis={{ angle: -45, size: 60, tickFormatter: shortMonth }} />
<BarChart ... valueAxis={{ label: "Visitors" }} categoryAxis={{ label: "Month" }} />
<BarChart ... valueAxis={{ unit: "k" }} />
<BarChart ... valueAxis={{ ticks: [0, 100, 250] }} />
<BarChart data={counts} ... valueAxis={{ allowDecimals: false, tickCount: 7 }} />
<BarChart ... categoryAxis={{ interval: 1 }} />
<BarChart ... valueAxis={{ mirror: true }} />
<BarChart ... categoryAxis={{ tickLine: true, tickSize: 12 }} />
<BarChart ... categoryAxis={{ tick: false, axisLine: true }} />
<BarChart ... valueAxis={{ domain: [0, 200], allowDataOverflow: true }} />
<BarChart ... valueAxis={{ domain: [0, "dataMax"], niceTicks: "none" }} />
<BarChart ... valueAxis={{ size: 80 }} categoryAxis={{ size: 50 }} />
<BarChart ... valueAxis={{ hide: true, domain: [0, 600] }} />
<BarChart ... series={["desktop", "mobile"]} legend={{ toggle: true }} valueAxis={{ includeHidden: true }} />
<BarChart data={duplicates} ... categoryAxis={{ allowDuplicatedCategory: false }} />

Grid options

Dashed lines, a background fill, stripes between the lines, lines at given values or pixels, and lines kept to the axis ticks.

grid strokeDasharray
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
grid fill
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
grid horizontalFill, verticalFill
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
grid horizontalValues
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
grid horizontalPoints, verticalPoints
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
grid syncWithTicks
JanFebMarAprMayJun0150300
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
Code
<!-- grid options -->
<BarChart ... grid={{ strokeDasharray: "3 3" }} />
<BarChart ... grid={{ fill: "var(--bg-muted)", fillOpacity: 0.5 }} />
<BarChart ... grid={{ horizontalFill: ["var(--bg-muted)", "transparent"],
                      vertical: true, verticalFill: ["var(--bg-muted)", "transparent"] }} />
<BarChart ... grid={{ horizontalValues: [100, 200] }} />
<BarChart ... grid={{ horizontalPoints: [40, 80], vertical: true, verticalPoints: [100] }} />
<BarChart ... valueAxis={{ ticks: [0, 150, 300] }} grid={{ syncWithTicks: true }} />

Moving to new data

animation matchBy pairs old and new bars by a key, so each month slides to its new place and the one that leaves fades; interpolate draws every frame with a function of your own, here one that grows each bar from its base.

JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
JanFebMarAprMayJun
Bar chart
MonthDesktop
January186
February305
March237
April73
May209
June214
Code
<!-- each month keeps its bar: the window slides -->
<BarChart data={rows} {config} x="month" animation={{ matchBy: matchByDataKey("month") }} />
<!-- (items, t) => the bars to draw: each grows from its base -->
<BarChart data={rows} {config} x="month" animation={{ interpolate: growBars }} />
Reference BarChart in the manual Every part, attribute, slot, key and data attribute.
Prev AreaChartNext Chart
Product
Manual Pricing Compare
Company
History Contact
Legal
Privacy Policy Acceptable Use Terms License Agreement
© Elements Dev Corporation 2026