Home > Mobile >  JS Vue3 dynamic bar chart graph with real-time reactive data
JS Vue3 dynamic bar chart graph with real-time reactive data

Time:01-08

Goal

I'm using Vue3 with the Composition API. I want to stream real-time data into a chart / graph (60 fps, possibly multiple streams / multiple updating arrays). To simplify for this question, I want to create a bar chart that updates it bars reactively to data changes by a button.

Attempts

I tried various JavaScript chart libraries like PrimeVue (Chart.js under the hood), vue-chartjs,Vue-ECharts, plotly.js. However, I'm still struggling either getting it to work or getting smooth animation. I thought real-time plotting would be a more common case, but I have a hard time finding examples (or my Google-foo fails me).

PrimeVue attempt

My best progress is with PrimeVue. I got the reactive part to work, but the issue is that the whole graph animates from scratch at each data update.

// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import PrimeVue from 'primevue/config';
import Chart from 'primevue/chart';

const app = createApp(App);
app.use(PrimeVue);
app.component('Chart', Chart);
app.mount("#app");
<script setup lang="ts">
import { reactive, ref } from 'vue'

const chartValues = reactive([0.3, 1])

const basicData = ref({
  labels: ['January', 'February'],
  datasets: [
    {
      label: 'My First dataset',
      backgroundColor: '#42A5F5',
      data: chartValues
    },
    {
      label: 'My Second dataset',
      backgroundColor: '#FFA726',
      data: [0.4, 0.1]
    }
  ]
  });

const horizontalOptions = ref(
{
  // animation: {
  //   duration: 0
  // }
}
);

function increment() {
  chartValues[0]  = 0.1
  if (chartValues[0] > 1) {
    chartValues[0] = 0
  }

}
</script>


<template>
  <h1>PrimeVue chart 2</h1>
  <button @click="increment">count is: {{ chartValues[0] }}</button>
  <div>
  <div >
    <h5>Horizontal</h5>
    <Chart type="bar" :data="basicData" :options="horizontalOptions" />
  </div>
</div>
</template>

I can prevent the whole graph animation by setting animation: {duration: 0}, but this does not look dynamic/fluid. There is no transition between values.

Questions

It would be helpful if you could:

  • (best) Share a code snippet / link to a demo (any chart/graph library is okay) that only updates bars in a bar chart for which the data has changed (or line point in a line chart) with a smooth transition (or anything related to a single array) using Vue3.
  • Recommend a good JS chart library for smooth real-time plot animation that works with Vue3's reactive() / ref().
  • Any other advice that would help me

CodePudding user response:

It depends on what kind of changes you want to make.

If you only want to change existing data, then it's relatively easy. If you want to add additional data to the chart it gets quite a bit harder, but based on your example, you're looking to mutate the a specific data inside an array so I won't cover the later.

The problem appears to be that these libraries don't handle the reactive data. Whether you have a reactive in ref or just using reactive The data passed to chart.js loses it's reactivity. I haven't looked into any of them to see why, but seems like prime-vue, vue-chartjs, and @j-t-mcc/vue3-chartjs all lose reactivity. I suspect they might be watching reactivity at a higher level, and when arrays and objects are mixed within reactive, it (video) Vue 3 ApexCharts reactive bar chart

Demo video: https://i.imgur.com/e5a0y8Z.mp4

  • Related