Search code examples
javascriptvue.jsvue-chartjs

Not working dynamically rendering my chart on vue-chartjs


I was define my chart as below (MainChart.vue).

import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
// const brandPrimary = '#20a8d8'
export default {
  extends: Line,
  mixins: [reactiveProp],
  props: ['options', 'chartData', 'height'],
  mounted () {
    this.renderChart(this.chartData, this.options)
    var elements = 1
  }
}

I tested this code and confirmed that it worked well.

<line-chart :chartData="myChartData"></line-chart>

but, I tried rendering chart dynamically, it is not working.

import lineChart from './MainChart';

// ...

let chartClass = Vue.extend(lineChart)
let chartInstance = new chartClass({
  propsData: {
    chartData: myChartData
  }
})
chartInstance.$mount()
console.log(chartInstance.$el)
console.log(chartInstance.$el.querySelector("canvas").toDataURL('image/png'))
console.log(chartInstance.$refs.canvas)
console.log(chartInstance.$refs.canvas.toDataURL('image/png'))

Console messages:

console

I checked from the console and found that nothing was drawn in the canvas area.

How can I do render my chart dynamically?

Similar questions:


Solution

  • To get full image data, you have to wait until the chart is finished. Using 'Promise' is helpful.

     async function addChart(d, i, w, h) {
      var canvas = document.createElement("canvas")
      canvas.width = 765
      canvas.height = 382
      //canvas.style.width = "765px"
      //canvas.style.height = "382px"
      //canvas.style.display = "none"
      canvas.id = "dynamicChart"
      document.body.appendChild(canvas)
    
      var ctx = document.getElementById("dynamicChart").getContext('2d');
      var draw = () => new Promise((resolve, reject) => {
       new Chart(ctx, {
        type: 'bar',
        data: d,
        options: {
         responsive: false
        }
       })
       setTimeout(() => resolve(), 100)
      })
    
      await draw()
    
      let imageData = document.getElementById("dynamicChart").toDataURL("image/png")
      console.log(imageData)
    
      addImage(imageData, i, w, h)
      document.body.removeChild(canvas)
     }
    
     // ...
    
     await addChart(myChartData, 0, 400, 300)
    

    If you want draw multiple chart for in the loop, try this:

    let chartFunctions = []
    myList.forEach((item) => {
      chartFunctions.push(async function() {
        await addChart(myChartData, 3, 160, 80)
      })
    }
    
    for(let k in chartFunctions) {
      await chartFunctions[k]()
    }
    

    Console messages:

    enter image description here