The BarChart component displays categorical data as vertical or horizontal bars. As a strong chart type for Vue charts, it supports grouped, stacked, and combined layouts for flexible data visualization in Nuxt and Vue projects. Examples ↗
<script lang="ts" setup>
defineOptions({
tags: ["barcharts", "vertical"],
});
withDefaults(
defineProps<{
showTitle?: boolean;
}>(),
{
showTitle: false,
},
);
const RevenueData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
];
const RevenueCategories = computed(() => ({
desktop: {
name: "Desktop",
color: "#22c55e",
},
}));
const xFormatter = (i: number): string => `${RevenueData[i]?.month}`;
const yFormatter = (tick: number) => tick.toString();
</script>
<template>
<div
class="mx-auto max-w-3xl space-y-6 rounded-lg"
:class="showTitle ? 'p-6' : ''"
>
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold">Bar Chart</h3>
<NuxtLink to="/blocks/bar-charts">
<UButton
icon="i-lucide-copy"
size="sm"
variant="soft"
color="neutral"
/>
</NuxtLink>
</div>
<BarChart
:data="RevenueData"
:height="300"
:categories="RevenueCategories"
:y-axis="['desktop']"
:x-num-ticks="6"
:radius="4"
:y-grid-line="true"
:x-formatter="xFormatter"
:y-formatter="yFormatter"
:legend-position="LegendPosition.TopRight"
:hide-legend="false"
/>
</div>
</template>
Use the new variant prop to switch from solid bars to built-in treatments such as hatched, gradient, duotone, stripped, or cubes.
<script lang="ts" setup>
defineOptions({
tags: ["barcharts", "stackedhorizontal"],
});
const RevenueData = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
];
const RevenueCategoriesMultple = {
desktop: { name: "Desktop", color: "#3b82f6" },
mobile: { name: "Mobile", color: "#22c55e" },
};
const yFormatter = (i: number): string => `${RevenueData[i]?.month}`;
</script>
<template>
<BarChart
:data="RevenueData"
:stacked="true"
:height="300"
:categories="RevenueCategoriesMultple"
variant="hatched"
:y-axis="['desktop', 'mobile']"
:group-padding="0"
:bar-padding="0.2"
:x-num-ticks="6"
:radius="4"
:orientation="Orientation.Horizontal"
:x-formatter="(i) => i"
:y-formatter="yFormatter"
:legend-position="LegendPosition.TopRight"
:hide-legend="false"
:x-grid-line="true"
/>
</template>
<script lang="ts" setup>
defineOptions({
tags: ["barcharts", "group"],
});
withDefaults(
defineProps<{
showTitle?: boolean;
}>(),
{
showTitle: false,
},
);
type RevenueDataItem = {
month: string;
desktop: number;
mobile: number;
};
const RevenueData: RevenueDataItem[] = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
];
const RevenueCategoriesMultple = {
desktop: { name: "Desktop", color: "#3b82f6" },
mobile: { name: "Mobile", color: "#22c55e" },
};
const xFormatter = (i: number): string => `${RevenueData[i]?.month}`;
const yFormatter = (tick: number) => tick.toString();
</script>
<template>
<div
class="mx-auto max-w-3xl space-y-6 rounded-lg"
:class="showTitle ? 'p-6' : ''"
>
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold">Bar Chart</h3>
<NuxtLink to="/blocks/bar-charts">
<UButton
icon="i-lucide-copy"
size="sm"
variant="soft"
color="neutral"
/>
</NuxtLink>
</div>
<BarChart
:data="RevenueData"
:height="300"
:categories="RevenueCategoriesMultple"
:y-axis="['desktop', 'mobile']"
:group-padding="0"
:bar-padding="0.2"
:x-num-ticks="6"
:radius="4"
:x-formatter="xFormatter"
:y-formatter="yFormatter"
:legend-position="LegendPosition.TopRight"
:hide-legend="false"
:y-grid-line="true"
/>
</div>
</template>
To create stacked bar charts, set the stacked prop to true. This will stack data series on top of each other instead of grouping them side by side.
<script lang="ts" setup>
defineOptions({
tags: ["barcharts", "stacked"],
});
withDefaults(
defineProps<{
showTitle?: boolean;
}>(),
{
showTitle: false,
},
);
type RevenueDataItem = {
month: string;
desktop: number;
mobile: number;
};
const RevenueData: RevenueDataItem[] = [
{ month: "January", desktop: 186, mobile: 80 },
{ month: "February", desktop: 305, mobile: 200 },
{ month: "March", desktop: 237, mobile: 120 },
{ month: "April", desktop: 73, mobile: 190 },
{ month: "May", desktop: 209, mobile: 130 },
{ month: "June", desktop: 214, mobile: 140 },
];
const RevenueCategoriesMultple = {
desktop: { name: "Desktop", color: "#3b82f6" },
mobile: { name: "Mobile", color: "#22c55e" },
};
const xFormatter = (i: number): string => `${RevenueData[i]?.month}`;
const yFormatter = (tick: number, _i?: number, _ticks?: number[]) =>
tick.toString();
</script>
<template>
<div
class="mx-auto max-w-3xl space-y-6 rounded-lg"
:class="showTitle ? 'p-6' : ''"
>
<div class="flex items-center justify-between">
<h3 class="text-lg font-semibold">Bar Chart</h3>
<NuxtLink to="/blocks/bar-charts">
<UButton
icon="i-lucide-copy"
size="sm"
variant="soft"
color="neutral"
/>
</NuxtLink>
</div>
<BarChart
:data="RevenueData"
:stacked="true"
:height="300"
:categories="RevenueCategoriesMultple"
:y-axis="['desktop', 'mobile']"
:group-padding="0"
:bar-padding="0.2"
:x-num-ticks="6"
:radius="4"
:x-formatter="xFormatter"
:y-formatter="yFormatter"
:legend-position="LegendPosition.TopRight"
:hide-legend="false"
:y-grid-line="true"
/>
</div>
</template>
<script lang="ts" setup>
defineOptions({
tags: ["barcharts", "withvaluelabel"],
});
type DataProps = {
month?: string;
desktop?: number;
mobile?: number;
date?: string;
value?: number;
visitors?: number;
};
const RevenueCategoriesMultiple = {
desktop: { name: "Desktop", color: "#3b82f6" },
mobile: { name: "Mobile", color: "#22c55e" },
};
const RevenueData: DataProps[] = [
{ month: "january", desktop: 186, mobile: 80 },
{ month: "february", desktop: 305, mobile: 200 },
{ month: "march", desktop: 237, mobile: 120 },
{ month: "april", desktop: 73, mobile: 190 },
{ month: "may", desktop: 209, mobile: 130 },
{ month: "jun", desktop: 214, mobile: 140 },
];
const options = {
data: RevenueData,
categories: RevenueCategoriesMultiple,
valueLabel: {
label: (d) => d.y.toString(),
labelSpacing: 16,
labelFontSize: 10,
color: "var(--ui-text)",
},
xNumTicks: 6,
xAxis: "month" as keyof DataProps,
groupPadding: 0,
barPadding: 0.2,
xFormatter: (tick: number, i?: number) =>
`${RevenueData[typeof i !== "undefined" ? i : tick]?.month}`,
yFormatter: (tick: number, i?: number) =>
`${typeof i !== "undefined" ? tick : tick}`,
};
</script>
<template>
<div>
<BarChart :height="300" :y-axis="['desktop', 'mobile']" v-bind="options" />
</div>
</template>
| Prop | Type | Default | Description |
|---|---|---|---|
data | T[] | Required | Array of data points for the chart. Each element represents a data point. |
height | number | Required | Height of the chart in pixels. |
categories | Record<string, BulletLegendItemInterface> | Required | Series configuration: name and color for each data key. |
stacked | boolean | false | If true, displays stacked bars instead of grouped bars. |
variant | BarVariant | 'solid' | Fill treatment: solid, cubes, hatched, duotone, gradient, or stripped. |
stackAndGrouped | boolean | false | If true, enables both stacked and grouped bars. |
yAxis | (keyof T)[] | Required | Array of property keys from the data object to display on the y-axis. |
xAxis | keyof T | undefined | The data key for the x-axis (required for stackAndGrouped or with valueLabel). |
xLabel | string | undefined | Optional label for the x-axis. |
yLabel | string | undefined | Optional label for the y-axis. |
padding | { top: number; right: number; bottom: number; left: number; } | undefined | Optional padding for the chart (top, right, bottom, left). |
xFormatter | axisFormatter | undefined | Formats x-axis labels. (tick, i, ticks) => string where tick can be a number or Date. |
yFormatter | axisFormatter | undefined | Formats y-axis labels. (tick, i, ticks) => string where tick can be a number or Date. |
xNumTicks | number | undefined | Desired number of ticks on the x-axis. |
yNumTicks | number | undefined | Desired number of ticks on the y-axis. |
xExplicitTicks | (number | string | Date)[] | undefined | Force specific ticks on the x-axis. |
minMaxTicksOnly | boolean | false | If true, only show first and last ticks on the x-axis. |
groupPadding | number | undefined | Padding between groups of bars in pixels. |
barPadding | number | 0 | Fractional padding between bars (0-1). |
radius | boolean | number | 2 | Rounded corners for top bars (boolean or pixel value). |
hideLegend | boolean | false | If true, hides the chart legend. |
hideTooltip | boolean | false | If true, hides the chart tooltip. |
legendPosition | LegendPosition | undefined | Position of the legend (see LegendPosition). |
legendStyle | string | Record<string, string> | undefined | Custom CSS style for the legend container. |
orientation | Orientation | 'vertical' | Orientation of the bars (vertical or horizontal). |
xDomainLine | boolean | false | Show domain (axis) line on the x-axis. |
yDomainLine | boolean | false | Show domain (axis) line on the y-axis. |
xTickLine | boolean | false | Show tick lines on the x-axis. |
yTickLine | boolean | false | Show tick lines on the y-axis. |
xGridLine | boolean | false | Show grid lines on the x-axis. |
yGridLine | boolean | false | Show grid lines on the y-axis. |
hideXAxis | boolean | false | If true, hides the x-axis. |
hideYAxis | boolean | false | If true, hides the y-axis. |
xAxisConfig | AxisConfig | undefined | Axis configuration for customizing the appearance of the x-axis. |
yAxisConfig | AxisConfig | undefined | Axis configuration for customizing the appearance of the y-axis. |
stackedGroupedSpacing | number | undefined | Spacing between stacked and grouped bars (only for stackAndGrouped). |
valueLabel | ValueLabel | undefined | Configuration for value label display (see ValueLabel). |
tooltipTitleFormatter | (data: T) => string | number | undefined | Custom formatter for tooltip titles. |
tooltip | TooltipConfig | undefined | Tooltip configuration (hideDelay, showDelay, followCursor). |
duration | number | undefined | Animation duration in milliseconds. |
The data for Vue charts should be an array of objects where each object represents a data point:
interface ChartData {
[key: string]: string | number;
}
Categories define the visual appearance and metadata for each data series:
interface Category {
name: string;
color: string;
}
interface Categories {
[key: string]: Category;
}