Appearance
@vibe-labs/design-vue-graphs
Vue 3 charting components for the Vibe Design System. Built on D3 scale/shape primitives with reactive dimensions, token-based series colors, and full tooltip/legend support.
Installation
ts
import { VibeGraphBar, VibeGraphLine, VibeGraphPie, VibeGraphSparkline } from "@vibe-labs/design-vue-graphs";Requires the CSS layer from @vibe-labs/design-components-graphs and peer dependencies d3-scale and d3-shape.
Chart Components
VibeGraphBar
Multi-series bar chart with grouped and stacked modes, horizontal/vertical orientation, and annotations.
vue
<VibeGraphBar
:series="[
{
name: 'Revenue',
data: [
{ label: 'Q1', value: 120 },
{ label: 'Q2', value: 180 },
],
},
{
name: 'Costs',
data: [
{ label: 'Q1', value: 80 },
{ label: 'Q2', value: 95 },
],
},
]"
:annotations="[{ value: 150, label: 'Target', variant: 'positive' }]"
y-label="Amount ($)"
/>
<!-- Stacked -->
<VibeGraphBar :series="data" stacked />
<!-- Horizontal -->
<VibeGraphBar :series="data" horizontal />
<!-- Custom tooltip -->
<VibeGraphBar :series="data">
<template #tooltip="{ datum, series }">
<strong>{{ series }}</strong>: {{ datum.value }}
</template>
</VibeGraphBar>Props
| Prop | Type | Default | Description |
|---|---|---|---|
series | GraphSeries[] | required | Data series |
horizontal | boolean | false | Horizontal bars |
stacked | boolean | false | Stacked mode |
barRadius | number | — | Bar corner radius |
+ all GraphBaseProps and GraphAxisProps |
VibeGraphLine
Multi-series line chart with configurable curves, area fills, data point markers, and draw animation.
vue
<VibeGraphLine
:series="[
{ name: 'Streams', data: monthlyData, color: '1' },
{ name: 'Downloads', data: downloadData, color: '2' },
]"
curve="monotoneX"
area
/>
<!-- With annotations -->
<VibeGraphLine :series="data" :annotations="[{ value: 1000, label: 'Goal' }]" />
<!-- Minimal -->
<VibeGraphLine :series="data" :legend="false" :grid="false" :points="false" />Props
| Prop | Type | Default | Description |
|---|---|---|---|
series | GraphSeries[] | required | Data series |
curve | "linear" | "monotoneX" | "step" | "natural" | "cardinal" | "monotoneX" | Line interpolation |
points | boolean | true | Show data point markers |
area | boolean | false | Fill area under lines |
+ all GraphBaseProps and GraphAxisProps |
VibeGraphPie
Pie and donut chart with slice labels, configurable padding, and corner radius.
vue
<!-- Pie -->
<VibeGraphPie
:data="[
{ label: 'Rock', value: 45 },
{ label: 'Pop', value: 30 },
{ label: 'Jazz', value: 15 },
{ label: 'Other', value: 10 },
]"
labels
/>
<!-- Donut -->
<VibeGraphPie :data="genreData" :inner-radius="0.6" />
<!-- Custom slice colors -->
<VibeGraphPie
:data="[
{ label: 'Active', value: 80, color: '#22c55e' },
{ label: 'Inactive', value: 20, color: '#ef4444' },
]"
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | GraphSlice[] | required | Pie slices |
innerRadius | number | 0 | 0 = pie, 0.6 = donut |
padAngle | number | 1 | Degrees between slices |
cornerRadius | number | 2 | Arc corner radius |
labels | boolean | false | Show percentage labels |
+ all GraphBaseProps |
VibeGraphSparkline
Minimal inline chart for dashboards, tables, and compact displays.
vue
<!-- Basic -->
<VibeGraphSparkline :data="[5, 12, 8, 20, 15, 25]" />
<!-- With area fill -->
<VibeGraphSparkline :data="values" area color="2" />
<!-- Show min/max markers -->
<VibeGraphSparkline :data="values" show-extremes />
<!-- Custom size -->
<VibeGraphSparkline :data="values" width="120px" height="2.5rem" />Props
| Prop | Type | Default | Description |
|---|---|---|---|
data | number[] | required | Flat array of values |
width | string | "100%" | SVG width |
height | string | "2rem" | SVG height |
color | string | "1" | Series index, status name, or CSS color |
area | boolean | false | Fill area under line |
curve | "linear" | "monotoneX" | "natural" | "monotoneX" | Interpolation |
showExtremes | boolean | false | Min/max dot markers |
animate | boolean | true | Draw animation on mount |
Shared Components
VibeGraphLegend
Interactive legend with color swatches. Supports block and line swatch styles.
vue
<VibeGraphLegend :items="legendItems" @toggle="handleToggle" />VibeGraphTooltip
Positioned tooltip that auto-clamps within the chart container. Supports custom content via slot.
VibeGraphEmpty
Empty state placeholder shown when charts have no data.
Common Props (GraphBaseProps)
All chart types (except sparkline) share:
| Prop | Type | Default | Description |
|---|---|---|---|
width | string | "auto" | Chart width |
height | string | "auto" | Chart height |
ratio | GraphRatio | — | Aspect ratio (16x9, 4x3, 1x1, 21x9) |
legend | boolean | true | Show legend |
legendPosition | "top" | "bottom" | "left" | "right" | "bottom" | Legend position |
tooltip | boolean | true | Enable tooltips |
animate | boolean | true | Mount animation |
animationDuration | number | 600 | Animation ms |
emptyText | string | "No data available" | Empty state message |
ariaLabel | string | — | Chart ARIA label |
Axis Props (GraphAxisProps)
Bar and line charts additionally support:
| Prop | Type | Description |
|---|---|---|
xLabel / yLabel | string | Axis labels |
grid | boolean | Grid lines (default: true) |
yMin / yMax | number | Explicit axis bounds |
yFormat / xFormat | (v) => string | Tick label formatters |
annotations | GraphAnnotation[] | Reference/threshold lines |
Events
All charts emit:
| Event | Payload | Description |
|---|---|---|
hover | GraphHoverEvent | Datum hovered |
leave | — | Mouse left datum |
click | GraphClickEvent | Datum clicked |
Composables
useSeriesColors(items)
Returns a computed array of resolved CSS colors from series/slice color props. Handles index mapping ("1" → var(--graph-series-1)), status names ("positive" → var(--graph-positive)), and passthrough CSS colors.
resolveSeriesColor(color, fallbackIndex)
Standalone resolution function — use outside reactive contexts.
useGraphDimensions(containerEl, margins?)
ResizeObserver-based reactive dimensions. Returns outer/inner dimensions with configurable margins.
useTooltip(containerEl)
Tooltip state management with smart clamping (stays within container bounds, flips above/below as needed).
Data Types
ts
interface GraphDatum {
label: string;
value: number;
meta?: Record<string, unknown>;
}
interface GraphSlice extends GraphDatum {
color?: string;
}
interface GraphSeries {
name: string;
data: GraphDatum[];
color?: string;
}
interface GraphAnnotation {
value: number;
label?: string;
variant?: GraphAnnotationVariant;
}Series Colors
The color prop on series/slices resolves through a cascade:
"1"through"8"→var(--graph-series-N)(tenant-themeable)"positive"/"negative"/"warning"/"neutral"→ status tokens"#ff6b6b"→ used as-isundefined→ auto-assigned from palette by index
Dependencies
| Package | Purpose |
|---|---|
d3-scale | Linear, band, and point scales |
d3-shape | Line, area, arc, and pie generators |
@vibe-labs/design-components-graphs | CSS tokens + generated styles |
Build
bash
npm run buildBuilt with Vite + vite-plugin-dts. D3 modules are externalized. Outputs ES module with TypeScript declarations.