1

I am currently making a reports page and currently struggling how to render the dataset to my BarChart. I have no problems showing static data to the chart but when I use axios it does not work. I read solutions about using watchers and mounted. But I am confused how to apply it if my BarChart is in another component.

This is my BarChart Code:

import { Bar } from "vue-chartjs";
export default {
  name: "BarChart",
  extends: Bar,
  data() {
    return {};
  },
  props: {
    label: {
      type: Array,
    },
    chartData: {
      type: Array,
    },
    options: {
      type: Object,
    },
  },
  mounted() {
    const dates = this.chartData.map((d) => d.date);
    const totalCheckIn = this.chartData.map((d) => d.totalCheckIn);
    const totalCheckOut = this.chartData.map((d) => d.totalCheckout);
    this.renderChart(
      {
        labels: dates,
        datasets: [
          {
            label: this.label[0],
            data: totalCheckIn,
          },
          {
            label: this.label[1],
            data: totalCheckOut,
          },
        ],
      },
      this.options
    );
  },
};

In my reports component this is how I used it:

<BarChart
   v-bind:chartData="checkIn"
   v-bind:options="checkInOptions"
   v-bind:label="checkInLabel"
></BarChart>
import BarChart from "../components/BarChart";

export default {
  name: "Reports",
  components: { BarChart },
  data() {
    return {
      checkInOptions: {
        responsive: true,
        maintainAspectRatio: false,
      },
      checkIn: [
        { date: "1", totalCheckIn: "2", totalCheckout: "2" },
        { date: "2", totalCheckIn: "1", totalCheckout: "2" },
      ],
      checkInLabel: ["Check In", "CheckOut"],
     }
   },
   beforeMount() {
    axios
      .get('http://localhost:3000/monthly-checkin/'+this.month+'/'+this.year+'')
      .then((res) => {
        this.checkIn = res.data.monthly;
        console.log(this.checkIn)
      })
      .catch((err) => {
        console.log(err.response.data.message);
      });
   } 
}

Please help

Ven
  • 89
  • 1
  • 8
  • You must `this.renderChart(...);` after the data is updated. – Chin. Udara Jun 12 '21 at 16:37
  • Does this answer your question? [Vue Chart.js - Chart is not updating when data is changing](https://stackoverflow.com/questions/43728332/vue-chart-js-chart-is-not-updating-when-data-is-changing) – Chin. Udara Jun 12 '21 at 16:38

1 Answers1

1

Use watch inside your BarChart component as below:

watch:{
    chartData:function(newVal,OldVal){
        //assign chart data
    },
  },

Afterwards you need to execute the method where your bar chart data could be updated. Below will be the full snippet.

import { Bar } from "vue-chartjs";
export default {
    name: "BarChart",
    extends: Bar,
    data() {
        return {};
    },
    props: {
        label: {
            type: Array,
        },
        chartData: {
            type: Array,
        },
        options: {
            type: Object,
        },
    },
    watch: {
        chartData: function (newVal, OldVal) {
            this.updateChart()
        },
    },
    mounted() {
        this.updateChart()
    },
    methods: {
        updateChart() {
            const dates = this.chartData.map((d) => d.date);
            const totalCheckIn = this.chartData.map((d) => d.totalCheckIn);
            const totalCheckOut = this.chartData.map((d) => d.totalCheckout);
            this.renderChart(
                {
                    labels: dates,
                    datasets: [
                        {
                            label: this.label[0],
                            data: totalCheckIn,
                        },
                        {
                            label: this.label[1],
                            data: totalCheckOut,
                        },
                    ],
                },
                this.options
            );
        }
    }
};
bhaginath
  • 456
  • 4
  • 13
  • 1
    I'm referring to the watcher handler, but you're right that there would be no loop only because the value hasn't actually changed. However, setting `chartData` to `newVal` in the `chartData` watcher is pointless because `chartData` is *already* that value. Plus, `chartData` is a prop, and props are not supposed to be mutated (and you'll see a browser console warning about it). The watcher just needs to call `updateChart()`. – tony19 Jun 14 '21 at 01:23
  • Thank you so much!! I was really confused how this work. I tried using watchers with ```async``` and ```await``` but it was too confusing and also didn't work out. Your solution is really simple to understand – Ven Jun 15 '21 at 13:43
  • 1
    Glad! it was helpful :) – bhaginath Jun 15 '21 at 18:47