Chart.js 中未显示折线图

mur*_*ra1 5 javascript charts typescript reactjs chart.js

问题比较突出,我看不到图形的线条,按任何按钮时都看不到。X 轴的时间应根据按下的按钮相应地更改我已经查看文档已有一段时间了,但仍然无法弄清楚。

图表数据

import React, { useRef, useEffect, useState } from "react";
import { historyOptions } from '../chartConfig/chartConfig';
import 'chartjs-adapter-moment';
import annotationPlugin from 'chartjs-plugin-annotation';
import { Chart, registerables } from 'chart.js';
Chart.register(...registerables);
Chart.register(annotationPlugin);



const determineTimeFormat = (
  timeFormat: string,
  day: any,
  week: any,
  year: any
) => {
  switch (timeFormat) {
    case "24h":
      return day;
    case "7d":
      return week;
    case "1y":
      return year;
    default:
      return day;
  }
};

interface Props {
  data: any
}

const ChartData: React.FC<Props> = ({ data }) => {
  const chartCanvasRef = useRef<HTMLCanvasElement | null>(null);
  const { day, week, year, detail } = data;
  const [timeFormat, setTimeFormat] = useState("24h");
  const [isRebuildingCanvas, setIsRebuildingCanvas] = useState(false);
  
 

  useEffect(() => {
    setIsRebuildingCanvas(true);
  }, [timeFormat]);

  useEffect(() => {
    if (isRebuildingCanvas) {
      setIsRebuildingCanvas(false);
    }
  }, [isRebuildingCanvas]);

  useEffect(() => {
      if (chartCanvasRef && chartCanvasRef.current && detail) {
    const chartCanvas = chartCanvasRef.current
    if (isRebuildingCanvas || !chartCanvas) {
      return;
    }
  
    const chartInstance = new Chart(chartCanvasRef.current, {
      type: "line",
      data: {
        datasets: [
          {
            label: `${detail.name} price`,
            data: determineTimeFormat(timeFormat, day, week, year),
            backgroundColor: "rgba(134,159,152, 1)",
            borderColor: "rgba(174, 305, 194, 0.4",

          },
        ],
      },

Run Code Online (Sandbox Code Playgroud)

选项

  options: {     
        plugins: {
          annotation: {
            annotations: {
           
            }
          }
        },
      
        animations: {
          tension: {
            duration: 1000,
            easing: 'linear',
            from: 1,
            to: 0,
            loop: true
          }
        },
        maintainAspectRatio: false,
        responsive: true,
        scales: {
          x: 
            {         
              type: 'time',
            },  
        },
      }
    });
    return () => {
      chartInstance.destroy();
    }
  }}, [day, isRebuildingCanvas,timeFormat, week, year, detail]);
Run Code Online (Sandbox Code Playgroud)

其余组件代码


return (
    <div className='chart__container'>
    {renderPrice()}
      {isRebuildingCanvas ? undefined : (
        <canvas ref={chartCanvasRef} id='myChart' width={250} height={250}></canvas>
      )}
      <button className='time__format' onClick={() => setTimeFormat("24h")}>24h</button>
      <button className='time__format' onClick={() => setTimeFormat("7d")}>7d</button>
      <button className='time__format'  onClick={() => setTimeFormat("1y")}>1y</button>
    </div>
  );
};

export default ChartData;
Run Code Online (Sandbox Code Playgroud)

小智 1

看来你的isRebuildingCanvas逻辑可能不一致,或者我不明白。

无论如何,从 Chart.js 的角度来看,您希望更改数据并chartInstance.update()在按下更改数据的按钮时调用。

部分示例:

  const canvas = useRef(null);
  const [chart, setChart] = useState();
  const [timeFormat, setTimeFormat] = useState("24h");

  useEffect(() => {
    if (chart || !canvas.current) return;
    const ctx = canvas.current.getContext("2d");
    if (!ctx) return;

    const config = {/*...*/};

    setChart(new Chart(ctx, config));
  }, [chart, canvas]);

  useEffect(() => {
    if (!chart) return;

    chart.config.data.datasets[0].data = determineTimeFormat(timeFormat, day, week, year);
    chart.update();
  }, [chart, timeFormat]);
Run Code Online (Sandbox Code Playgroud)

还有一个完整的、非常相似的示例: https ://codesandbox.io/s/blissful-faraday-hzcq0