I'm new to Vue, and struggling to display multiple Highcarts on a Vue3 page using vue3-highcharts. I followed the Reactive Chart Example here, which works great, but I'm confused how to implement the chartOptions object for multiple charts using v-for.
A single chart using the following code works:
<vue-highcharts
type="chart"
:options="chartOptions"
:redraw-on-update="true"
:one-to-one-update="false"
:animate-on-update="true"
@updated="onUpdate"/>
and the associated setup / computed code
setup() {
const seriesData = ref([25, 39, 30, 15]);
const categories = ref(['Jun', 'Jul', 'Aug', 'Sept']);
const chartOptions = computed(() => ({
chart: {
type: 'line',
},
title: {
text: 'Number of project stars',
},
xAxis: {
categories: categories.value,
},
yAxis: {
title: {
text: 'Number of stars',
},
},
series: [{
name: 'New project stars',
data: seriesData.value,
}],
}));
I have tried multiple methods to use v-for to load multiple charts, here is the latest / most successful:
<vue-highcharts
v-for="item in hmCharts"
:key="item.id"
:options="item.options"
:redraw-on-update="true"
:one-to-one-update="false"
:animate-on-update="true"
@rendered="onRender"
@update="onUpdate"
@destroy="onDestroy" />
const hmCharts = ref([
{
id: 'one',
options: getChartoptions('one')
},{
id: 'two',
options: getChartoptions('two')
}])
const seriesData = [[0, 0, 10], [0, 1, 19], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117]]
hmCharts.value[0].options.series[0].data = seriesData
hmCharts.value[1].options.series[0].data = seriesData
This method will eventually load both charts, but it takes a full minute or more to load. I found the following error in the console:
runtime-core.esm-bundler.js?9e79:6620 [Vue warn]: Maximum recursive updates exceeded. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function.
I have spent more time and research on this than I care to admit, and really hoping someone can help me understand what it happening here. Thanks!
Update: I created a codesandboxio project to reproduce the issue: codesandboxio project. It takes awhile to load the charts, and then throws errors in the console.
CodePudding user response:
Not wrapping hmCharts
inside a ref
seems to fix the problem:
https://codesandbox.io/s/vue-highcharts-recursive-error-forked-gwqd4?file=/src/App.vue
The gist of it is a Highcharts instance can't be watched by Vue for reactivity, as it contains itself at various levels, and every time something changes (mutates) inside of it, Vue will attempt to update its dependencies, creating a never ending loop.
Another fix is to replace ref
with shallowRef
:
https://codesandbox.io/s/vue-highcharts-recursive-error-forked-qn46j?file=/src/App.vue