简体   繁体   中英

How To Use Api Data With Vue Chart.js

So I am new to using data visualization in an application and I am trying to set my data coming from my api as the data the doughnut chart uses to display however I cannot figure out how to properly access the data

I have installed vue-chartjs as a way to simplify it for component use

Here is the Chart component

<script>
import { Doughnut } from 'vue-chartjs'
import {mapGetters} from 'vuex'

export default {
    name: 'FirmChart',
    extends: Doughnut,
    computed: {
        ...mapGetters(['chartEngagements']),
    },
    mounted () {
        this.renderChart({
        labels: ['Scanned', 'Recieved', 'Preparation', 'Review', '2nd Review', 'Complete'],
        datasets: [
                {
                label: 'Data One',
                borderColor: 'black',
                pointBackgroundColor: 'white',
                borderWidth: 1,
                pointBorderColor: 'white',
                backgroundColor: [
                    '#0077ff', 
                    '#0022ff',
                    '#1133bb',
                    '#0088aa',
                    '#11ffdd',
                    '#aabbcc',
                    '#22aabb',
                    ],
                data: [
                    10,
                    10,
                    10,
                    10,
                    10,
                    10,
                    ]
                },
            ]
        }, {responsive: true, maintainAspectRatio: false});
    },
    created() {
        this.$store.dispatch('retrieveEngagementsChartData')
    }
}
</script>

now my data is coming from the chartEngagements getter and this is the display of that data in the console

{Complete: Array(1), Review: Array(3), 2nd Review: Array(1), Recieved: Array(7), Preparation: Array(1), …}

My question is how do I set the Complete: Array(1) etc to the data[] attribute in my this.renderChart() method??

I have tried doing something like this but It will not display anything

mounted () {
        this.renderChart({
        labels: ['Scanned', 'Recieved', 'Preparation', 'Review', '2nd Review' 'Complete'],
        datasets: [
                {
                label: 'Data One',
                borderColor: 'black',
                pointBackgroundColor: 'white',
                borderWidth: 1,
                pointBorderColor: 'white',
                backgroundColor: [
                    '#0077ff', 
                    '#0022ff',
                    '#1133bb',
                    '#0088aa',
                    '#11ffdd',
                    '#aabbcc',
                    '#22aabb',
                    ],
                data: [
                    this.chartEngagements.complete,
                    this.chartEngagements.review,
                    this.chartEngagements.2ndreview,
                    this.chartEngagements.preparation,
                    this.chartEngagements.recieved,
                    this.chartEngagements.scanned,
                    ]
                },
            ]
        }, {responsive: true, maintainAspectRatio: false});

However it doesn't display anything.. any help would be greatly appreciated or a point in the right direction!

Have you checked out the examples in the docs? https://vue-chartjs.org/guide/#chart-with-api-data

Your problem is, that your data api call is async. So your chart is rendered, even if your data is not fully loaded.

There is also an example with vuex which is a bit outdated https://github.com/apertureless/vue-chartjs-vuex

You have to make sure that your data is fully loaded before you render your chart.

I faced similar issue while implementing Charts with API data in one of my Vue JS apps I was working on. I am using Vuex for state management, a simple solution for this problem is to move "chartData" from "data" to "computed" which would make it reactive. Below is the sample code from my app.

<template>  
    <line-chart v-if="chartData"
      style="height: 100%"
      chart-id="big-line-chart"
      :chart-data="chartData"
      :extra-options="extraOptions"
    >
    </line-chart>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import * as expenseTypes from '../../store/modules/expense/expense-types';
import * as chartConfig from "../../components/reports/chart.config";
import BarChart from "../../components/reports/BarChart";

export default {
  components: {
    BarChart,
  },
  data () {
    return {
      extraOptions: chartConfig.chartOptionsMain
    }
  },
  computed: {
    ...mapGetters({
      allExpenses: expenseTypes.GET_ALL_EXPENSES,
      expenseCount: expenseTypes.GET_EXPENSE_COUNT,
    }),
    expenseAmount() {
      let expenseAmount = [];
      this.allExpenses.map((item) => {
        expenseAmount.push(item.amount);
      })
      return expenseAmount;
    },
    expenseLabels() {
      let expenseLabels = [];
      this.allExpenses.map((item) => {
        expenseLabels.push(item.note);
      })
      return expenseLabels;
    },
    chartData() {
      return {
        datasets: [
          {
            data: this.expenseAmount
          },
        ],
        labels: this.expenseLabels
      }
    }
  },
  async mounted() {
    await this.getAllExpenses();
    await this.fillChartData();
  },
  methods: {
    ...mapActions({
      getAllExpenses: expenseTypes.GET_ALL_EXPENSES_ACTION,
    }),
  },
};
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM