0

I have a function in my vue applications that creates a chart.This is the chart function:

startChart: function (canvas, type) {

    // init chart.js
    var ctx = document.getElementById("myChart");
    var myDoughnut = new Chart(ctx, {
        type: 'doughnut',
        data: {
            labels: this.getAnalyticList[this.getRowIndex].chartNames,
            datasets: [{
                data: this.getAnalyticList[this.getRowIndex].chartData,
                backgroundColor: [
                    'rgba(255, 99, 132, 0.6)',
                    'rgba(54, 162, 235, 0.6)',
                    'rgba(255, 206, 86, 0.6)',
                    'rgba(75, 192, 192, 0.6)',
                    'rgba(153, 102, 255, 0.6)',
                    'red',
                    'yellow',
                    'blue',
                    'green',
                    'orange',
                    'teal',
                    'violet',
                    'pink',
                    'purple'
                ]
            }]
        },
        options: {
            responsive: true,
            defaultFontColor: '#ffffff',

        }
    })
}

and i then started it in the vue mounted hook using this line

this.startChart(this.$refs.canvas, 'Doughnut');

What i want to do is take the row index of a table loaded above the chart and that would then be passed into the getAnalyticList value that loads the charts so i can grab different arrays from the same list. I was working on creating an update function i got off this js fiddle from this stack article. I've been trying to adapt the function he created into vue but am having no luck here is the function:

changeData: function () {
            var myChart = Chart.doughnut(this.$refs.canvas, {
                data: data,
            });
            myChart.data.datasets.data = this.getAnalyticList[this.getRowIndex].chartData;
            myChart.data.labels = this.getAnalyticList[this.getRowIndex].chartNames;
            myChart.update();
        }

Any suggestions would be appreciated.

2
  • You may be interested in vue-chartjs. It's well tested and maintained, so you shouldn't have to do the integration yourself. Commented Aug 2, 2017 at 14:35
  • unfortunately its not possible for this current project Commented Aug 2, 2017 at 14:48

1 Answer 1

2

I think the only problem with your code is that you're not updating the dataset correctly. With myChart.data.datasets.data = ... your adding data to datasets object - it should be myChart.data.datasets[0].data = ....

I've also added the chart object to Vue.js model in startChart with-out reactivity because it needs to be updated manually. Just don't add it to data hook. So you can reference the chart with this.myChart in your updating method.

I've renamed getRowIndex in the demo because rowIndex is more readable - you could do the same with the getAnalyticsLists. I would name it with get-prefix if it's a method that is getting something.

Scroll down in the demo to toggle the data with the next button. That button increments rowIndex and rolls over at the end.

Please have a look at the demo below or at this jsfiddle.

const chartComponent = {
  data() {
      return {
        //myChart: undefined, // don't add chart here -> reactivity could be a problem
        getAnalyticList: [{
          chartNames: [
            'Red',
            'Yellow',
            'Blue'
          ],
          chartData: [10, 20, 30]
        },
        {
          chartNames: [
            'Red',
            'Yellow',
            'Blue'
          ],
          chartData: [40, 10, 20]
        }
        ],
        rowIndex: 0
      }
    },
    template: `
    <div>
  	<canvas id="myChart" width="200px" height="200px"></canvas>
    <button @click="incRow">next</button>
    {{rowIndex}}
    </div>
  `,
    methods: {
      startChart: function() {
        var ctx = document.getElementById("myChart");
        var myDoughnut = this.myChart =  new Chart(ctx, {
          type: 'doughnut',
          data: {
            labels: this.getAnalyticList[this.rowIndex].chartNames,
            datasets: [{
              data: this.getAnalyticList[this.rowIndex].chartData,
              backgroundColor: [
                'rgba(255, 99, 132, 0.6)',
                'rgba(54, 162, 235, 0.6)',
                'rgba(255, 206, 86, 0.6)',
                'rgba(75, 192, 192, 0.6)',
                'rgba(153, 102, 255, 0.6)',
                'red',
                'yellow',
                'blue',
                'green',
                'orange',
                'teal',
                'violet',
                'pink',
                'purple'
              ]
            }]
          },
          options: {
            responsive: true,
            defaultFontColor: '#ffffff',
						
          }
        })
      },
      incRow () {
      	if (this.rowIndex < this.getAnalyticList.length - 1) {
        	this.rowIndex++;
        }
        else {
        	this.rowIndex = 0;
        }
        this.changeData()
      },
      changeData () {
      	this.myChart.data.datasets[0].data =
        	this.getAnalyticList[this.rowIndex].chartData;
        this.myChart.data.labels = this.getAnalyticList[this.rowIndex].chartNames;
        this.myChart.update();
        console.log('changed', this.myChart.data)
      }
    },
    mounted() {
      console.log('started')
      this.startChart();
    }
}

new Vue({
  el: '#app',
  components: {
    chart: chartComponent
  }
})
div {
   width: 400px;
   height: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.bundle.min.js"></script>
<div id="app">
  <chart></chart>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.