skip to Main Content

Everyone,

I was migrating react-chartjs-2 from v2 to v5 but, and here is my code, I lost the gradient color, which is not working in v5. and not be able to figure out what was wrong or what I missed here. I am sharing the code. Please help me out on this.

Here is my v2 code | old code

import React from 'react';
import { Line as LineChart } from 'react-chartjs-2';
import { formatCurrency } from './../util';

const DashboardChart = ({ salesData }) => {
  const chartLabels = salesData.map(sale => sale.date);
  const chartValues = salesData.map(sale => sale.amount);

  const chartData = canvas => {
    const ctx = canvas.getContext('2d');
    var gradientFill = ctx.createLinearGradient(
      0,
      0,
      0,
      250
    );
    gradientFill.addColorStop(0, 'rgba(0, 97, 215, 0.3)');
    gradientFill.addColorStop(1, 'rgba(0, 200, 255, 0)');
    console.log(gradientFill)
    return {
      labels: chartLabels,
      datasets: [
        {
          label: 'Sales',
          borderColor: '#3182ce',
          data: chartValues,
          backgroundColor: gradientFill
        }
      ]
    };
  };

  return (
    <LineChart
      height={100}
      data={chartData}
      options={{
        elements: {
          line: {
            tension: 0.3,
            borderWidth: 1.5
          },
          point: { radius: 0 }
        },
        scales: {
          yAxes: [
            {
              ticks: {
                callback: value => formatCurrency(value)
              }
            }
          ]
        }
      }}
    />
  );
};

export default DashboardChart;

Here is my v5 code | latest code

import React, { useEffect, useRef } from 'react';
import { Line } from 'react-chartjs-2';
import { formatCurrency } from '../util';

import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
  Filler
} from 'chart.js';

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

const useCanvasGradient = (canvasRef, chartValues) => {
  useEffect(() => {
    const canvas = canvasRef.current;
    const ctx = canvas?.getContext('2d');

    if (ctx) {
      const gradientFill = ctx.createLinearGradient(0, 0, 0, 250);
      gradientFill.addColorStop(0, 'rgba(0, 97, 215, 0.3)');
      gradientFill.addColorStop(1, 'rgba(0, 200, 255, 0)');

      ctx.fillStyle = gradientFill;
      ctx.fillRect(0, 0, canvas.width, canvas.height);

      // Set the background color of the chart to the canvas pattern
      chartValues.backgroundColor = ctx.createPattern(canvas, 'repeat');
    }
  }, [canvasRef, chartValues]);
};

const DashboardChart = ({ salesData }) => {
  const chartLabels = salesData.map(sale => sale.date);
  console.log(JSON.stringify(chartLabels))
  const chartValues = {
    label: 'Sales',
    borderColor: '#3182ce',
    data: salesData.map(sale => sale.amount),
  };
  console.log(JSON.stringify(chartValues))
  const canvasRef = useRef(null);

  useCanvasGradient(canvasRef, chartValues);

  const chartData = {
    labels: chartLabels,
    datasets: [chartValues],
  };

  const options = {
    responsive: true,
    elements: {
      line: {
        tension: 0.3,
        borderWidth: 1.5,
      },
      point: { radius: 0 },
    },
    scales: {
      y: {
        ticks: {
          callback: value => formatCurrency(value),
        },
      },
    },
  };

  return (
    <>
      <canvas ref={canvasRef} id="canvasId" width={500} height={500} style={{ display: 'none' }} />
      <Line
        height={100}
        data={salesData ? chartData : null}
        options={options}
      />
    </>
  );
};

export default DashboardChart;

and also i am sharing the screenshot of v2 and v5

here is the v2 screenshot

here is the v5 screenshot

Also sharing live code URL 🔗

Here is another live example just re-verified the color which i am using is correct or not using vanilaJS – Live Example

2

Answers


  1. Chosen as BEST ANSWER
    // Add lables & data and options is outside of the component so to avoid re-rendering
    
    const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
    
    export const data = {
      labels,
      datasets: [
        {
          label: 'Dataset 1',
          data: [1902, 893, 1293, 723, 2341, 2113, 236, 578, 912, 2934, 345, 782],
          borderColor: '#3182ce',
          fill: true,
        },
      ],
    };
    
    const options = {
        responsive: true,
        elements: {
          line: {
            tension: 0.3,
            borderWidth: 1.5,
          },
          point: { radius: 0 },
        },
        scales: {
          y: {
            ticks: {
              callback: (value) => value,
            },
          },
        },
      };
    
    
    // saprate a function which is responsible of gradient
    function createGradient(ctx: CanvasRenderingContext2D) {
      const gradient = ctx.createLinearGradient(0, 0, 0, 250);
    
      gradient.addColorStop(0, 'rgba(0, 97, 215, 0.4)');
      gradient.addColorStop(1, 'rgba(0, 200, 255, 0)');
    
      return gradient;
    }
    
    
    function App() {
      const chartRef = useRef<ChartJS>(null);
      const [chartData, setChartData] = useState<ChartData<'bar'>>({
        datasets: [],
      });
    
      useEffect(() => {
        const chart = chartRef.current;
    
        if (!chart) {
          return;
        }
    
        const chartData = {
          ...data,
          datasets: data.datasets.map((dataset) => ({
            ...dataset,
            backgroundColor: createGradient(chart.ctx),
          })),
        };
    
        setChartData(chartData);
      }, []);
    
      return (
        <Fragment>
          <h1>react-chartjs-2 | chart.js</h1>
          <Chart ref={chartRef} type="line" data={chartData} options={options} />
        </Fragment>
      );
    }
    

    Also working example - 👇🏻

    I have fixed this issue and here is my code live Example

    I am sharing this because of might be if someone upgrading from v2 to v5 may be this will help him / her out.

    Thanks


  2. const chartValues = {
    …props,
    fill : true
    }

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search