Releases: graphieros/vue-data-ui
v3.7.0
New dark theme #267
- The default color scheme is adapted to light mode. This release adds the
'dark'theme with defaults adapted to dark mode, saving the hassle of having to setup config details when looking for a quick out-of-the-box setup.
const config = ref({
theme: 'dark', // new
});For a quick setup:
const config = computed(() => ({
theme: isDarkMode ? 'dark' : '', // empty strings defaults to light theme
}));- This release also implements a clear hierarchy in configuration precedence: while using a theme, your provided config will take precedence to the theme's, which was not the case before. For example, if the only thing you want to change is the background color but the rest of the theme is fine, now that's possible.
Bundle size reduction
- Components now only bundle their individual themes
- The
getThemeConfigutility, which can be used to get all the themes for a given component, is now async:
import { getThemeConfig } from 'vue-data-ui';
const xy_themes = await getThemeConfig('vue_ui_xy');This is a very small breaking change, but it's a niche feature.
Add Galician locale
- New
'gl'locale in your dateTimeFormatter config
Readme grammar & typo fixes #265
- Thanks @WuMingDao for the help :)
v3.6.0
VueUiStackline new component !
- Visualize cumulative totals on stacked lines, to easily compare parts of a whole across different categories.
- API is very close to
VueUiStackbar
A chart maker is also available so you can copy paste your preferred config. Find it here.

v3.5.2
VueUiWordCloud
- Set
config.strictPixelPaddingto true by default - When
config.strictPixelPaddingistrue, slightly increase word spacing
v3.5.1
VueUiSparkHistogram
- Improve layout to avoid labels from overflowing from the svg
- Add config attributes to show / hide labels:
const config = ref({
style: {
labels: {
value: {
show: true, // new, default: true
},
timeLabel: {
show: true, // new, default: true
},
valueLabel: {
show: true, // new, default: true
},
},
},
});VueUiStackbar
- Position totals right above bars instead of on top of the chart #262
- Add optional frame around the chart area:
const config = ref({
style: {
chart: {
grid: {
frame: {
show: false,
stroke: "#E1E5E8",
strokeWidth: 2,
strokeLinecap: "round",
strokeLinejoin: "round",
strokeDasharray: 0,
},
},
},
},
});- Add config options to show total in tooltip:
const config = ref({
style: {
chart: {
tooltip: {
showTotal: false,
totalTranslation: "Total",
},
},
},
});Built-in chart annotator
- Add slots to customize button contents (your own icons for example):
<VueUiXy :dataset="dataset" :config="config">
<template #annotator-action-close>
<MyCloseIcon />
</template>
<template #annotator-action-color="{ color }">
<MyColorIcon :color="color" />
</template>
<template #annotator-action-draw="{ mode }">
<MyDrawIcon v-if="mode === 'draw'" />
<MyTextIcon v-else />
</template>
<template #annotator-action-undo="{ disabled }">
<MyUndoIcon />
</template>
<template #annotator-action-redo="{ disabled }">
<MyRedoIcon />
</template>
<template #annotator-action-delete="{ disabled }">
<MyDeleteIcon />
</template>
</VueUiXy>v3.5.0
Programmatically toggle series visibility #261
Expose new functions to toggle series visibility:
showSeries: (name: string) => void
hideSeries: (name: string) => voidSet a ref on your chart component to call exposed methods:
<VueUiXy ref="chart" :dataset="dataset" :config="config" />Example:
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);
}Components affected:
- VueUiDonut
- VueUiDonutEvolution
- VueUiGalaxy
- VueUiHistoryPlot
- VueUiHorizontalBar
- VueUiNestedDonuts
- VueUiOnion
- VueUiParallelCoordinatePlot
- VueUiQuadrant
- VueUiRadar
- VueUiRidgeline
- VueUiRings
- VueUiScatter
- VueUiSparkStackbar
- VueUiStackbar
- VueUiTreemap
- VueUiWaffle
- VueUiXy
- VueUiXyCanvas
v3.4.9
v3.4.8
User menu
- Fix #optionSvg slot not available
v3.4.7
UserOptions menu
- Show menu tooltips when custom content is used through the #optionXxx slots in menu items
<VueUiXy :dataset="dataset" :config="config">
<!-- Now the tooltip will be visible when using option slots -->
<template #optionImg>
<MyCustomIcon />
</template>
</VueUiXy>VueUiFlow
- Add borderRadius config option for nodes:
const config = ref({
style: {
chart: {
nodes: {
borderRadius: 0, // default
},
},
},
});- Improve chart accessibility (enable node focus with keyboard)
v3.4.5
VueUiTreemap
- Fix issues with default labels line height
- Fix cropped rects when zoom is active
v3.4.3
VueUiWordCloud
- Smoother opacity handling on word hovering
- New config attributes:
const config = ref({
style: {
chart: {
words: {
hoverOpacity: 0.5,
selectedStroke: "transparent",
},
},
},
});VueUiXy
- Allow passing metadata of any type in dataset items, for example:
const dataset = ref([
{
name: "Series A",
type: "line",
smooth: true,
color: "#1f77b4",
series: [1, 1, 2, 3, 5, 8, 13, 21],
// metadata:
markerIndices: [2, 6],
exposeMarkers: true,
},
]);This metadata can be leverage through the #svg slot to precisely draw annotations on the chart.
For example:
<VueUiXy :dataset="dataset" :config="config">
<template #svg="{ svg }">
<g v-html="freestyle(svg)" />
</template>
</VueUiXy>The #svg slot exposes all the data series, where you can recover your metada, based on which you can
inject content inside the chart:
function freestyle({ data, drawingArea }) {
// Filter series based on metadata:
const markedSeries = data.filter((d) => !!d.exposeMarkers);
// Filter out datapoint coordinates based on metadata:
const points = (markedSeries[0]?.plots || []).filter((_, i) =>
markedSeries[0].markerIndices.includes(i)
);
// Draw content based on these coordinates:
return `
<g>
<line
x1="${points[0]?.x}"
x2="${points[0]?.x}"
y1="${drawingArea.top}"
y2="${drawingArea.bottom}"
stroke="black"
stroke-width="3"
/>
<text
x="${points[0]?.x + 12}"
y="${drawingArea.top + 12}"
fill="red"
font-size="16"
>
This is awesome
</text>
</g>
`;
}VueUiScatter
- Allow passing metadata of any type in dataset items, for example:
const dataset = ref([
{
name: "Cluster A",
values: [
{ x: 10, y: 20, name: "p0", /* metadata: */ marked: true },
{ x: 2, y: 10, name: "p1" },
{ x: 12, y: 16, name: "p2" },
{ x: 11, y: 11, name: "p3" },
{ x: 20, y: 10, name: "p5", /* metadata: */ marked: true },
],
// metadata:
marked: true,
},
]);This metadata can be leverage through the #svg slot to precisely draw annotations on the chart.
For example:
<VueUiScatter :dataset="dataset" :config="config">
<template #svg="{ svg }">
<g v-html="freestyle(svg)" />
</template>
</VueUiScatter>The #svg slot exposes all the data series, where you can recover your metada, based on which you can
inject content inside the chart:
function freestyle({ drawingArea, data }) {
const marked = (data || []).filter((d) => !!d?.marked);
const markedPlots = marked[0]?.plots.filter((p) => !!p?.v?.marked);
const circles = (markedPlots || []).map((p) => {
return `
<g style="pointer-events: none;">
<circle
cx="${p?.x}"
cy="${p?.y}"
r="20"
stroke="#FF0000"
fill="none"
/>
<path
d="M${p?.x - 20},${p?.y} ${p?.x - 5},${p?.y} M${p?.x},${
p?.y - 20
} ${p?.x},${p?.y - 5} M${p?.x + 20},${p?.y} ${p?.x + 5},${p?.y} M${p?.x},${
p?.y + 20
} ${p?.x},${p?.y + 5}"
stroke="#FF0000"
/>
</g>
`;
});
return circles;
}VueUiStackbar
- Allow passing metadata of any type in dataset items, for example:
const dataset = ref([
{
name: "Series 1",
series: [1, 2, 3, 4, 5, 6],
// metadata:
marked: true,
},
{
name: "Series 2",
series: [12, 2, 8, 7, 3, 1],
// metadata:
marked: true,
},
{
name: "Series 3",
series: [3, 4, 5, 6, 7, 8],
},
]);This metadata can be leverage through the #svg slot to precisely draw annotations on the chart.
For example:
<VueUiStackbar :dataset="dataset" :config="config">
<template #svg="{ svg }">
<g v-html="freestyle(svg)" />
</template>
</VueUiStackbar>The #svg slot exposes all the data series, where you can recover your metada, based on which you can
inject content inside the chart:
function freestyle({ drawingArea, data }) {
const marked = data?.filter((d) => !!d.marked);
const paths = marked.map((m, i) => {
const dp = m ?? { x: [], y: [] };
const minY = Math.min(...dp?.y);
const minX = dp.x[dp.y.indexOf(minY)];
const maxY = Math.max(...dp?.y);
const maxX = dp.x[dp.y.indexOf(maxY)];
return `
<defs>
<marker
id="arrow_${i}"
viewBox="0 0 10 10"
refX="5"
refY="5"
markerWidth="6"
markerHeight="6"
orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
</defs>
<path
d="M${
minX > maxX
? `${maxX},${maxY} ${minX},${minY}`
: `${minX},${minY} ${maxX},${maxY}`
}"
stroke="#000000"
marker-end="url(#arrow_${i})"
/>
`;
});
return paths;
}VueUiCandlestick
- Expose processed dataset in #svg slot which can be used to inject content inside the chart, for example:
<VueUiCandlestick :dataset="dataset" :config="config">
<template #svg="{ svg }">
<g v-html="freestyle(svg)" />
</template>
</VueUiCandlestick>function freestyle({ drawingArea, data }) {
const maxVol = data.filter((d) => !!d.isMaxVolume);
const minVol = data.filter((d) => !!d.isMinVolume);
return `
<path
d="M${minVol[0]?.high?.x},${minVol[0]?.high?.y} ${maxVol[0]?.high?.x},${maxVol[0]?.high?.y}"
stroke="black"
/>
<path
d="M${minVol[0]?.low?.x},${minVol[0]?.low?.y} ${maxVol[0]?.low?.x},${maxVol[0]?.low?.y}"
stroke="black"
/>
<polygon
points="
${minVol[0]?.high.x},${minVol[0]?.high?.y}
${maxVol[0]?.high?.x},${maxVol[0]?.high?.y}
${maxVol[0]?.low?.x},${maxVol[0]?.low?.y}
${minVol[0]?.low?.x},${minVol[0]?.low?.y}
"
fill="#00000020"
/>
`;
}