Search code examples
javascriptvue.jschart.jsvue-chartjs

How to Render Chart Datasets in Vue?


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


Solution

  • 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
                );
            }
        }
    };