Echart 对象从 eChart 更改为 '<div>..' 未捕获类型错误:myChart.value.setOption 不是函数

问题描述 投票:0回答:1

我正在使用 vue 通过 VUE 动态折线图显示数据。在父 VUE 中,我请求服务器获取每个数据点,然后将它们传递给子 VUE。现在我在子 VUE 中显示数据点时遇到一个问题,“Uncaught TypeError: myChart.value.setOption is not a function”。子VUE冷如下,很奇怪,在函数startDataGeneration()中,myChart.value从eChart对象变成了'..'。控制台如下所示,但是,如果我删除父 VUE 中的参数(例如,这个问题不存在,但我无法删除它,因为我需要将数据传递给子 VUE。

在此输入图片描述

//In parent.VUE
<DashGPUPowerUsage :gpuPower="state.gpuPower" :isGPUPowerLoading="state.isGPUPowerLoading" />
//This is child VUE DashGPUPowerUsage.vue
<template>
    <div ref="myChart" style="width: 100%; height: 400px;"></div>
</template>

<script setup>
import { onMounted, ref, watch } from 'vue';
import * as echarts from 'echarts';

const props = defineProps({
    gpuPower: null,
    isGPUPowerLoading: Boolean,
});

// Create a reference for the chart container
const myChart = ref(null);
let seriesData = ref([]);
const isFirstUpdate = ref(true);

const initChart = () => {
    myChart.value = echarts.init(myChart.value);
    // Set an initial chart option, without any series data yet
    myChart.value.setOption({
        title: {
            text: "Dynamic Data & Time Axis",
        },
        tooltip: {
            trigger: "axis",
            formatter: (params) => {
                return params
                    .map(
                        (param) =>
                            `${param.seriesName}<br/>Time: ${param.name}<br/>Value: ${param.value[1].toFixed(
                                3
                            )}`
                    )
                    .join("<br/>");
            },
            axisPointer: {
                animation: false,
            },
        },
        xAxis: {
            type: "time",
            boundaryGap: false,
            data: [], // Initial empty data
        },
        yAxis: {
            type: "value",
            boundaryGap: [0, "100%"],
        },
        series: [], // Empty series initially
    });
};


const generateNewData = () => {
    for (const hostIp in props.gpuPower) {
        const hostData = props.gpuPower[hostIp];
        if (hostData && hostData.data && Array.isArray(hostData.data.result)) {
            const resultData = hostData.data.result;

            resultData.forEach((gpuInfo) => {
                const uuid = gpuInfo.metric.UUID;
                const timestamp = gpuInfo.value[0];
                const powerUsage = parseFloat(gpuInfo.value[1]);

                const date = new Date(timestamp * 10000);
                const currentSeriesData = seriesData.value.find((series) => series.uuid === uuid);
                if (currentSeriesData) {
                    currentSeriesData.data.push({
                        name: date.toString(),
                        value: [date, powerUsage]
                    });

                    //set max Data Points to be shown in the chart
                    if (currentSeriesData.data.length > 2000) {
                        currentSeriesData.data.shift();
                    }
                } else {
                    seriesData.value.push({
                        name: gpuInfo.metric.modelName,
                        uuid: uuid,
                        type: 'line',
                        showSymbol: false,
                        data: [
                            {
                                name: date.toDateString(),
                                value: [date, powerUsage]
                            }
                        ]
                    })
                }
            })

        }
    }
}

const updateChart = () => {
    if (!seriesData.value) return; // If seriesData is null, skip the update
    myChart.value.setOption({
        xAxis: {
            data: seriesData.value[0].data.map((item) => item.value[0]),
        },
        series: seriesData.value,
    });
};

const startDataGeneration = () => {
    console.log('BEFORE POWER: ', myChart.value)
    setInterval(() => {
        console.log('AFTER POWER: ', myChart.value)
        generateNewData();
        updateChart();
    }, 1000); // Update chart every second
};


onMounted(() => {
    // Initialize seriesData to an array once the component is mounted
    seriesData.value = [
        {
            "name": "NVIDIA GeForce RTX 3090",
            "uuid": "GPU-eaff73fa-41bd-b365-3f0d-a3bb4c921c48",
            "type": "line",
            "showSymbol": false,
            "data": [
                {
                    "name": "Sun Sep 04 2518",
                    "value": [
                        "2518-09-05T02:30:34.560Z",
                        17.668
                    ]
                }
            ]
        },
        {
            "name": "NVIDIA RTX A6000",
            "uuid": "GPU-3a679677-ef7f-78ee-217e-a1552b8e79f1",
            "type": "line",
            "showSymbol": false,
            "data": [
                {
                    "name": "Sun Sep 04 2518",
                    "value": [
                        "2518-09-05T02:30:34.489Z",
                        26.318
                    ]
                }
            ]
        },
        {
            "name": "NVIDIA GeForce RTX 3090",
            "uuid": "GPU-ff3ad650-f347-686c-e061-a287e28136e2",
            "type": "line",
            "showSymbol": false,
            "data": [
                {
                    "name": "Sun Sep 04 2518",
                    "value": [
                        "2518-09-05T02:30:34.489Z",
                        10.42
                    ]
                }
            ]
        },
        {
            "name": "NVIDIA A100-PCIE-40GB",
            "uuid": "GPU-17f4ff58-3e4e-eb03-d93f-65eafd6c9068",
            "type": "line",
            "showSymbol": false,
            "data": [
                {
                    "name": "Sun Sep 04 2518",
                    "value": [
                        "2518-09-05T02:30:34.489Z",
                        39.201
                    ]
                }
            ]
        },
        {
            "name": "Tesla V100-PCIE-16GB",
            "uuid": "GPU-a4388fa4-5170-baea-3e17-cdc3b0adbf94",
            "type": "line",
            "showSymbol": false,
            "data": [
                {
                    "name": "Sun Sep 04 2518",
                    "value": [
                        "2518-09-05T02:30:34.489Z",
                        36.936
                    ]
                }
            ]
        }
    ];

    // Now that seriesData is initialized, set the chart and start data generation
    initChart();
    startDataGeneration();
});

</script>

解释为什么会发生这种情况,或者如何正确传递数据?

vue.js linechart
1个回答
0
投票

myChart
是模板引用,不应手动覆盖。不需要使图表实例具有反应性,因此它可以只是一个变量而不是引用:

let chartInstance;

const initChart = () => {
    chartInstance = echarts.init(myChart.value);
    ...
© www.soinside.com 2019 - 2024. All rights reserved.