Chartjs-How to update chart when state changes in vue?

0👍

Using a watcher like this should be enough:

<script>
import { Line } from "vue-chartjs";
import { mapState } from "vuex";

export default {
  name: "ChartLine",
  extends: Line,
  computed: {
    ...mapState(["chartData", "options"])
  },
  methods: {
    regraph() {
      this.renderChart(this.chartData, this.options);
    }
  },
  mounted() {
    this.regraph();
  },
  watch: {
    chartData: {
      handler: this.regraph,
      deep: true
    }
  }
};
</script>

Also having the explicit vuex state map inside the ChartLine component seems a bit wasteful – passing the vuex data through props would render the component more generic:

<template>
  <div id='pension' class="navbarPar">
    <ChartLine :options="options" :chart-data="chartData"/> 
  </div>
</template>
<script>...

Chartline.vue:

<script>
import { Line } from "vue-chartjs";

export default {
  name: "ChartLine",
  extends: Line,
  props: {
    options: {
      type: Object,
      default: () => ({})
    },
    chartData: {
      type: Object /*is it?*/,
      default: () => ({})
    }
  },
  methods: {
    regraph() {
      this.renderChart(this.chartData, this.options);
    }
  },
  mounted() {
    this.regraph();
  },
  watch: {
    chartData: {
      handler: this.regraph,
      deep: true
    }
  }
};
</script>

0👍

If you are using vue-chartjs, the library has its own way to handle reactive data in charts:

// ChartLine.js
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins

export default {
  extends: Line,
  mixins: [reactiveProp],
  props: ['options'], // passed from the parent
  mounted () {
    // this.chartData is created in the mixin (pass it as any prop with :chart-data="data").
    this.renderChart(this.chartData, this.options)
  }
}

Now the Pension.vue file

// Pension.vue
<template>
  <div id='pension' class="navbarPar">
    <ChartLine :chart-data="charData" :options="options" /> 
  </div>
</template>

<script>
  import ChartLine from '../components/ChartLine';
  import { mapState } from 'vuex'

  export default {
    name: 'Pension',
    components: {
      ChartLine,
    },
    data(){
      return{
        form: {
          ...
        },
        var:{
          ...
        },
      }
    },
    methods: {
      calculate: function(indice){
      ...
      //modify data of mapState
      //after here, I want to rerender chart
      }
    },
    computed:{
      ...mapState(['charData','options']),
    },
  }
</script>

You can read more about it here: https://vue-chartjs.org/guide/#updating-charts,
there are some caveats

Leave a comment