kartsims
kartsims

Reputation: 1008

Can't get Chart.js to run in a Vue.js component

So I am trying to display a nice chart using Chart.js inside a Vue.js component... Should not be so complicated but I am hitting a wall there.

Here is my component code (syntax is based on Vue.js webpack boilerplate)

<template>

  <canvas v-el:canvas style="width: 100%; height: 200px"></canvas>

</template>

<script>
import Chart from 'chart.js'

export default {
  compiled: function () {

    // fetch canvas DOM element
    let canvas = this.$els.canvas

    // init chart.js
    let chart = new Chart(canvas, {
      type: 'bar',
      data: {
        labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
        datasets: [{
          label: '# of Votes',
          data: [12, 19, 3, 5, 2, 3]
        }]
      },
      options: {
        scales: {
          yAxes: [{
            ticks: {
              beginAtZero: true
            }
          }]
        }
      }
    })
    console.log(chart)

  }
}
</script>

I simplified the component as much as I could, and used data from the doc example (will bind real data using props later).

So I keep getting this error in the console :

Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.

I looked it up, it seems that this has something to do with the variable passed to getComputedStyle used in Vue.js.

My best guess would be that this.$els.canvas does not return the right object. But if I output it in the console using console.log it seems right.

console.log(canvas)
// outputs <canvas style="width: 300px; height: 150px;"></canvas>
console.log(canvas.tagName)
// outputs CANVAS
console.log(canvas.style.height)
// outputs 200px

Hmmm this is actually weird and could be helpful : did you notice that I set the canvas style.height in the template, but if I do console.log(canvas) I see height: 150px but if console.log(canvas.style.height) 2 lines below, I get 200px as an output ?!! WTF is going on ?.. Vue is messing with my head right now

Link to jsFiddle for you to play with (check out the result in the console) https://jsfiddle.net/kartsims/g8s12yd2/3/#&togetherjs=CQrzT996AR

Upvotes: 1

Views: 3086

Answers (1)

kartsims
kartsims

Reputation: 1008

I figured out why and will let you know, just in case someone happens to be in the same position :

I couldn't get this to work inside a vue component displayed by Vue Router... I figured that it was because I should have used ready hook instead of compiled... At compiled, the DOM is not fully ready yet.

Upvotes: 3

Related Questions