首页 > 解决方案 > Vue.JS、Axios、CanvasJS - 从 API 获取数据并填充/渲染图表

问题描述

我是新手,Vue.JS并试图在我的图表中包含反应性数据,一次一步。这是我的Javascript

window.onload = function () {
    var chartParent = new Vue({
        el: '#chartContainer',
        data: function() {
            return {
                chart: null,
                tempData: null
            }
        },
        computed: {
            chartOptions() {
                return {
                    theme: "light2",
                    subtitles: [
                        {
                            text: "Performance",
                            fontStyle: "bold",
                            verticalAlign: "center",
                            dockInsidePlotArea: true
                        },
                        {
                            text: "Legend (On Hover)",
                            fontStyle: "bold",
                            verticalAlign: "bottom",
                            horizontalAlign: "right",
                            dockInsidePlotArea: true
                        }
                    ],
                    toolTip:{
                        enabled: false,
                    },
                    data: [
                        {
                            type: "doughnut",
                            indexLabel: "",
                            mousemove: this.donutChartMousemove,
                            showInLegend: false,
                            dataPoints: [
                                {
                                    "y": 90,
                                    "label": "Temp In Range",
                                    "color": "#218340",
                                    "legendLabel": "(Temp ≤ + 1°F)"
                                },
                                {
                                    "y": 5,
                                    "label": "Temp In Tolerance",
                                    "color": "#F7B731",
                                    "legendLabel": "(+ 1°F < Temp <= 2°F)"
                                },
                                {
                                    "y": 5,
                                    "label": "Temp Above Setpoint",
                                    "color": "#A62337",
                                    "legendLabel": "(Temp > + 2°F)"
                                }
                            ]
                        }
                    ]
                }
            }
        },
        mounted: function () {
            axios
                .get('/api/temps')
                .then((response) => { this.tempData = response.data })
                .catch((error)   => { console.log(error) })
            this.chart = new CanvasJS.Chart("chartContainer", this.chartOptions);
            this.chart.render();
        },
        methods: {
            donutChartMousemove: function(e){
                this.chart.subtitles[0].set("text", e.dataPoint.label + " (" + e.dataPoint.y + "%)");
                this.chart.subtitles[0].set("fontColor", e.dataPoint.color);
                this.chart.subtitles[1].set("text", e.dataPoint.legendLabel);
                this.chart.subtitles[1].set("fontColor", e.dataPoint.color);
            }
        }
    })
}

这是位于的JSON数据/api/temps

{
  "Temps_agg": {
    "Avg_Dry_Bulb": 95,
    "Station1": {
      "TempInRange_Day": 92.7777777777778,
      "TempInTolerance_Day": 7.2222222222222,
      "TempAboveSetpoint_Day": 0
    },
    "Station2": {
      "TempInRange_Day": 83.22222222222227,
      "TempInTolerance_Day": 16.777777777777832,
      "TempAboveSetpoint_Day": 0
    }
  }
}

我想像这样将值传递Station1到我的图表中(上面的代码段):

                            dataPoints: [
                                {
                                    "y": this.tempData.Temps_agg.Station1.TempInRange_Day,
                                    "label": "Temp In Range",
                                    "color": "#218340",
                                    "legendLabel": "(Temp ≤ + 1°F)"
                                },
                                {
                                    "y": this.tempData.Temps_agg.Station1.TempInTol_Day,
                                    "label": "Temp In Tolerance",
                                    "color": "#F7B731",
                                    "legendLabel": "(+ 1°F < Temp <= 2°F)"
                                },
                                {
                                    "y": this.tempData.Temps_agg.Station1.TempAboveSetpoint_Day,
                                    "label": "Temp Above Setpoint",
                                    "color": "#A62337",
                                    "legendLabel": "(Temp > + 2°F)"
                                }
                            ]

当我这样做时,我收到此错误:

app.js:28150 [Vue warn]: Error in mounted hook: "TypeError: Cannot read property 'Temps_agg' of null"
//trim
app.js:29413 TypeError: Cannot read property 'Temps_agg' of null
//trim

如果我打印响应,我可以在控制台axios中看到响应:JSON

            axios
                .get('/api/temps')
                .then((response) => { console.log(response.data) })
                .catch((error)   => { console.log(error) })

我怀疑我造成了“种族”状况?

编辑1:谢谢@hmm 的指导。这对我有用:

            async created () {
                try {
                    let response = await axios.get('/api/temps');
                    this.chartData = response;
                    this.chart = new CanvasJS.Chart("chartContainer", this.chartOptions);
                    this.chart.render();
                }catch(err){
                    console.log(err);
                }
            },

你会注意到我删除mounted ()了,现在我将图表呈现在async created ().

标签: javascriptvue.jsaxios

解决方案


Edit 1 的解决方案有点“hacky”,因为 Vue 在继续组件生命周期之前不会等待 promise 解决。它可能有效,但它似乎不像 Vue 做事的方式。

我不知道你的用例,但看起来你可以保持这个非常简单。

data () {
  return {
    chart: null
  }
},
mounted () {
  axios.get('/api/temps')
    .then((response) => {
      let chartOptions = {
        ...
        data: response.data,
        ...
      }

      this.chart = new CanvasJS.Chart("chartContainer", chartOptions);
      this.chart.render();
    })
    .catch((error) => { console.log(error) })
}

推荐阅读