# vue-data-ui
[](https://npmx.dev/vue-data-ui)
[](https://npmx.dev/package/vue-data-ui)
[](https://npmx.dev/package/vue-data-ui)
[](https://npmx.dev/package/vue-data-ui?modal=chart)
[](https://vue-data-ui.graphieros.com)
[](https://github.com/graphieros/vue-data-ui/issues)
[](https://madewithvuejs.com/p/vue-data-ui/shield-link)
[](https://github.com/graphieros/vue-data-ui)
A user-empowering data visualization Vue component library for eloquent data storytelling.
Interactive Documentation:
- Deployed Site - [Vue Data UI](https://vue-data-ui.graphieros.com/)
- GitHub Repo - [vue-data-ui-doc](https://github.com/graphieros/vue-data-ui-doc)
Available components
## Charts
- [VueUiAgePyramid](https://vue-data-ui.graphieros.com/docs#vue-ui-age-pyramid)
- [VueUiBump](https://vue-data-ui.graphieros.com/docs#vue-ui-bump)
- [VueUiCandlestick](https://vue-data-ui.graphieros.com/docs#vue-ui-candlestick)
- [VueUiChestnut](https://vue-data-ui.graphieros.com/docs#vue-ui-chestnut)
- [VueUiChord](https://vue-data-ui.graphieros.com/docs#vue-ui-chord)
- [VueUiCirclePack](https://vue-data-ui.graphieros.com/docs#vue-ui-circle-pack)
- [VueUiDag](https://vue-data-ui.graphieros.com/docs#vue-ui-dag)
- [VueUiDonutEvolution](https://vue-data-ui.graphieros.com/docs#vue-ui-donut-evolution)
- [VueUiDonut](https://vue-data-ui.graphieros.com/docs#vue-ui-donut)
- [VueUiDumbbell](https://vue-data-ui.graphieros.com/docs#vue-ui-dumbbell)
- [VueUiFlow](https://vue-data-ui.graphieros.com/docs#vue-ui-flow)
- [VueUiFunnel](https://vue-data-ui.graphieros.com/docs#vue-ui-funnel)
- [VueUiGalaxy](https://vue-data-ui.graphieros.com/docs#vue-ui-galaxy)
- [VueUiGauge](https://vue-data-ui.graphieros.com/docs#vue-ui-gauge)
- [VueUiHeatmap](https://vue-data-ui.graphieros.com/docs#vue-ui-heatmap)
- [VueUiHistoryPlot](https://vue-data-ui.graphieros.com/docs#vue-ui-history-plot)
- [VueUiHorizontalBar](https://vue-data-ui.graphieros.com/docs#vue-ui-horizontal-bar)
- [VueUiMolecule](https://vue-data-ui.graphieros.com/docs#vue-ui-molecule)
- [VueUiMoodRadar](https://vue-data-ui.graphieros.com/docs#vue-ui-mood-radar)
- [VueUiNestedDonuts](https://vue-data-ui.graphieros.com/docs#vue-ui-nested-donuts)
- [VueUiOnion](https://vue-data-ui.graphieros.com/docs#vue-ui-onion)
- [VueUiParallelCoordinatePlot](https://vue-data-ui.graphieros.com/docs#vue-ui-parallel-coordinate-plot)
- [VueUiQuadrant](https://vue-data-ui.graphieros.com/docs#vue-ui-quadrant)
- [VueUiQuickChart](https://vue-data-ui.graphieros.com/docs#vue-ui-quick-chart)
- [VueUiRadar](https://vue-data-ui.graphieros.com/docs#vue-ui-radar)
- [VueUiRelationCircle](https://vue-data-ui.graphieros.com/docs#vue-ui-relation-circle)
- [VueUiRidgeline](https://vue-data-ui.graphieros.com/docs#vue-ui-ridgeline)
- [VueUiRings](https://vue-data-ui.graphieros.com/docs#vue-ui-rings)
- [VueUiScatter](https://vue-data-ui.graphieros.com/docs#vue-ui-scatter)
- [VueUiStackbar](https://vue-data-ui.graphieros.com/docs#vue-ui-stackbar)
- [VueUiStackline](https://vue-data-ui.graphieros.com/docs#vue-ui-stackline)
- [VueUiStripPlot](https://vue-data-ui.graphieros.com/docs#vue-ui-strip-plot)
- [VueUiThermometer](https://vue-data-ui.graphieros.com/docs#vue-ui-thermometer)
- [VueUiTiremarks](https://vue-data-ui.graphieros.com/docs#vue-ui-tiremarks)
- [VueUiTreemap](https://vue-data-ui.graphieros.com/docs#vue-ui-treemap)
- [VueUiWaffle](https://vue-data-ui.graphieros.com/docs#vue-ui-waffle)
- [VueUiWheel](https://vue-data-ui.graphieros.com/docs#vue-ui-wheel)
- [VueUiWordCloud](https://vue-data-ui.graphieros.com/docs#vue-ui-word-cloud)
- [VueUiXyCanvas](https://vue-data-ui.graphieros.com/docs#vue-ui-xy-canvas)
- [VueUiXy](https://vue-data-ui.graphieros.com/docs#vue-ui-xy)
## Mini charts
- [VueUiSparkHistogram](https://vue-data-ui.graphieros.com/docs#vue-ui-sparkhistogram)
- [VueUiSparkbar](https://vue-data-ui.graphieros.com/docs#vue-ui-sparkbar)
- [VueUiSparkgauge](https://vue-data-ui.graphieros.com/docs#vue-ui-sparkgauge)
- [VueUiSparkline](https://vue-data-ui.graphieros.com/docs#vue-ui-sparkline)
- [VueUiSparkStackbar](https://vue-data-ui.graphieros.com/docs#vue-ui-sparkstackbar)
- [VueUiSparkTrend](https://vue-data-ui.graphieros.com/docs#vue-ui-spark-trend)
- [VueUiGizmo](https://vue-data-ui.graphieros.com/docs#vue-ui-gizmo)
- [VueUiBullet](https://vue-data-ui.graphieros.com/docs#vue-ui-bullet)
## 3d
- [VueUi3dBar](https://vue-data-ui.graphieros.com/docs#vue-ui-3d-bar)
## Tables
- [VueUiTableHeatmap](https://vue-data-ui.graphieros.com/docs#vue-ui-table-heatmap)
- [VueUiTableSparkline](https://vue-data-ui.graphieros.com/docs#vue-ui-table-sparkline)
- [VueUiTable](https://vue-data-ui.graphieros.com/docs#vue-ui-table)
- [VueUiCarouselTable](https://vue-data-ui.graphieros.com/docs#vue-ui-carousel-table)
## Rating
- [VueUiRating](https://vue-data-ui.graphieros.com/docs#vue-ui-rating)
- [VueUiSmiley](https://vue-data-ui.graphieros.com/docs#vue-ui-smiley)
## Maps
- [VueUiGeo](https://vue-data-ui.graphieros.com/docs#vue-ui-geo)
- [VueUiWorld](https://vue-data-ui.graphieros.com/docs#vue-ui-world)
## Productivity
- [VueUiHill](https://vue-data-ui.graphieros.com/docs#vue-ui-hill)
## Utilities
- [VueUiAccordion](https://vue-data-ui.graphieros.com/docs#vue-ui-accordion)
- [VueUiAnnotator](https://vue-data-ui.graphieros.com/docs#vue-ui-annotator)
- [VueUiCursor](https://vue-data-ui.graphieros.com/docs#vue-ui-cursor)
- [VueUiDashboard](https://vue-data-ui.graphieros.com/docs#vue-ui-dashboard)
- [VueUiDigits](https://vue-data-ui.graphieros.com/docs#vue-ui-digits)
- [VueUiIcon](https://vue-data-ui.graphieros.com/docs#vue-ui-icon)
- [VueUiKpi](https://vue-data-ui.graphieros.com/docs#vue-ui-kpi)
- [VueUiMiniLoader](https://vue-data-ui.graphieros.com/docs#vue-ui-mini-loader)
- [VueUiSkeleton](https://vue-data-ui.graphieros.com/docs#vue-ui-skeleton)
- [VueUiTimer](https://vue-data-ui.graphieros.com/docs#vue-ui-timer)
# Installation
```
npm i vue-data-ui
```
You can declare components globally in your main.js:
```js
import { createApp } from 'vue';
import App from './App.vue';
// Include the css;
import 'vue-data-ui/style.css';
// You can declare Vue Data UI components globally
import { VueUiRadar } from 'vue-data-ui';
const app = createApp(App);
app.component('VueUiRadar', VueUiRadar);
app.mount('#app');
```
Or you can import just what you need into your files:
```js
```
You can also use the "VueDataUi" universal component, just specifying which component you are using. You can of course use the slots provided, if the target component has them.
```js
```
Note that the following utility components are not supported by the universal VueDataUi component and must be imported individually:
- Arrow
- VueUiIcon
- VueUiPattern
## Typescript
Types are available in the 'vue-data-ui.d.ts' file under the types directory of the package.
## Vue Data UI version2 -> version3 migration
Vue Data UI v3 does not contain breaking changes.
However, some charts have their padding configs modified, which can lead to excessive padding with a v2 config.
### Version 3 features
- `config.loading` (default: false) toggle loading state manually, to display a beautiful skeleton loader which uses the same chart component and shares layout features derived from your config. This skeleton loader is also triggered automatically if the provided dataset is undefined.
- `config.debug` (default: false) set to true to show warning messages during development, turn off for production.
- smart label resizing and auto-rotating features
- more charts support responsive mode
- config event callbacks
## Nuxt
[This repo contains a boilerplate implementation of the vue-data-ui package in Nuxt](https://github.com/graphieros/vue-data-ui-nuxt)
# Customizable tooltips
Charts with tooltips have a config option to customize tooltip contents:
```js
customFormat: ({ seriesIndex, datapoint, series, config }) => {
return `
${ ... }
`;
}
```
# Data formatting
Data labels can be customized using the `formatter` config attribute (since v2.3.29 on all chart components):
```
// the formatter attribute is generally placed under the label or dataLabel config attribute objects
const config = ref({
formatter: ({ value, config }) => {
return `formatted ${value}`;
}
})
```
# Slots
## #svg slot
Most Vue Data UI chart components include a #svg slot you can use to introduce customized svg elements (shapes, text, etc).
```html
This is a custom caption
```
The svg slot also works when using the VueDataUi universal component, if the component it wraps supports it.
## #legend slot (since v.2.0.41)
All charts expose a #legend slot except for:
- VueUiCirclePack
- VueUiDumbbell
- VueUiFlow
- VueUiFunnel
- VueUiHeatmap
- VueUiHill
- VueUiRelationCircle
- VueUiSparkHistogram
- VueUiSparkStackbar
- VueUiSparkbar
- VueUiSparkgauge
- VueUiSparkline
- VueUiThermometer
- VueUiTimer
- VueUiTiremarks
- VueUiWheel
The legend slot also works when using the VueDataUi universal component, if the component it wraps supports it.
It is recommended to set the show legend config attribute to false, to hide the default legend.
```html
{{ legend.name }}
```
## Legend toggle
An opt-in config option displays a toggle button to hide/show all series, when the number of series > 2.
This attribute can be found in the `legend.selectAllToggle` config section:
```js
legend: {
selectAllToggle: {
show: false,
backgroundColor: '#E1E5E8',
color: '#2D353C'
}
}
```
This legend toggle option is available for the following components:
- VueUiDonut
- VueUiDonutEvolution
- VueUiGalaxy
- VueUiHistoryPlot
- VueUiHorizontalBar
- VueUiNestedDonuts
- VueUiOnion
- VueUiParallelCoordinatePlot
- VueUiQuadrant
- VueUiQuickChart
- VueUiRadar
- VueUiRidgeline
- VueUiRings
- VueUiRings
- VueUiScatter
- VueUiSparkStackbar
- VueUiStackbar
- VueUiStackline
- VueUiTreemap
- VueUiWaffle
- VueUiWorld
- VueUiXy
- VueUiXyCanvas
## Tooltip slots
Use the #tooltip slot to customize tooltip contents.
You will usually only need the `datapoint` attribute exposed by the slot, but you can always log what the slot provides if you need more.
```html
{{ tooltip.timeLabel.text }}
{{ serie.name }}: {{ serie.value }}
```
Customize tooltip contents with #tooltip-before and #tooltip-after slots, to include an image, another chart or any other rich content into your tooltips.
It's an alternative to the config option `tooltip.customFormat`, in case richer tooltip content is needed.
All slots expose the following object:
```
{
datapoint,
seriesIndex,
series,
config,
}
```
Components with time series will also expose an additional `timeLabel` attribute.
The following charts bear these slots:
- VueUiAgePyramid
- VueUiCandlestick
- VueUiCirclePack
- VueUiDonut
- VueUiGalaxy
- VueUiHeatmap
- VueUiHistoryPlot
- VueUiHorizontalBar
- VueUiMolecule
- VueUiNestedDonuts
- VueUiOnion
- VueUiParallelCoordinatePlot
- VueUiQuadrant
- VueUiQuickChart
- VueUiRadar
- VueUiRings
- VueUiScatter
- VueUiSparkStackbar
- VueUiStackbar
- VueUiStackline
- VueUiTreemap
- VueUiWordCloud
- VueUiWorld
- VueUiXy \*
- VueUiXyCanvas
- VueUiwaffle
\* VueUiXy slots specifically expose the following additional attributes:
```
{
...,
bars,
lines,
plots
}
```
```html
This content shows first
This content shows the last
```
The #tooltip-before & #tooltip-after slots also work when using the VueDataUi universal component, if the component it wraps supports them.
## Add a watermark using the #watermark slot
You can use the #watermark slot to include any watermark content with your own styling.
This slot exposes the isPrinting boolean you can use to display the watermark only when producing a pdf or an image.
```html
```
Since version 3.5.1, slots are exposed to customize the chart annotator sub-menu:
```html
```
# Custom palette
It is possible to provide a custom palette in the config prop through config.customPalette (string[]) for the following components:
- VueUi3dBar
- VueUiBump
- VueUiChestnut
- VueUiChord
- VueUiCirclePack
- VueUiDonut
- VueUiDonutEvolution
- VueUiFlow
- VueUiGalaxy
- VueUiGauge
- VueUiHistoryPlot
- VueUiHorizontalBar
- VueUiMolecule
- VueUiNestedDonuts
- VueUiOnion
- VueUiParallelCoordinatePlot
- VueUiQuadrant
- VueUiQuickChart
- VueUiRadar
- VueUiRelationCircle
- VueUiRidgeline
- VueUiRings
- VueUiScatter
- VueUiSparkStackbar
- VueUiSparkbar
- VueUiStackbar
- VueUiStackline
- VueUiStripPlot
- VueUiTableSparkline
- VueUiThermometer
- VueUiTreemap
- VueUiWaffle
- VueUiWordCloud
- VueUiWorld
- VueUiXy
- VueUiXyCanvas
If the array of colors provided in customPalette is too small for the dataset, remaining colors will be computed from the default internal palette.
Accepted color formats: HEX, RGB, HSL, named colors.
# Responsive charts
By default, all charts will scale to the width of their container.
However the following charts can be made fully responsive, making them better to use in resizable containers:
| Component | Responsive feature implemented |
| --------------------------- | ------------------------------ |
| VueUi3dBar | ✅ |
| VueUiAgePyramid | ✅ |
| VueUiAgePyramid | ✅ |
| VueUiBullet | ✅ |
| VueUiBump | ✅ |
| VueUiCarouselTable | - |
| VueUiChestnut | - |
| VueUiChord | ✅ |
| VueUiCirclePack | ✅ |
| VueUiDag | ✅ |
| VueUiDonut | ✅ |
| VueUiDonutEvolution | ✅ |
| VueUiDumbbell | ✅ |
| VueUiFlow | ✅ |
| VueUiFunnel | ✅ |
| VueUiGalaxy | ✅ |
| VueUiGauge | ✅ |
| VueUiGeo | ✅ |
| VueUiHeatmap | ✅ |
| VueUiHistoryPlot | ✅ |
| VueUiHorizontalBar | ✅ |
| VueUiMolecule | - |
| VueUiMoodRadar | ✅ |
| VueUiNestedDonuts | ✅ |
| VueUiOnion | ✅ |
| VueUiParallelCoordinatePlot | ✅ |
| VueUiQuadrant | ✅ |
| VueUiQuickChart | ✅ |
| VueUiRadar | ✅ |
| VueUiRelationCircle | ✅ |
| VueUiRidgeline | ✅ |
| VueUiRings | ✅ |
| VueUiScatter | ✅ |
| VueUiSparkHistogram | ✅ |
| VueUiSparkStackbar | - |
| VueUiSparkTrend | ✅ |
| VueUiSparkbar | - |
| VueUiSparkgauge | - |
| VueUiSparkline | ✅ |
| VueUiStackbar | ✅ |
| VueUiStackline | ✅ |
| VueUiStripPlot | ✅ |
| VueUiTableHeatmap | - |
| VueUiTableSparkline | - |
| VueUiThermometer | ✅ |
| VueUiTimer | ✅ |
| VueUiTiremarks | ✅ |
| VueUiTreemap | ✅ |
| VueUiWaffle | ✅ |
| VueUiWheel | ✅ |
| VueUiWordCloud | ✅ |
| VueUiWorld | - |
| VueUiXy | ✅ |
| VueUiXyCanvas | ✅ |
To activate responsiveness, set the config.responsive attribute to true:
```js
const config = ref({
responsive: true,
// rest of your config
});
```
**Important:** when using the responsive feature, charts must be placed inside a container with fixed dimensions. Avoid setting a 100% height to this container, as it will result in the chart growing infinitely.
# Big data optimization (since v2.4.11)
Very large datasets (> 5k or > 10k datapoints) will cause the browsers rendering engines to slow down, caused by too many SVG DOM elements to render.
The following charts use the LTTB algorithm (Largest-Triangle-Three-Bucket) beyond a certain threshold to downsample the rendered dataset while preserving its shape. These components are the most susceptible to be used with very large datasets:
| Component | Default Threshold | Remark |
| --------------- | ----------------- | ------------------------------------------------------------- |
| VueUiXy | 1095 | |
| VueUiXyCanvas | 10000 | Since this chart uses canvas, the threshold can be set higher |
| VueUiQuadrant | 1095 | |
| VueUiScatter | 1095 | |
| VueUiSparkline | 1095 | |
| VueUiSparkTrend | 1095 | |
The downsample threshold for each component can be set in the config prop passed to components:
```js
const config = ref({
downsample: {
threshold: 500,
},
...// rest of your config
})
```
# Chart custom background (since v2.4.59)
A #chart-background slot is available on most charts to customize their background, to display a gradient, an image, etc.
The content placed inside this slot has pointer-events set to none, so it does not interfere with the components' interactivity.
```html
```
The following components do not support this slot, because it would not make sense:
- VueUiCarouselTable
- VueUiDag
- VueUiGizmo
- VueUiIcon
- VueUiKpi
- VueUiRating
- VueUiSmiley
- VueUiSparkStackbar
- VueUiSparkbar
- VueUiTableHeatmap
- VueUiTableSparkline
- VueUiTreemap
- VueUiWaffle
- VueUiXyCanvas
# Pattern slot (v2.4.67+)
A #pattern slot is available on some components to apply custom patterns on datapoints for further customization.
The slot exposes the seriesIndex, and a patternId which must be used on the pattern element to be recognized.
A pattern element must be used inside this slot. It will be injected inside a defs element of the component.
```html
```
The #pattern slot is available on the following components:
- VueUiChord
- VueUiCirclePack
- VueUiDonut
- VueUiGauge
- VueUiRidgeline
- VueUiRings
- VueUiStackbar
- VueUiStackline
- VueUiHorizontalBar
- VueUiWaffle
- VueUiWorld
- VueUiXy
A set of 12 readymade patterns is available through the VueUiPattern component:
```js
import { VueUiPattern } from 'vue-data-ui';
```
```html
```
VueUiPattern accepts the following props:
- id: string, required. Pass the patternId provided by the #pattern slot
- name: string, required. The name of the pattern to use
- fill: string, optional. The backgroundColor of the pattern. Transparent by default to show the datapoint base color
- stroke: string, optional. Default: #2D353C
- strokeWidth: number, optional. Default: 1
- scale: number, optional. Default: 1
List of available patterns:
| pattern name |
| ---------------- |
| bubbles |
| flooring |
| grid |
| hexagon-diamond |
| hexagon-flooring |
| hexagon-grid |
| maze |
| redrum |
| scales |
| squares |
| wave |
| zigzag |
# Utility functions
A set of utility functions is available:
```js
import {
abbreviate,
darkenColor,
lightenColor,
shiftColorHue,
createTSpans,
getCumulativeAverage,
getCumulativeMedian,
} from 'vue-data-ui';
```
### abreviate
```js
import { abbreviate } from 'vue-data-ui';
const text = 'lorem ipsum dolor sit amet';
const abbreviated = abbreviate({
source: text,
length: 5,
}); // Result: LIDSA
```
### darkenColor
```js
import { darkenColor } from 'vue-data-ui';
const color = '#FF0000';
const darkened = darkenColor(color, 0.5); // Result: #800000ff
```
### lightenColor
```js
import { lightenColor } from 'vue-data-ui';
const color = '#FF0000';
const lightened = lightenColor(color, 0.5); // Result: #ff8080ff
```
### shiftColorHue
```js
import { shiftColorHue } from 'vue-data-ui';
// Color format can be HEX (with or without alpha channel), RGB, RGBA, or named color
const color = '#FF0000';
const shifted = shiftColorHue(color, 0.1); // Result: #ff9900ff
```
### createTSpans
```js
import { createTSpans } from 'vue-data-ui';
const textContent = createTSpans({
content: 'This is an example of multiline text',
fontSize: 16,
fill: '#1A1A1A',
maxWords: 3,
x: 10,
y: 20,
});
```
```html
```
### getCumulativeAverage
```js
import { getCumulativeAverage } from 'vue-data-ui';
// simple usage
const arr = [0, 1, 2, 3, 4];
const cumulativeAvg = getCumulativeAverage({ values: arr });
// Ignore invalid values entirely
const arrWithInvalid = [1, null, 2, Infinity, NaN, undefined];
const cumulativeAvgNoInvalid = getCumulativeAverage({
values: arrWithInvalid,
config: {
keepInvalid: false,
},
});
// Convert invalid values to zero
const cumulativeAvgZeroed = getCumulativeAverage({
values: arrWithInvalid,
config: {
convertInvalidToZero: true,
},
});
```
### getCumulativeMedian
```js
import { getCumulativeMedian } from 'vue-data-ui';
// simple usage
const arr = [0, 1, 2, 3, 4];
const cumulativeMed = getCumulativeMedian({ values: arr });
// Ignore invalid values entirely
const arrWithInvalid = [1, null, 2, Infinity, NaN, undefined];
const cumulativeMedNoInvalid = getCumulativeMedian({
values: arrWithInvalid,
config: {
keepInvalid: false,
},
});
// Convert invalid values to zero
const cumulativeMedZeroed = getCumulativeMedian({
values: arrWithInvalid,
config: {
convertInvalidToZero: true,
},
});
```
### mergeConfigs
```js
import { mergeConfigs, getVueDataUiConfig } from 'vue-data-ui';
const defaultConfig = getVueDataUiConfig('vue_ui_xy');
// Create a full config with user overrides
const merged = mergeConfigs({
defaultConfig,
userConfig: {
chart: {
backgroundColor: '#FF0000',
},
},
});
```
## Multiline data labels
Some components will display labels on multiple lines when the provided text contains a line break. (example: "I contain a\nline break").
Below is a table of the places where such line breaks can be used:
| Component | Label displayed | Where to use line breaks |
| --------------------------- | -------------------- | ------------------------------------------------------ |
| VueUiBump | Series labels | dataset names |
| VueUiDag | Node labels | dataset label |
| VueUiDonutEvolution | Time labels (x axis) | config.style.chart.layout.grid.xAxis.dataLabels.values |
| VueUiHistoryPlot | Plot labels | dataset names |
| VueUiHorizontalBar | Series labels | dataset names |
| VueUiParallelCoordinatePlot | Axis labels | config.style.chart.yAxis.labels.axisNames |
| VueUiQuadrant | Plot labels | dataset names |
| VueUiQuickChart | Time labels (x axis) | config.xyPeriods |
| VueUiRidgeline | Time labels (x axis) | config.style.chart.xAxis.labels.values |
| VueUiRings | Series labels | dataset names |
| VueUiStackbar | Time labels (x axis) | config.style.chart.grid.x.timeLabels.values |
| VueUiStackline | Time labels (x axis) | config.style.chart.grid.x.timeLabels.values |
| VueUiStripPlot | x axis labels | dataset names |
| VueUiXy | Time labels (x axis) | config.chart.grid.labels.xAxisLabels.values |
## PDF generation
This package requires jspdf as a peer dependency. Please install it in your project if you intend to use the PDF printing feature.
## `useObjectBindings`
A composable that **flattens** a reactive object into a set of refs (one for each “leaf” property) so you can easily bind to deeply nested values by their string paths.
### Why use it?
- **Automatic reactivity**: Every nested property becomes a `Ref`, with automatic getters/setters that keep your source object in sync.
- **Flat API surface**: Access or update any nested field by its dot‑delimited path, without writing deep destructuring or `ref` plumbing.
- **Dynamic path support**: New paths added at runtime are discovered automatically (and proxied), so you never lose reactivity when mutating the structure.
```js
import { useObjectBindings, getVueDataUiConfig } from 'vue-data-ui';
const config = ref(getVueDataUiConfig('vue_ui_donut')); // or your custom config for this component
const bindings = useObjectBindings(config);
// Now `bindings` has computed refs for each leaf path:
// bindings["style.chart.backgroundColor"] → Ref
// bindings["style.chart.color"] → Ref
// bindings["customPalette"] → Ref
// by default, arrays are skipped:
// no "customPalette.0", unless you disable skipArrays
```
You can then use these in your template:
```html
```
## Exposed methods
Most chart components expose the following methods:
### getData
```js
const componentRef = ref(null);
onMounted(async () => {
if (componentRef) {
const data = await componentRef.value.getData();
console.log(data);
}
});
```
### getImage
```js
const componentRef = ref(null);
onMounted(async () => {
if (componentRef) {
const { imgUri, base64, title, width, height, aspectRatio } =
await componentRef.value.getImage({ scale: 2 }); // optional scale, defaults to 2, increase for better image quality
console.log(imageUri);
}
});
```
### showSeries / hideSeries
```ts
showSeries: (name: string) => void
hideSeries: (name: string) => void
```
Set a ref on your chart component to call exposed methods:
```html
```
Example:
```js
const chart = ref(null); // Add this ref on the chart component
function showSeriesByName(name) {
if (!chart.value) return;
chart.value.showSeries(name);
}
function hideSeriesByName(name) {
if (!chart.value) return;
chart.value.hideSeries(name);
}
```
`showSeries` and `hideSeries` exposed methods are available on the following components:
- VueUiDonut
- VueUiDonutEvolution
- VueUiGalaxy
- VueUiHistoryPlot
- VueUiHorizontalBar
- VueUiNestedDonuts
- VueUiOnion
- VueUiParallelCoordinatePlot
- VueUiQuadrant
- VueUiRadar
- VueUiRidgeline
- VueUiRings
- VueUiScatter
- VueUiSparkStackbar
- VueUiStackbar
- VueUiStackline
- VueUiTreemap
- VueUiWaffle
- VueUiXy
- VueUiXyCanvas
## a11y
### Keyboard navigation
Chart components, when applicable, enable keyboard navigation inside the chart area (arrows), to cycle through datapoints when the chart area is in focus.
It is possible to configure the following translations, used in hidden hints for screenreaders:
```js
const config = computed(() => ({
a11y: {
translations: {
keyboardNavigation:
'Use the left and right arrow keys to move between data points.',
tableAvailable: 'A data table for this chart is available below.',
tableCaption: 'Chart data table',
},
},
}));
```
A #hint scoped slot is available to display a navigation hint when the chart area is in focus. This slot exposes the `a11y.translations.keyboardNavigation` text, and a `isVisible` boolean which is `true` when the chart area is in focus. The hint is absolutely positioned below the chart area.
```html
{{ hint }}
```
The #hint slot is available for the following components:
- VueUiAgePyramid
- VueUiBump
- VueUiCandlestick
- VueUiChord
- VueUiCirclePack
- VueUiDag
- VueUiDonutEvolution
- VueUiDonut
- VueUiDumbbell
- VueUiFlow
- VueUiGalaxy
- VueUiGeo
- VueUiHeatmap
- VueUiHistoryPlot
- VueUiHorizontalBar
- VueUiMoodRadar
- VueUiNestedDonuts
- VueUiOnion
- VueUiParallelCoordinatePlot
- VueUiQuadrant
- VueUiQuickChart
- VueUiRadar
- VueUiRelationCircle
- VueUiRidgeline
- VueUiRings
- VueUiScatter
- VueUiSparkHistogram
- VueUiSparkline
- VueUiSparkStackbar
- VueUiStackbar
- VueUiStackline
- VueUiStripPlot
- VueUiTreemap
- VueUiWaffle
- VueUiWordCloud
- VueUiXy
- VueUiXyCanvas
### Copy alt text
On all charts with a contextual menu, the `altCopy` button can be enabled.
The purpose of this button is to provide the necessary data to create a custom alt text, that can be copied when posting a picture of the chart on socials for example.
```js
const config = computed(() => (
userOptions: {
buttons: {
altCopy: true, // false by default. Set to true to display the button in the context menu
},
callbacks: {
altCopy: ({ dataset:dst, config:cfg }) => {
// Convert the data into a tailor-made alt text you can copy to the clipboard
}
},
buttonTitles: {
altCopy: 'Copy alt text' // provide your translation for the button's tooltip
}
}
));
```
A slot is available to customize the contents of the button:
```html
```
### opt-in cursor pointer
Starting from v3.15.0, all clickable elements will have a default cursor.
To have a cursor pointer on these elements, you have to opt-in through the config:
```js
const config = computed(() => ({
useCursorPointer: true, // false by default
}));
```