我正在使用 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>
解释为什么会发生这种情况,或者如何正确传递数据?
myChart
是模板引用,不应手动覆盖。不需要使图表实例具有反应性,因此它可以只是一个变量而不是引用:
let chartInstance;
const initChart = () => {
chartInstance = echarts.init(myChart.value);
...