Reputation: 693
I'm trying to update my chart every 5 seconds with new data from an API call. My chart is updating but is rendering each point hundreds of times each. I checked the logs and it shows that there's an infinite loop being caused and I'm not sure how to resolve this. Below is my current code:
Note: 'graphData' prop is an Array I'm passing from Parent that is data from API call that I want added to chart
ChildComponent.vue
<template>
<div class="graphCard">
<Linechart :chartData="dataCollection" :options="options" />
</div>
</template>
<script>
import Linechart from '@/utils/Linechart.js'
export default {
components: {
Linechart
},
props: ['graphData'],
data() {
return {
collection: []
}
},
computed: {
dataCollection() {
this.collection.push(this.graphData[0])
return {
datasets: [
{
label: 'chart',
backgroundColor: 'indigo',
borderColor: 'indigo',
fill:false,
showLine: true,
data: this.collection
}]
}
},
options() {
return {
id: 'Cumulative',
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
distribution: 'series',
time: {
displayFormats: {
millisecond: 'mm:ss:SS',
quarter: 'MMM YYYY'
}
}
}],
yAxes: [{
ticks: {
//beginAtZero: true
}
}]
}
}
}
LineChart.js
import { Scatter, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Scatter,
mixins: [reactiveProp],
props: ['chartData', 'options'],
mounted () {
this.renderChart(this.chartData, this.options)
}
}
In an alternative approach I also tried to set up dataCollection and options as 'data' instead of 'computed,' with a watcher on the graphData prop, but the chart did not update and ran into an issue 'Uncaught TypeError: Cannot read property 'skip' of undefined'
Upvotes: 1
Views: 1991
Reputation: 693
@BTL got me on the right track with the approach but some issues still prevented the graph from updating correctly. It seems the chartData can't properly update if new data is pushed directly onto the dataset. What worked for me:
watch: {
graphData (newData) {
currentDataList.push(newData[0])
this.dataCollection = {
datasets: [{
label: 'label',
backgroundColor:'red',
borderColor: 'red',
fill:false,
showLine: true,
lineTension: 0,
data: currentDataList
}]
}
}
}
Upvotes: 0
Reputation: 4656
Normally a computed
is better than a watcher
but I'm not sure I can debug this infinite loop without more context.
So here is the data
+ watch
alternative who should work.
The code :
<template>
<div class="graphCard">
<Linechart :chartData="dataCollection" :options="options" v-if="dataCollection.datasets[0].data.length"/>
</div>
</template>
<script>
import Linechart from '@/utils/Linechart.js'
export default {
components: {
Linechart
},
props: ['graphData'],
data() {
return {
dataCollection: {
datasets: [{
label: 'chart',
backgroundColor: 'indigo',
borderColor: 'indigo',
fill:false,
showLine: true,
data: []
}]
},
options: {
id: 'Cumulative',
legend: {
display: false
},
scales: {
xAxes: [{
type: 'time',
distribution: 'series',
time: {
displayFormats: {
millisecond: 'mm:ss:SS',
quarter: 'MMM YYYY'
}
}
}],
yAxes: [{
ticks: {
//beginAtZero: true
}
}]
}
}
}
},
watch: {
graphData (newData) {
this.dataCollection.datasets[0].data.push(newData[0])
}
}
}
Upvotes: 1