Search code examples
vue.jschart.jsvuejs3primevue

How to add data dynamically to primevue Line chart from vuejs3?


I am trying to make a realtime chart with primevue Line Chart as described here:

https://www.primefaces.org/primevue/showcase/#/chart/line

At first I declared the Chart tag with data and options attributes:

<Chart type="line" :data="basicData" :options="basicOptions"/>

Then I declared the objects inside data return script:

import Chart from 'primevue/chart'

export default {
  name: 'Chart Test',
  components: {
    Chart
  },
  data () {
    return {
      basicData: {
        labels: ['0', '10', '20', '30', '40', '50', '60'],
        datasets: [
          {
            label: 'Speed',
            data: [0],
            fill: false,
            borderColor: '#42A5F5',
            tension: 0
          }
        ]
      },
      basicOptions: {
        plugins: {
          legend: {
            labels: {
              color: '#495057'
            }
          }
        },
        scales: {
          x: {
            ticks: {
              color: '#495057'
            },
            grid: {
              color: '#ebedef'
            }
          },
          y: {
            ticks: {
              color: '#495057'
            },
            grid: {
              color: '#ebedef'
            }
          }
        }
      }
    }
  }

And now I want to add data dynamically, by calling a method like:

    methods: {
        addData () {
            // update data from Chart here dynamically
        }
    }

How can I do that? I didn't find this information anywhere on the internet.

UPDATE: The accepted answer solved my problem. Thanks.


Solution

  • The Chart.js docs indicate that you can push new data into the chart's data.datasets[] and data.labels properties, and then calling chart.update():

    function addData(chart, label, data) {
        chart.data.labels.push(label);
        chart.data.datasets.forEach((dataset) => {
            dataset.data.push(data);
        });
        chart.update();
    }
    

    PrimeVue's Chart component exposes the underlying Chart.js instance via chart, so you can use that property update the chart:

    1. Apply a template ref on the Chart component:

      <Chart ref="primeChart">
      
      import { ref } from 'vue'
      
      export default {
        setup() {
          const primeChart = ref()
          // chart.js instance is now available via primeChart.value.chart
      
          return {
            primeChart,
          }
        }
      }
      
    2. Return the chart data from setup() (i.e., use the Composition API to avoid making the bound array data reactive). This is necessary to avoid a Maximum call stack size exceeded error when modifying the chart data.

      export default {
        setup() {
          return {
            // non-reactive data
            basicData: {/*...*/},
            basicOptions: {/*...*/},
          }
        }
      }
      
    3. Create an addData method that updates the chart.js instance (via the template ref), following the example from the Chart.js docs above:

      export default {
        setup() {
          const primeChart = ref()
      
          const addData = () => {
            const chart = primeChart.value.chart
            chart.data.labels.push(/* NEW DATA LABEL */)
            chart.data.datasets[0].data.push(/* NEW DATA VALUE */)
            chart.update()
          }
        }
      }
      

      Now you can use addData() (e.g., through a button click) to update the chart with new data.

    demo