The DonutChart component visualizes proportional data as circular segments with customizable colors and legends. Use it to display percentage-based data in Vue and Nuxt apps. Examples ↗
<script lang="ts" setup>
defineOptions({
tags: ["donutcharts", "basic"],
});
const data = [
{ name: "Product", percentage: 45 },
{ name: "Services", percentage: 25 },
{ name: "Support", percentage: 20 },
{ name: "Other", percentage: 10 },
];
const categories = {
Product: {
name: "Product",
color: "var(--color-indigo-500)",
},
Services: {
name: "Services",
color: "var(--color-purple-500)",
},
Support: {
name: "Support",
color: "var(--color-pink-500)",
},
Other: {
name: "Other",
color: "var(--color-rose-400)",
},
};
</script>
<template>
<DonutChart
:data="data.map((i) => i.percentage)"
:height="200"
:categories="categories"
:hide-legend="true"
:type="DonutType.Full"
:radius="0"
>
<div class="text-center">
<div class="font-semibold">Label</div>
<div class="text-muted">2 seconds ago</div>
</div>
</DonutChart>
</template>
Set variant="gradient" for dimensional segment fills and add glow for a soft outer highlight.
<script setup lang="ts">
defineOptions({
tags: ["donutcharts", "withlegend"],
});
const donutData = ref([35, 25, 20, 15, 5]);
const marketShareLabels = {
"Product A": {
name: "Product A",
color: "var(--ui-primary)",
},
"Product B": {
name: "Product B",
color: "var(--ui-info)",
},
"Product C": {
name: "Product C",
color: "var(--ui-success)",
},
"Product D": {
name: "Product D",
color: "var(--ui-warning)",
},
Other: {
name: "Other",
color: "var(--ui-error)",
},
};
</script>
<template>
<DonutChart
:data="donutData"
:categories="marketShareLabels"
variant="gradient"
glow
:height="200"
:radius="80"
:pad-angle="0.1"
:arc-width="20"
>
<div class="text-center">
<div class="font-semibold">Label</div>
<div class="text-muted">2 seconds ago</div>
</div>
</DonutChart>
</template>
<script lang="ts" setup>
defineOptions({
tags: ["donutcharts", "basic"],
});
const data = [
{ name: "Night Ops", percentage: 42 },
{ name: "Dusk Activity", percentage: 28 },
{ name: "Twilight", percentage: 18 },
{ name: "Dawn Events", percentage: 12 },
];
const categories = {
night: {
name: "Night Ops",
color: "var(--color-slate-950)",
},
dusk: {
name: "Dusk Activity",
color: "var(--color-slate-800)",
},
twilight: {
name: "Twilight",
color: "var(--color-slate-600)",
},
dawn: {
name: "Dawn Events",
color: "var(--color-slate-400)",
},
};
function getCategoryColor(label?: string) {
return Object.values(categories).find((c) => c.name === label)?.color;
}
</script>
<template>
<div class="relative">
<DonutChart
:data="data.map((i) => i.percentage)"
:height="200"
:radius="80"
:categories="categories"
:hide-legend="true"
:type="DonutType.Full"
:pad-angle="0"
:arc-width="0"
>
<template #tooltip="{ values }">
<div class="flex items-center gap-2 p-2 text-default">
<div
class="size-3 rounded-full"
:style="{
backgroundColor: getCategoryColor(values?.label),
}"
/>
<span class="mr-1 text-dimmed">
{{ values?.label }}
</span>
{{ values ? values[values?.label] : "" }}
</div>
</template>
</DonutChart>
</div>
</template>
| Prop | Type | Default | Description |
|---|---|---|---|
type | DonutType | 'full' | The type of donut chart to render. See DonutType for available options (half or full). |
variant | 'flat' | 'gradient' | 'flat' | Paints segments with a flat color or a diagonal gradient. |
glow | boolean | false | Adds a soft outer glow to each segment. |
data | number[] | required | The data to be displayed in the donut chart. Each number in the array represents a segment value. |
arcWidth | number | The arc width of the chart in pixels. | |
height | number | required | The height of the chart in pixels. |
radius | number | required | The radius of the donut in pixels. |
hideLegend | boolean | false | If true, hides the chart legend. |
legendPosition | LegendPosition | Optional position for the legend, if applicable. See LegendPosition for available options. | |
legendStyle | string | Record<string, string> | Optional style object for the legend container. Allows custom CSS styling. | |
categories | Record<string, BulletLegendItemInterface> | required | A record mapping category keys to BulletLegendItemInterface objects. This defines the visual representation and labels for each category in the chart's legend. |
padAngle | number | 0 | Pad angle between segments in radians. |
tooltipTitleFormatter | (data: T) => string | number | undefined | Custom formatter for tooltip titles. |
hideTooltip | boolean | false | If true, hides the chart tooltip. |
tooltip | TooltipConfig | undefined | Tooltip configuration (hideDelay, showDelay, followCursor). |
duration | number | undefined | Animation duration in milliseconds. |
The data should be an array of numbers where each number represents a segment value:
type DonutChartData = number[];
Categories define the visual appearance and labels for each segment in the chart's legend:
interface BulletLegendItemInterface {
name: string;
color: string;
}
type DonutCategories = Record<string, BulletLegendItemInterface>;
<script setup lang="ts">
const data = ref([35, 25, 20, 15, 5]);
const labels = [
{ name: "Product A", color: "#3b82f6" },
{ name: "Product B", color: "#22c55e" },
{ name: "Product C", color: "#f59e0b" },
{ name: "Product D", color: "#a855f7" },
{ name: "Other", color: "#06b6d4" },
];
const categories: Record<string, BulletLegendItemInterface> =
Object.fromEntries(
labels.map((i) => [i.name, { name: i.name, color: i.color }]),
);
</script>
<template>
<DonutChart
:data="data"
:height="260"
:categories="categories"
:radius="4"
:arc-width="20"
:pad-angle="0.1"
/>
</template>
The DonutChart uses the keys of the categories object to determine the labels shown in the default tooltip. To ensure your tooltips look "nice and cool", use display-ready strings as keys.
// ❌ Technical keys lead to technical tooltips
const categories = {
cpu: { name: "CPU Usage", color: "red" },
};
// ✅ Display keys lead to clean tooltips
const categories = {
"CPU Usage": { name: "CPU Usage", color: "red" },
};
In this component, the radius prop often controls the corner radius (segment rounding) rather than the outer radius of the chart.
2 and 8 provide a modern, rounded look.radius to a high value (like 80 or 100 on a small chart) can distort the segments and break the tooltip interactive areas.To adjust the physical dimensions of the donut, use height and arcWidth instead of radius:
height: Controls the overall size of the SVG container.arcWidth: Controls the thickness of the donut ring (and the size of the inner hole).Available donut chart types:
DonutType.Half or 'half' - Half donut chartDonutType.Full or 'full' - Full donut chart (default)Available legend positions:
LegendPosition.TopRight - Top right of the chartLegendPosition.BottomRight - Bottom right of the chartLegendPosition.Left - Left of the chartLegendPosition.Right - Right of the chartThe DonutChart component for Vue charts can be customized using CSS variables.
| Variable | Default | Description |
|---|---|---|
--vis-donut-background-color | #E7E9F3 | The background color of the donut chart. |
Example:
:root {
--vis-donut-background-color: transparent !important;
}