ref.chartInstance always null
Mootook opened this issue · comments
Hello, thanks for this package. I started using it on my team lately, and it's great!
However, I'm wondering if I'm doing something wrong or if there's an issue with the properties.
I use a ref on my component instance and am trying to access the chartInstance so that I can retrigger an update when one of my props changes (none of the data, just a background color for a dynamically drawn gradient).
Something like
<template>
<Bar :data="data" ref="chartRef" />
</template>
<script>
setup () {
const chartRef = ref(null)
watch(barColorPreference, () => {
const chartInstance = chartRef.value.chartInstance // this is always null
})
const data = computed(() => ({ })) // all my data
return { chartRef, data }
}
</script>
The README.md specifies that I should be able to access the chartInstance this way. Am I missing something?
I forked the CodeSandbox from the README.md
https://codesandbox.io/s/demo-vue-chart-3-forked-y6jvv?file=/src/App.vue
Hi @Mootook and thanks!
You're not doing anything wrong, accessing chartInstance has been implemented today thanks to this issue #4 but I forgot to update the docs.
But there is still bugs because making chartInstance reactive will throw an error in Vue 3 and not in Vue 2 :(
I will work on a solution making chartInstance reactive only for Vue 2.
The workaround for now is using the events chart:render
or chart:update
like this:
<template>
<div>
<DoughnutChart
ref="doughnutRef"
:data="testData"
@chart:render="handleChartRender"
/>
<button @click="shuffleData">Shuffle</button>
</div>
</template>
<script lang="ts">
import { shuffle } from 'lodash';
import { computed, defineComponent, ref } from 'vue';
import { Doughnut } from 'vue-chart-3';
import { Chart, ChartData, ChartOptions } from 'chart.js';
export default defineComponent({
name: 'Home',
components: { DoughnutChart: Doughnut },
setup() {
const data = ref([30, 40, 60, 70, 5]);
const doughnutRef = ref<typeof Doughnut>();
const testData = computed<ChartData<'doughnut'>>(() => ({
labels: ['Paris', 'Nîmes', 'Toulon', 'Perpignan', 'Autre'],
datasets: [
{
data: data.value,
backgroundColor: ['#77CEFF', '#0079AF', '#123E6B', '#97B0C4', '#A5C8ED'],
},
],
}));
function handleChartRender(chart: Chart<'doughnut'>) {
console.log(chart);
}
function shuffleData() {
data.value = shuffle(data.value);
}
return { testData, shuffleData, doughnutRef, handleChartRender };
},
});
</script>
By the way the data in each Chart Component is already reactive to changes! If your data
changes, the Chart will update itself like in the exemples :)
Docs updated!
@victorgarciaesgi Ah, that makes sense. Thanks!
Also, my use case does not involve changing the data. I'm allowing for dynamically setting the background color of a BarChart while keeping the data consistent.
This is perhaps not in the bounds of this issue, but my current implementation is something like
watch(barColorPreference, async newColor => {
data.labels = [] // clear and await the render to rerender the chart
await nextTick()
data.label = originalLabels
})
I assume there's a much better way.
Okay! Does the workaround is okay for you ? (with the events)
@victorgarciaesgi yup! Thanks again