I try to write some simple chart component with vue-chartjs for my current vue-js project.
The idea is to create a live chart, so I want to automatically add data to my chart without rendering new.
My issue is that either I don't see any data or the chart will not update.
My LineChart.vue (components/charts/LineCharts.vue) looks like:
<script>
import { Line, mixins } from 'vue-chartjs'
export default {
extends: Line,
mixins: [mixins.reactiveProp],
props: ['options'],
watch: {
chartData () {
this.$data._chart.update()
}
},
mounted () {
this.renderChart(this.chartData, this.options)
}
}
</script>
And my demo.vue where I want to test my component:
<template>
<ViewTemplate>
<LineChart
v-if="loaded"
:chartData="lineChartData"
:options="options"
/>
</ViewTemplate>
</template>
<script>
import ViewTemplate from '../../components/ViewTemplate'
import LineChart from '../../components/charts/LineChart'
import pollingMixin from '../../mixins/pollingMixin'
export default {
name: 'demo',
components: { LineChart, ViewTemplate },
mixins: [pollingMixin],
data () {
return {
loaded: false,
lineChartData: {
labels: [],
datasets: []
},
options: {
responsive: true,
maintainAspectRatio: false,
title: {
display: true,
text: '',
position: 'left'
},
legend: {
display: true,
position: 'top'
},
scales: {
yAxes: [
{
ticks: {
min: this.calculateMin,
max: this.calculateMax
}
}
],
xAxes: [
{
scaleLabel: {
display: true
},
type: 'time',
time: {
displayFormats: {
second: 'HH:mm:ss',
minute: 'HH:mm',
hour: 'DD. MMM HH:mm',
day: 'DD. MMM'
},
tooltipFormat: 'DD.MM HH:mm:ss'
},
position: 'bottom'
}
]
},
elements: {
point: {
radius: 0,
hitRadius: 10,
hoverRadius: 10
},
line: {
tension: 0
}
}
}
}
},
methods: {
createChart () {
this.lineChartData = {
labels: [],
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: []
}, {
label: 'Data One',
backgroundColor: '#f87979',
data: []
}
]
}
this.loaded = true
},
fillData () {
// this.lineChartData.labels.push(1)
let i
for (i in this.lineChartData.datasets) {
if (Object.prototype.hasOwnProperty.call(this.lineChartData.datasets, i)) {
this.lineChartData.datasets[i].data.push(this.getRandomInt())
}
}
},
getRandomInt () {
const dp = {}
dp.x = Date.now()
dp.y = Math.floor(Math.random() * (50 - 5 + 1)) + 5
return dp
},
updateState () {
if (this.loaded === true) {
this.fillData()
}
}
},
computed: {
calculateMin () {
if (Object.prototype.hasOwnProperty.call(this.lineChartData, 'datasets')) {
let min = this.lineChartData.datasets[0].data[0].y
let i
for (i = 0; i < this.lineChartData.datasets.length; i++) {
let j
for (j = 0; j < this.lineChartData.datasets[i].data.length; j++) {
if (this.lineChartData.datasets[i].data[j].y < min) {
min = this.lineChartData.datasets[i].data[j].y
}
}
}
return min
} else {
return null
}
},
calculateMax () {
if (Object.prototype.hasOwnProperty.call(this.lineChartData, 'datasets')) {
let max = this.lineChartData.datasets[0].data[0].y
let i
for (i = 0; i < this.lineChartData.datasets.length; i++) {
let j
for (j = 0; j < this.lineChartData.datasets[i].data.length; j++) {
if (this.lineChartData.datasets[i].data[j].y > max) {
max = this.lineChartData.datasets[i].data[j].y
}
}
}
return max
} else {
return null
}
}
},
mounted () {
this.createChart()
}
}
</script>
Due to my PollingMixing, the method UpdateState will be executed every second.
Each array lineChartData.datasets[i].data is growing with every step.
I mean, after 60 seconds, each dataset will have 60 values.
The problem is: I don't see it, the chart doesn't illustrate it.
I got the error "element._view is undefined" on my console window.
Does anyone know what this error means?
Does anyone have an idea how to use the reactiveProp correctly?
Actually I thought, with the watch chartData and some new data,
my chart will be updated automatically.
I've tried several solutions, none worked.
This is just a simple clipping of my real work.
I hope someone has a good idea.
Thanks in advance!
Matthias