Skip to content

Releases: graphieros/vue-data-ui

v3.7.0

12 Nov 22:07

Choose a tag to compare

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 getThemeConfig utility, 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


Docs are up to date

v3.6.0

06 Nov 22:20

Choose a tag to compare

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

View examples

View documentation

A chart maker is also available so you can copy paste your preferred config. Find it here.

image image

v3.5.2

01 Nov 07:28

Choose a tag to compare

VueUiWordCloud

  • Set config.strictPixelPadding to true by default
  • When config.strictPixelPadding is true, slightly increase word spacing

Docs are up to date

v3.5.1

30 Oct 14:35

Choose a tag to compare

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>

Documentation website is up to date

v3.5.0

28 Oct 16:02

Choose a tag to compare

Programmatically toggle series visibility #261

Expose new functions to toggle series visibility:

showSeries: (name: string) => void
hideSeries: (name: string) => void

Set 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

Documentation website is up to date

v3.4.9

27 Oct 22:51

Choose a tag to compare

VueUiStackbar #260

  • Emit non segregated series @selectLegend

v3.4.8

26 Oct 10:12

Choose a tag to compare

User menu

  • Fix #optionSvg slot not available

v3.4.7

26 Oct 06:27

Choose a tag to compare

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

23 Oct 06:11

Choose a tag to compare

VueUiTreemap

  • Fix issues with default labels line height
  • Fix cropped rects when zoom is active

v3.4.3

22 Oct 12:58

Choose a tag to compare

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"
        />
    `;
}