簡體   English   中英

使用來自 api 的數據初始化 Chart.js 圖表

[英]Initialize a Chart.js chart with data from an api

正如我在標題中提到的,我想用 api 初始化 Chart.js 圖表。 我找到了教程,但它們大多在呈現頁面后更新數據。 我想在頁面呈現之前更新圖表。 所以我直接看到初始化圖表而無需重新加載。

<template>
    <h3>Stacked</h3>
    <Chart type="bar" v-if="isReady" :data="stackedData" :options="stackedOptions"/>
</template>

<script>
import axios from "axios";
import {defineComponent, ref} from 'vue';
export default {
 
    data()  {  
 
       return {
              isReady: false,
              stackedData: {
                labels: ['A', 'B', 'C', 'D'],
                datasets: [{
                    type: 'bar',
                    label: 'Something',
                    backgroundColor: '#42A5F5',
                    data: this.list_all
                }, {
                    type: 'bar',
                    label: 'Another',
                    backgroundColor: '#66BB6A',
                    data: this.list_intersection
                }]
            },
           
            stackedOptions: {
                tooltips: {
                    mode: 'index',
                    intersect: false
                },
                responsive: true,
                scales: {
                    xAxes: [{
                        stacked: true,
                    }],
                    yAxes: [{
                        stacked: true
                    }]
                }
            },
            basicOptions: null,

//---------------------------------------------------
            all:[]
            list_intersection:[],
            list_all:[]
        }    
    },

    beforeCreate() {
            let apiKaderURL = 'http://localhost:4000/apiKader';
            axios.get(apiKaderURL).then(res => {

                this.all = res.data;
                this.saveData()
                this.isReady=true;
            }).catch(error => {
                console.log(error)
            });
        },

     methods:{
       saveData: function (){
          
          for (var i in this.all){
                if(this.all[i].id==='2' ){
                    this.list_all.push(this.all[i].someNumber)
                }
                if(this.all[i].id==='8'){
                    this.list_intersection.push(this.all[i].someNumber) 
                }                     
           }
           return this.list_all && this.list_intersection
       }
    }
}
</script>


我只是想用 axios 獲取值,過濾它們,然后將它們返回到圖表對象的數據屬性,以便使用這些值進行初始化。

我想,因為我調用beforeCreate ,它應該可以工作,因為我在渲染之前初始化了值,但圖表沒有顯示任何值。

我也嘗試過使用vue-chartjs來實現,但我認為它並不能真正與 Vue 3 一起使用,或者我做錯了什么。

我怎樣才能做到這一點? 非常感謝您。

我之前沒有使用過 Chart.js,但我通讀了安裝、集成和使用文檔並提出了一個可能對您有所幫助的示例(帶有 Vue CLI 的 Vue 2)。

我使用我的 App.vue SFC 作為子圖表組件 ChartTest.vue 的父級。 在父級中,我使用“mounted”掛鈎中的“setTimeout”調用模擬了 API 調用延遲。

應用程序.vue

<template>
  <div id="app">
    <chart-test v-if="dataReady" :chartData="chartData" />
  </div>
</template>

<script>
  import ChartTest from '@/components/ChartTest'

  export default {
    name: 'App',
    components: {
      ChartTest
    },
    data() {
      return {
        chartData: [12, 19, 3, 5, 2, 3],
        dataReady: false
      }
    },
    methods: {
      getData() {
        this.dataReady = true;
      }
    },
    mounted() {
      // Simulate API call
      setTimeout(this.getData(), 2000);
    }
  }
</script>

ChartTest.vue

<template>
  <div class="chart-test">
    <h3>Chart Test</h3>
    <canvas id="my-chart" width="400" height="400" ref="chartref"></canvas>
  </div>
</template>

<script>
  import Chart from 'chart.js';

  export default {
    data() {
      return {
        myChart: null
      }
    },
    props: {
      chartData: {
        type: Array,
        required: true
      }
    },
    mounted() {
      this.myChart = new Chart(this.$refs.chartref, {
        type: 'bar',
        data: {
          labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
          datasets: [{
            label: '# of Votes',
            data: this.chartData,
            backgroundColor: [
              'rgba(255, 99, 132, 0.2)',
              'rgba(54, 162, 235, 0.2)',
              'rgba(255, 206, 86, 0.2)',
              'rgba(75, 192, 192, 0.2)',
              'rgba(153, 102, 255, 0.2)',
              'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
              'rgba(255, 99, 132, 1)',
              'rgba(54, 162, 235, 1)',
              'rgba(255, 206, 86, 1)',
              'rgba(75, 192, 192, 1)',
              'rgba(153, 102, 255, 1)',
              'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
          }]
        },
        options: {
          scales: {
            yAxes: [{
              ticks: {
                beginAtZero: true
              }
            }]
          }
        }
      });
    }
  }
</script>

生命周期鈎子(如beforeCreate等)實際上不會延遲后續組件生命周期步驟,即使是異步的,它們只是提供運行代碼的入口點。

使用v-if延遲圖表的呈現,直到數據准備好。 v-if就像watch一樣,在此之前根本不會渲染圖表。 使用isReady變量,您將在數據完成保存時設置該變量:

<Chart type="bar" v-if="isReady" :data="stackedData" :options="stackedOptions"/>
data()  {  
  return {
    isReady: false,
    ...
  }
}
axios.get(apiKaderURL).then(res => {
  this.all = res.data;
  this.saveData()
  this.isReady = true;  // Triggering the `v-if`
})

(未經測試,但應該在原則上工作)


此外,您不能使用this從另一個數據屬性設置數據屬性,它將是undefined 您可以將它們設置為null

data: this.list_all  // Does nothing, can't use `this` like that
data: null           // Change to this

因此將其設置為null並修復saveData方法:

methods: {
  saveData() {
    const listAll = [];
    const listIntersection = [];

    for (var i in this.all){
      if(this.all[i].id==='2' ){
        listAll.push(this.all[i].someNumber)
      }
      if(this.all[i].id==='8'){
        listIntersection.push(this.all[i].someNumber) 
      }                     
    }
   
    this.stackedData.datasets[0].data = listAll;
    this.stackedData.datasets[1].data = listIntersection;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM