[英]Lightning JS Chart causing crashes and not showing data correctly
我有一個組件,我想顯示一個包含多個線系列的圖表,代表過去 24 小時內的價格變化。 我有一個發送此數據的端點,我使用下面的代碼來顯示它。
其中一個問題來自似乎來自庫本身的錯誤,這意味着圖表甚至不會出現。 加載頁面時來自控制台的錯誤。
其他時候,頁面將加載一秒鍾,然后 go 白色並耗盡足夠的 CPU 導致崩潰。
圖形實際顯示在屏幕上的幾次,它不顯示任何線條,直到第 81-85 行被取消注釋,然后它顯示線條但不放大它們,在屏幕上留下一團糟。
任何幫助將非常感激。
/* eslint-disable new-cap */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-magic-numbers */
import React, { useEffect, useState } from "react";
import { LegendBoxBuilders, lightningChart, Themes } from "@arction/lcjs";
import "./TopCurrencyGraph.css";
import axios from "axios";
export interface data {
data: dataPoint[];
}
export interface dataPoint {
currency: string;
percentage: number;
timestamp: string;
}
interface graphPoint {
x: number;
y: number;
}
const TopCurrencyGraph = () => {
const historicalAddr = `http://${
process.env.back || "localhost:8000"
}/historical24hChangeData`;
useEffect(() => {
const map: { [name: string]: graphPoint[] } = {};
axios
.get(historicalAddr)
.then((res) => {
const { points } = res.data;
const pointList = points as dataPoint[];
pointList.forEach((obj) => {
const newPoint = {
x: new Date(obj.timestamp).getTime() * (60 * 24),
y: obj.percentage * 100,
};
if (obj.currency in map) {
map[obj.currency].push(newPoint);
} else {
map[obj.currency] = [newPoint];
}
});
})
.catch((err) => {
console.log(err, historicalAddr);
});
const chart = lightningChart().ChartXY({
theme: Themes.lightNew,
container: "currency-graph",
});
chart.setTitle("Top Currencies");
chart.getDefaultAxisX().setTitle("Time");
chart.getDefaultAxisY().setTitle("Percentage Change");
const entries = Object.entries(map);
const names = entries.map(([a, _b]) => a);
const lists = entries.map(([_, b]) => b);
const seriesArray = new Array(5).fill(null).map((_, idx) =>
chart
.addLineSeries({
dataPattern: {
pattern: "ProgressiveX",
},
})
// eslint-disable-next-line arrow-parens
.setStrokeStyle((stroke) => stroke.setThickness(1))
.setName(names[idx])
);
seriesArray.forEach((series, idx) => {
if (idx === 1) {
series.add(lists[idx]);
}
});
chart.addLegendBox(LegendBoxBuilders.HorizontalLegendBox).add(chart);
return () => {
chart.dispose();
};
}, []);
// done thnx
return (
<div className="graph-container">
<div id="currency-graph" className="graph-container"></div>
</div>
);
};
export default TopCurrencyGraph;
您的代碼看起來語法正確,但我相信您會遇到問題,因為您沒有正確管理異步代碼(axios 從您的端點獲取數據)。
const map: { [name: string]: graphPoint[] } = {};
axios
.get(historicalAddr)
.then((res) => {
// This code is NOT executed immediately, but only after some time later.
...
})
// This code and everything below is executed BEFORE the code inside `then` block.
// Because of this, you end up supplying `undefined` or other incorrect values to series / charts which shows as errors.
const chart = lightningChart().ChartXY({
theme: Themes.lightNew,
container: "currency-graph",
});
您可能會發現調試您提供給系列的值很有用,例如如下所示。 我認為這些值不是您所期望的。
seriesArray.forEach((series, idx) => {
if (idx === 1) {
console.log('series.add', lists[idx])
series.add(lists[idx]);
}
});
改進建議
這是我嘗試修改您提供的代碼以正確管理異步數據加載,方法是在處理數據后移動所有依賴於數據的代碼。
/* eslint-disable new-cap */
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-magic-numbers */
import React, { useEffect, useState } from "react";
import { LegendBoxBuilders, lightningChart, Themes } from "@arction/lcjs";
import "./TopCurrencyGraph.css";
import axios from "axios";
export interface data {
data: dataPoint[];
}
export interface dataPoint {
currency: string;
percentage: number;
timestamp: string;
}
interface graphPoint {
x: number;
y: number;
}
const TopCurrencyGraph = () => {
const historicalAddr = `http://${
process.env.back || "localhost:8000"
}/historical24hChangeData`;
useEffect(() => {
const chart = lightningChart().ChartXY({
theme: Themes.lightNew,
container: "currency-graph",
});
chart.setTitle("Top Currencies");
chart.getDefaultAxisX().setTitle("Time");
chart.getDefaultAxisY().setTitle("Percentage Change");
const seriesArray = new Array(5).fill(null).map((_, idx) =>
chart
.addLineSeries({
dataPattern: {
pattern: "ProgressiveX",
},
})
// eslint-disable-next-line arrow-parens
.setStrokeStyle((stroke) => stroke.setThickness(1))
);
chart.addLegendBox(LegendBoxBuilders.HorizontalLegendBox).add(chart);
axios
.get(historicalAddr)
.then((res) => {
const { points } = res.data;
const pointList = points as dataPoint[];
const map: { [name: string]: graphPoint[] } = {};
pointList.forEach((obj) => {
const newPoint = {
x: new Date(obj.timestamp).getTime() * (60 * 24),
y: obj.percentage * 100,
};
if (obj.currency in map) {
map[obj.currency].push(newPoint);
} else {
map[obj.currency] = [newPoint];
}
});
const entries = Object.entries(map);
const names = entries.map(([a, _b]) => a);
const lists = entries.map(([_, b]) => b);
seriesArray.forEach((series, idx) => {
series.setName(names[idx])
if (idx === 1) {
series.add(lists[idx]);
}
});
})
.catch((err) => {
console.log(err, historicalAddr);
});
return () => {
chart.dispose();
};
}, []);
// done thnx
return (
<div className="graph-container">
<div id="currency-graph" className="graph-container"></div>
</div>
);
};
export default TopCurrencyGraph;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.