简体   繁体   中英

Can't change the time of the xAxes in the Chart.js

So I have ChartData Component. I am taking the data from an API, the data is being displayed through Chart. I have determine Format Logic , which it's the main thing is to determine the time of the data, I have 3 buttons, the thing that I am struggling to achieve is when let's say I wanna see the data of 7days when I press the button. I can see data is changing in the yAxes but I can't see time being changed on the xAxes , it's still set to hours, it should display the days.

ChartData

import React, { useRef, useEffect, useState } from "react";
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",
          },        
        ],
      },

Options

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]);

Rest of the Component

return (
    <div className='chart__container'>
    {renderPrice()}
      {isRebuildingCanvas ? undefined : (
        <canvas ref={chartCanvasRef}  width={250} height={250} id='myChart'></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;

I have created a similar working example without reactjs. This can be useful for you to understand. You can refer the fiddle as well. A limitation that am currently facing is if there is data more than 100 then am getting errors while updating the data, performed slicing of data upto 100 to make it working.

 var coinData = {}; var fetchData = async() => { api = "https://api.coingecko.com/api/v3"; id = "bitcoin"; var [day1, week1, year1, detail1] = await Promise.all([ fetch(api + `/coins/${id}/market_chart/?vs_currency=usd&days=1`).then(data => { return data.json() }), fetch(api + `/coins/${id}/market_chart/?vs_currency=usd&days=7`).then(data => { return data.json() }), fetch(api + `/coins/${id}/market_chart/?vs_currency=usd&days=365`).then(data => { return data.json() }), fetch(api + `/coins/markets/?vs_currency=usd&ids=${id}`).then(data => { return data.json() }) ]); coinData = { day: formatData(day1.prices).slice(0, 100), week: formatData(week1.prices).slice(0, 100), year: formatData(year1.prices).slice(0, 100), detail: detail1[0] } } const formatData = (data) => { return data.map((el) => { return { t: el[0], y: el[1].toFixed(2) }; }); }; const determineTimeFormat = (timeFormat) => { switch (timeFormat) { case "24h": return coinData.day; case "7d": return coinData.week; case "1y": return coinData.year; default: return coinData.day; } }; var chartInstance; fetchData().then(() => { /* console.log(coinData); */ var ctx = document.getElementById('chartJSContainer'); chartInstance = new Chart(ctx, { type: "line", labels: false, data: { datasets: [{ label: `${coinData.detail.name} price`, data: determineTimeFormat('1d'), parsing: { yAxisKey: 'y', xAxisKey: 't', }, backgroundColor: "rgba(134,159,152, 1)", borderColor: "rgba(174, 305, 194, 0.4)" }], }, options: { scales: { x: { ticks: { source: "data" }, type: 'time', time: { unit: "day" } } }, } }); }); function setTimeFormat(format) { Chart.instances[0].data.datasets[0].data = determineTimeFormat(format); Chart.instances[0].update(); }
 <script src="https://cdn.jsdelivr.net/npm/chart.js@3.3.1/dist/chart.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@1.0.0/dist/chartjs-adapter-moment.min.js"></script> <body> <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><br><br> <canvas id="chartJSContainer" width="600" height="400"></canvas> </body>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM