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





  • 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.


Log in to reply