5

The problem is quite forward, I can't see the line of the graph, and when I press any button. The time of the X-axes should change accordingly to which button is pressed I have been looking through the documentation, for quite some time, but still can't figure it out.

ChartData

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",

          },
        ],
      },

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 code


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;
10
  • 1
    "I can see the bar" -- only one bar? Commented May 25, 2021 at 19:54
  • @aleksxor What do you mean? Commented May 25, 2021 at 20:08
  • 1
    Well, if you're seeing only one bar on the chart then switching it to "line" definitely wouldn't help. Line can be drawn only between two points at least. Commented May 25, 2021 at 20:11
  • 2
    To draw a line you have to have at least two points. One bar indicates you have only one. Commented May 25, 2021 at 20:25
  • 2
    If you want a line in a line graph you will need to have at least 2 points because thats how chart.js draws lines, between points so you will need at least 2 data entries in your data array Commented May 30, 2021 at 15:28

1 Answer 1

1

Looks like your isRebuildingCanvas logic might be inconsistent, or I don't just understand it.

Anyway, from the Chart.js perspective, you'd want to change the data and call chartInstance.update() when pressing the button that changes the data.

Partial example:

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

And a complete, very similar example: https://codesandbox.io/s/blissful-faraday-hzcq0

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.