amCharts and $refs
-
I’m using amCharts4 with Quasar. As per the amCharts4 documentation on integrating with Vue, I am using this.$refs in the mounted method, like this:
mounted() { let chart = am4core.create(this.$refs.chartdiv, am4charts.XYChart);
I had put my chart in a Vue Single-File Component (in this example, called stockChart.vue). This has been working fine for me, but now I’d like the chart to be displayed on a q-carousel-slide. The same chart doesn’t display within the q-carousel-slide, which is stumping me. In other words, this displays the chart as expected:
<template> <q-page class="flex flex-center"> <stockChart /> </q-page> </template>
But this doesn’t display the chart:
<template> <q-page class="flex flex-center"> <q-carousel> <q-carousel-slide> <stockChart /> </q-carousel-slide> </q-carousel> </q-page> </template>
Based on some research, I think this might be because the q-carousel may be using v-if, so the ref isn’t created in the Dom until the slide is shown, but I thought implementing the chart creation code in mounted() [as per the amCharts documentation] would have worked but it doesn’t.
I’m not the most experienced Vue/node.js programmer, so I’m a bit stumped right now. Can someone give me some ideas of where to look or how to debug this?
-
Where to look to debug is in the source code.
Hihi…
I learned a lot myself on this one, as I was interested in getting this to work too.
https://codesandbox.io/s/codesandbox-app-nosgp
The issue isn’t
v-if
per se. It’s the fact that the rendering of each slide is done at the point it is called to be shown. So, sort of like a v-if, but not quite. The trick is in next-tick. See the watcher of the v-model function.I also let the data generate upfront to be a bit more performant and to keep the slides the same while switching between them.
One other thing I also did was to attach the chart functionality to the slide itself via an id instead of a ref. Refs just didn’t work.
Anyone else who also knows more, please do check this out.
One thing I think would help is to generate the chart HTML in the page and v-show it in the carousel slide to help with performance, i.e. not call to generate the chart for each slide being shown, but rather have it “pre-generated” and just show it when it’s needed. I’m just not sure how to get that done though.
Scott
-
would using <keep-alive> work?
https://vuejs.org/v2/guide/components-dynamic-async.html -
I tried that. The problem is as I understand it, the chart system is outside of Vue’s rendering. So, first Vue needs to render, then the amChart can do its thing.
Scott
-
Thinking about that, I took out the carousel animation and it seems a little bit snappier.
Scott
-
Thanks, Scott. Your solution worked perfectly out of the box. I did remove carousel animation as well, and it looks great. I learned several new things, including how to post a full Quasar SPA app via Code Sandbox; thanks again.