Home > Net >  how to create a react-chart.js gradient line in typescript
how to create a react-chart.js gradient line in typescript

Time:01-03

I am trying to create a gradient line using react-chartjs-2 and typescript

Evertything is fine up to the point where i am trying to create a gradient line, This is where typescript throws an error i am having a hard time getting rid off.

here is the component code :

import { useRecoilValue } from "recoil"
import { currencies, symbol } from "../../state/atoms"
import moment from 'moment';

import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';
import { Line } from 'react-chartjs-2';
import Actions from "../Actions";

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend
);

const CurrencyGraph = () => {
  //getting graph numeric infos from the Recoil store
  const apiSymbol = useRecoilValue(symbol)
  const currencyInfos = useRecoilValue(currencies)

  // computing price array for the Y axis
  const prices = currencyInfos.map((item) => item[4])
  const priceLabel = prices.map(price => Number(price))

  // computing hours array for the X axis
  const time = currencyInfos.map((item) => item[6])
  let hours = time.map(time => moment.unix(Number(time)/1000).format("hh A"))
 
  // not displaying the grid by default
  ChartJS.defaults.scale.grid.display = false;

  const options = {
    responsive: true,
    scales: {
        y: {
            ticks: {
                // Include a dollar sign in the ticks
                callback: function(value:any, index:any, values:any) {
                    return '$'   value;
                }
            }
        }
    },
    plugins: {
      legend: {
        position: 'top' as const,
      },
      title: {
        display: true,
        text: apiSymbol,
      },
    },
  };

  //using canvas.getContext to create a gradient 
  const data = (canvas: { getContext: (arg0: string) => any; }) => {
    const ctx = canvas.getContext("2d");
    const gradient = ctx.createLinearGradient(0, 0, 0, 200);
    gradient.addColorStop(0, 'rgba(250,174,50,1)');   
    gradient.addColorStop(1, 'rgba(250,174,50,0)');

    const result = {
      labels: hours,
      datasets: [
        {
          label: 'currency value in $',
          data : priceLabel,
          tension:0.5,
          pointStyle: 'circle',
          pointRadius:1,
          pointBorderWidth:0,
          pointBorderColor:'black',
          borderWidth:2,
          backgroundColor: 'black',
          fill:true,
          borderColor: gradient,
          
        },
      ]
    }
    return result
  }

  return (
    <div className="graph">  
     <Line options={options} data={data} />
     <Actions />
    </div>
  )
}

export default CurrencyGraph

then i cannot compile because typescript is throwing this error :

TS2741: Property 'datasets' is missing in type '(canvas: { getContext: (arg0: string) => any; }) => { labels: string[]; datasets: { label: string; data: number[]; tension: number; pointStyle: string; pointRadius: number; pointBorderWidth: number; pointBorderColor: string; borderWidth: number; backgroundColor: string; fill: boolean; borderColor: any; }[]; }' but required in type 'ChartData<"line", (number | ScatterDataPoint | null)[], unknown>'.
    115 |   return (
    116 |     <div className="graph">  
  > 117 |      <Line options={options} data={data} />
        |                                   ^^^^^^
    118 |      <Actions />
    119 |     </div>
    120 |   )

I am probably not understanding very weel what typescript is telling me. I did try and add a type to data like so :

type dataType = {
labels: [],
datasets: []
}

and then adding the type to my function, but it odes not work so well, i get the same error

thanks to anyonwe who can help !!

CodePudding user response:

Change const data = (canvas: { getContext: (arg0: string) => any; }) to

const data = (canvas: HTMLCanvasElement) => {}

And in the return do

<Line options={options} data={data(canvasRef)} />

You will have to pass the ref of your canvas element to the data function

  • Related