Legend
The <Legend> component displays a legend identifying chart series by color and label.
Add a legend
<BarChart :width="500" :height="300" :data="data">
<Bar data-key="desktop" fill="#8884d8" />
<Bar data-key="mobile" fill="#82ca9d" />
<Legend />
</BarChart>
Legend entries follow series registration order. Moving keyed series in the template keeps each existing series and its color in that order; newly mounted series are appended.
Position the legend
Use the position prop to place the legend relative to the chart. When set, it overrides align and verticalAlign.
Inside positions (insideTop, insideBottomRight, center, …) float over the plot area — the chart keeps its full size:
<Legend position="insideTopRight" />
Outside positions (top, bottom, left, right) sit beyond the axes, and the plot area shrinks to make room. Use offset to control the gap:
<Legend position="top" :offset="10" />
When layout is left at its default ('auto'), it resolves to vertical for left/right positions and horizontal otherwise.
Customize legend content
Use the #content slot:
<Legend>
<template #content="legendProps">
<div class="flex gap-4 justify-center">
<span v-for="entry in legendProps.payload" :key="entry.value" class="flex items-center gap-1">
<span class="w-3 h-3 rounded-full" :style="{ backgroundColor: entry.color }" />
{{ entry.value }}
</span>
</div>
</template>
</Legend>
Legend props
| Prop | Type | Default | Description |
|---|---|---|---|
position | 'top' | 'bottom' | 'left' | 'right' | 'center' | 'inside*' | { x, y } | — | Legend position; overrides align and verticalAlign |
offset | number | 0 | Gap along the position direction |
layout | 'horizontal' | 'vertical' | 'auto' | 'auto' | Layout direction; 'auto' resolves from position |
align | 'left' | 'center' | 'right' | 'center' | Horizontal alignment (legacy, use position instead) |
vertical-align | 'top' | 'middle' | 'bottom' | 'bottom' | Vertical alignment (legacy, use position instead) |
width | number | — | Fixed width |
height | number | — | Fixed height |
icon-size | number | 14 | Size of the legend icon |
icon-type | string | — | Legend icon shape ('line', 'plainline', 'square', 'rect', 'circle', 'cross', 'diamond', 'star', 'triangle', 'wye') |
to | string | HTMLElement | — | Teleport legend to a CSS selector or DOM element |
wrapper-style | CSSProperties | — | Inline styles for the legend wrapper |
content-style | CSSProperties | — | Inline styles for the content |
item-style | CSSProperties | — | Inline styles for each legend item |
formatter | (value: string | undefined, entry: LegendPayload) => string | — | Format legend label text |
hidden | LegendHidden (data keys) | — | Hidden series, for v-model:hidden. Without it, clicks do not hide series |
payload-uniq-by | boolean | Function | — | Deduplicate legend entries |
item-sorter | 'value' | 'dataKey' | Function | — | Sort legend entries. Without it, entries keep the data order (Pie) or the series order |
Legend events
| Event | Payload | Description |
|---|---|---|
@click, @mouseenter, @mouseleave | (entry: LegendPayload, index: number, event: MouseEvent | KeyboardEvent) | An entry is clicked (or activated with the keyboard), entered or left |
@update:hidden | (hidden: LegendHidden) | A click toggled an entry; used by v-model:hidden |
@bbox-update | (box: { width, height } | null) | The legend size changed |
Legend slots
| Slot | Props | Description |
|---|---|---|
#content | { payload, layout, align, verticalAlign, ...props } | Custom legend content. payload is an array of { value, color, type, dataKey } entries. |
<script setup lang="ts">
import { ref } from 'vue'
import { Legend } from 'vccs'
const hidden = ref<string[]>([])
</script>
<template>
<Legend v-model:hidden="hidden" />
</template>