【发布时间】:2021-08-03 06:42:31
【问题描述】:
我目前正在使用 Graph.js 渲染图形,它正在处理初始渲染,但是直到我按下 setTimeformats 按钮以便在同一画布上显示另一个图形之前,它给了我错误:画布已经在使用中。必须先销毁 ID 为“0”的图表,然后才能重新使用画布。我是否正确使用它?我应该如何销毁图表以便在同一画布上使用其他图表?非常感谢您的帮助。
import React, { useRef, useEffect, useState } from "react";
import { historyOptions } from "../chartConfig/chartConfig";
import Chart from 'chart.js/auto';
interface Props{
data:any
}
const ChartData:React.FC<Props> = ({ data}) => {
const chartRef = useRef<HTMLCanvasElement | null>(null);
const { day, week, year, detail } = data;
const [timeFormat, setTimeFormat] = useState("24h");
const determineTimeFormat = () => {
switch (timeFormat) {
case "24h":
return day;
case "7d":
return week;
case "1y":
return year;
default:
return day;
}
};
useEffect(() => {
if (chartRef && chartRef.current && detail) {
const chartInstance = new Chart(chartRef.current, {
type: "line",
data: {
datasets: [
{
label: `${detail.name} price`,
data: determineTimeFormat(),
backgroundColor: "rgba(174, 305, 194, 0.5)",
borderColor: "rgba(174, 305, 194, 0.4",
pointRadius: 0,
},
],
},
options: {
...historyOptions,
},
});
if (typeof chartInstance !== "undefined") chartInstance.destroy();
}
});
const renderPrice = () => {
if (detail) {
return (
<>
<p className="my-0">${detail.current_price.toFixed(2)}</p>
<p
className={
detail.price_change_24h < 0
? "text-danger my-0"
: "text-success my-0"
}
>
{detail.price_change_percentage_24h.toFixed(2)}%
</p>
</>
);
}
};
return (
<div className="bg-white border mt-2 rounded p-3">
<div>{renderPrice()}</div>
<div>
<canvas ref={chartRef} id="myChart" width={250} height={250}></canvas>
</div>
<div className="chart-button mt-1">
<button
onClick={() => setTimeFormat("24h")}
className="btn btn-outline-secondary btn-sm"
>
24h
</button>
<button
onClick={() => setTimeFormat("7d")}
className="btn btn-outline-secondary btn-sm mx-1"
>
7d
</button>
<button
onClick={() => setTimeFormat("1y")}
className="btn btn-outline-secondary btn-sm"
>
1y
</button>
</div>
</div>
);
};
export default ChartData;
【问题讨论】:
-
每次你的状态或道具改变时都会触发你的 useEffect:see here。如果这是有意的,那么您可以在旧图表实例上调用
.destroy()(如果它存在),或者从它的外观来看,您只想交换第一个数据集中的数据,因此您可以在之后调用.update()改变数据。 api spec here -
其实很抱歉,我认为你不能轻易地保留画布实例(react 会在每次渲染时重新创建它),所以
.update()不会按预期工作。最好销毁它。 -
@CallumMorrisson 我已经更新了代码,可以这样工作
标签: javascript reactjs typescript