@unovis/vue 1.7.0
Unovis is a modular data visualization framework. @unovis/vue provides autogenerated Vue 3 wrappers for the core classes in @unovis/ts (README.md).
Version and environment
- Package:
@unovis/vue@1.7.0. - Peer dependencies:
@unovis/tspinned to exactly1.7.0, andvue^3(package.json:56-59). Install both at the exact same version:npm install -P @unovis/ts @unovis/vue(README.md:16). A version mismatch between the two packages breaks peer resolution. - ESM first. The package has
type: module, subpath exports under./*, andsideEffects: false(package.json:28-39). - No CSS import. Styles are injected from JS at runtime (
index.js:1). - Docs: https://unovis.dev/docs/intro. Component docs live at
https://unovis.dev/docs/components/<Name>. Gallery: https://unovis.dev/gallery.
How the wrappers work
Every Vis* component is a thin wrapper around one @unovis/ts class. Verify these rules before writing code:
- Props map one to one to the core config interface, for example
AreaConfigInterface. Use camelCase in script and kebab-case in templates::line-width="2",:stack-min-height="true". - Accessors are functions. Pass them as props:
:x="d => d.x",:y="['sales', 'cost'].map(k => d => d[k])". datacan live on the container or on a component. The container shares itsdatawith all children. A child falls back to its owndataonly when the container has none (components/area/index.js:35). Pass data at the container level for multi component charts.- Reactivity: a config change calls
setConfigthenrenderon the core class. Adatachange callssetData. Both update the chart in place, without remounting. - Every wrapper exposes
component, a ref to the core@unovis/tsinstance, throughdefineExpose. Use a template ref to call core methods:chart.value?.component?.destroy(). - Each module also exports selectors, for example
VisAxisSelectorsequalsAxis.selectorsfrom@unovis/ts. Use selectors with theeventsprop and tooltiptriggers(events and tooltips). - Containers collect children through provide and inject. Place
Vis*children in the container's default slot. The XY container defers chart creation until at least one child registers (containers/xy-container/index.js:50-52), sov-forand conditional children work. - Legends and maps are standalone.
VisBulletLegend,VisFlowLegend,VisRollingPinLegend,VisLeafletMap, andVisLeafletFlowMaprender into their own DOM node. Use them outside containers. All other components require a container context.
Quick start
<script setup lang="ts">
import { ref } from 'vue'
import { VisXYContainer, VisLine, VisAxis } from '@unovis/vue'
type DataRecord = { x: number; y: number }
const data = ref<DataRecord[]>([
{ x: 0, y: 0 },
{ x: 1, y: 2 },
{ x: 2, y: 1 },
])
const x = (d: DataRecord) => d.x
const y = (d: DataRecord) => d.y
</script>
<template>
<VisXYContainer :data="data" :height="300">
<VisLine :x="x" :y="y" />
<VisAxis type="x" />
<VisAxis type="y" />
</VisXYContainer>
</template>
Sizing: the container fits its parent's width. Set height explicitly, or the default of 300px applies (XY Container docs).
Component catalog
Two containers: VisXYContainer for XY charts with axes, VisSingleContainer for one standalone visualization plus an optional tooltip. Full list with key props: components.md.
- XY components:
VisArea,VisLine,VisScatter,VisStackedBar,VisGroupedBar,VisBoxplot(new in 1.7),VisTimeline,VisXYLabels. - Auxiliary:
VisAxis,VisCrosshair,VisTooltip,VisBrush,VisFreeBrush,VisPlotband,VisPlotline,VisAnnotations. - Single container components:
VisDonut,VisNestedDonut,VisRadialBar(new in 1.7),VisHeatmap(new in 1.7),VisTreemap,VisSankey,VisChordDiagram,VisGraph,VisTopoJSONMap. - Standalone:
VisBulletLegend,VisFlowLegend,VisRollingPinLegend,VisLeafletMap,VisLeafletFlowMap.
Common tasks
Ordinal x values
Return the index from the x accessor. Format the axis ticks back to labels.
<script setup lang="ts">
const x = (d: DataRecord, i: number) => i
const tickFormat = (i: number) => data.value[i]?.category ?? ''
</script>
<template>
<VisXYContainer :data="data">
<VisStackedBar :x="x" :y="d => d.value" />
<VisAxis type="x" :tick-format="tickFormat" />
</VisXYContainer>
</template>
Tooltip with crosshair
<script setup lang="ts">
import { VisStackedBarSelectors } from '@unovis/vue'
const triggers = {
[VisStackedBarSelectors.bar]: (d: DataRecord) => `${d.category}: ${d.value}`,
}
</script>
<template>
<VisXYContainer :data="data">
<VisStackedBar :x="x" :y="d => d.value" />
<VisCrosshair :template="triggers" />
<VisAxis type="x" />
</VisXYContainer>
</template>
More patterns, including snap mode and events: events-tooltips.md.
Custom fills with svgDefs
<script setup lang="ts">
const gradientDef = `
<linearGradient id="area-gradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#4d8cfd" stop-opacity="0.8" />
<stop offset="100%" stop-color="#4d8cfd" stop-opacity="0.1" />
</linearGradient>`
</script>
<template>
<VisXYContainer :data="data" :svg-defs="gradientDef">
<VisArea :x="x" :y="y" color="url(#area-gradient)" />
</VisXYContainer>
</template>
Waterfall chart with the baseline accessor
VisStackedBar gained baseline in 1.7 for floating bars (components/stacked-bar/index.js:11). Pair it with barStyle for dashed projected values (components/stacked-bar/index.js:10).
<script setup lang="ts">
// data records carry the floating bar start and end
const baseline = (d: WaterfallRecord) => d.start
const y = (d: WaterfallRecord) => d.end - d.start
const color = (d: WaterfallRecord) => (d.delta >= 0 ? '#00c19a' : '#ff6b7e')
</script>
<template>
<VisXYContainer :data="data">
<VisStackedBar :x="x" :y="y" :baseline="baseline" :color="color" />
<VisAxis type="x" />
<VisAxis type="y" />
</VisXYContainer>
</template>
Align stacked charts with bleed
bleed overrides the space the container reserves for edge marks. It takes a Spacing object or a function. Capture the horizontal bleed of the chart with the largest marks from onRenderComplete, then pass it to the other charts (containers/xy-container/index.js:29-30). Guide: https://unovis.dev/docs/guides/bleed.
<script setup lang="ts">
import { ref } from 'vue'
const horizontalBleed = ref<{ left?: number; right?: number }>()
const onRenderComplete = (svg: SVGSVGElement, margin: unknown, bleed: { left: number; right: number }) => {
horizontalBleed.value = { left: bleed.left, right: bleed.right }
}
</script>
<template>
<VisXYContainer :data="data" :on-render-complete="onRenderComplete">
<VisScatter :x="x" :y="y" :size="25" />
</VisXYContainer>
<VisXYContainer :data="data" :bleed="horizontalBleed">
<VisLine :x="x" :y="y" />
</VisXYContainer>
</template>
Colors and patterns
1.7 adds chart wide color synchronization and pattern fills:
colorFunctiononVisXYContainer,VisSingleContainer, andVisBulletLegendmaps a key to a color (containers/xy-container/index.js:39,html-components/bullet-legend/index.js:17).colorKeyson a component names the stable keys aligned with itsyaccessors (components/area/index.js:25).patternonVisArea,VisLine,VisScatter,VisGroupedBar,VisStackedBar,VisDonut, and others adds stripes, dots, and hatches.
Details and examples: color-patterns.md.
Gotchas
- Pin
@unovis/tsand@unovis/vueto the same exact version. The peer range is1.7.0, with no caret (package.json:57). VisCrosshair,VisTimeline, andVisBoxplotdeclare onlydataas a Vue prop. All other config travels as attributes. If a config prop seems ignored on these three, upgrade to 1.7.0: theirdataprop was silently dropped between 1.6.5 and 1.7 (fix PR).- Axis labels clipped at the top or bottom? Increase the container
margin, for example:margin="{ top: 10, right: 10, bottom: 10, left: 10 }". - Nuxt and SSR: the core is SSR ready since 1.6.4. If hydration or
documenterrors appear, wrap the chart in<ClientOnly>(issue 607). For headless rendering in Node 20+, use the separate@unovis/ssrpackage (https://unovis.dev/releases/1.7). - Strict CSP: set
window.UNOVIS_NONCEbefore the library is imported. Guide: https://unovis.dev/docs/guides/csp. - Dark theme: add the class
theme-darktobody. Override--vis-dark-*variables per component (theming guide).
References
- components.md: full export catalog with container rules and key props.
- events-tooltips.md: events, selectors, tooltips, crosshair, annotations.
- color-patterns.md: color synchronization, patterns, CSS variables, themes.
- migration-v1.7.md: changes from 1.6.x to 1.7.0 that affect Vue code.