I would like to provide dynamic data to the chart which changes its view as per the data
But it doesn't change the view, even though I provide the dynamic data every time. Please refer the demo below.
https://codesandbox.io/s/y32yj8vxo1
Please check out the docs on reactive data
Chart.js per default is not reactive and does not reflect changes in the dataset.
I provided two helper mixin for this purpose: reactiveData and reactiveProp.
Both add a vue.js watcher to the dataset and either update or rerender the chart if the data changes.
You can also check out the examples
Hey @apertureless,
Thanks for the reply.
Right now my code look like this:
<script>
import { Doughnut } from 'vue-chartjs'
const { reactiveProp } = mixins //what should be the actual path I should give here
export default {
extends: Doughnut,
mixins: [reactiveProp],
props: ['data', 'options'],
mounted () {
this.renderChart(this.data, this.options)
}
}
</script>
But I have a doubt, what should be the path for mixins?
Well, it stands all in the Readme or the docs.
There are plenty of examples.
import { Doughnut, mixins } from 'vue-chartjs'
You can import the mixins object directly from vue-chartjs and then use destructing to get the reactiveProp or use the dot notatation. mixins.reactiveProp.
Like mentioned in the docs: The reactiveProp creates automatically a prop named chartData which holds the data of the chart and adds a watcher to it.
<script>
import { Doughnut, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins //what should be the actual path I should give here
export default {
extends: Doughnut,
mixins: [reactiveProp],
props: ['options'],
mounted () {
this.renderChart(this.chartData, this.options)
}
}
</script>
That's really a great explanation. But still, I could not get it done.
<script>
import { Doughnut, mixins } from 'vue-chartjs'
export default {
extends: Doughnut,
mixins: [mixins.reactiveProp],
props: ['chartData', 'options'],
mounted () {
this.renderChart(this.chartData, this.options)
}
}
</script>
and
<template>
<Chart v-if="showChart" :chartData="chartData" :options="{responsive: true, maintainAspectRatio: false}"></Chart>
</template>
<script>
export default {
data () {
return {
chartData: {
labels: ['Upvotes', 'Shares', 'Views'],
datasets: [
{
backgroundColor: [
'#41B883',
'#E46651',
'blue'
],
data: []
}
]
}
}
}
}
</script>
You are not setting any data in your another_component.vue
Oops.
I've this method in my another_component.vue
showStats (project) {
this.showChart = true
this.chartData.datasets[0].data = []
this.chartData.datasets[0].data = [project.upvotes.length, 2, 2]
}
Could be related to this: https://vue-chartjs.org/#/home?keyword=reac&id=limitations
And already discussed in #351
I understand.
I tried Vue.set, array.splice and this.
Nothing helped. @apertureless
Well the problem is that you only change the data inside your dataset array.
The mixin however expect the labels to change too.
It was made with realtime data in mind. So adding new data and not modifying existing one. If you add new data you need to add new labels.
The easiest way would be to add a watcher by yourself and then rerender the chart.
<script>
import { Doughnut, mixins } from 'vue-chartjs'
export default {
extends: Doughnut,
mixins: [mixins.reactiveProp],
props: ['chartData', 'options'],
watch: {
chartData () {
this.renderChart(this.chartData, this.options)
}
},
mounted () {
this.renderChart(this.chartData, this.options)
}
}
</script>
Hey @apertureless, I understand. But adding watcher doesn't work for me. Can you check what's wrong here?
https://codesandbox.io/s/r1r0p8543m
Hey @apertureless, do I have got any updates, pal?
@harishankards Dude, the guy is not your personal code reviewer. Please ask a question on SO or be much more specific...
Hey @hitautodestruct, I understand this is not a personal code reviewer. Just seeking out help, as the reactive data is not working for me. That's it, pal. If you also can help, would be grateful.
Well, I guess the problem is that you are mutating the data without the labels. So that watcher does not recognize it.
Your example is also quite weird. Why are you mutating the data array? Why are you not just set the new data array in a whole?
I don't really get the real-world use case for what you are doing there.
If you have fixed labels that never change you can also move the object inside your component and just pass the data[] array.
https://github.com/apertureless/npm-stats/blob/develop/src/components/BarChart.vue
And @hitautodestruct is right, as this is not a bug, you should ask on StackOverflow.