Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gradient bar charts with react & chart.js

I want to have a horizontal bar chart with react and chart.js and react-chartjs-2 this chart should be divided in tow part yellow and red when the data is change for example.like this image but the issue is that it show all charts in red.

You can see my complete code - this my bar-Chart componen :

   import React, { useEffect, useState } from "react";
   import Chart from "chart.js/auto";
   import { Bar } from "react-chartjs-2";

   import "./BarChart.css";

   const BarChart = (props) => {
       const [Chartdata, setData] = useState(null);

       useEffect(() => {
        console.log(props);

        setData({
         labels: props.labels,
        datasets: [
           {
           label: props.globalLabel,
           data: props.data,
           backgroundColor: (context) => {
           const { ctx, chartArea, scales } = context.chart;
           if (!chartArea || !props.colorData) return null;
           const { top, bottom, left, right } = chartArea;
            const { x, y } = scales;
            let gradients = [];
            const colorDataLength = props.colorData.length;
            if (colorDataLength !== props.data.length) return null;
            for (let i = 0; i < colorDataLength; i++) {
              const gradientSegment = ctx.createLinearGradient(
               0,
               left,
               0,
               right
              );
              gradientSegment.addColorStop(0, props.colorData[i][0].color);

              for (let j = 1; j < props.colorData[i].length - 1; j++) {
            // props.colorData[i][j].point
            //props.colorData[i][j].color
  
               let border =
                 (right - x.getPixelForValue(props.colorData[i][j].point)) /
                 (right - left);
                 console.log(border);
                 if (border > 1) border = 1;
                   gradientSegment.addColorStop(
                      border,
                    props.colorData[i][j - 1].color
                    );
                    gradientSegment.addColorStop(
                     border,
                     props.colorData[i][j].color
                   );
                   }

                 gradientSegment.addColorStop(
                 1,
                props.colorData[i][props.colorData[i].length - 1].color
               );
             gradients.push(gradientSegment);
            }

            return gradients;
            },
             borderColor: props.borderColor || "rgb(100,150,150)",
            borderWidth: 1,
          },
           ],
          });
          }, [props]);

  return (
    <div className={`${props.className} bar--height`}>
     {!!Chartdata && (
       <Bar
          options={{
             indexAxis: "y", // Rotate the chart horizontally
             maintainAspectRatio: false,
              responsive: true,
             scales: {
               x: {
                 beginAtZero: true,
              },
              y: {
                beginAtZero: true,
             },
            },
         }}
           data={Chartdata}
        />
       )}
    </div>
  );
  };

  export default React.memo(BarChart);

in main comp:

   <BarChart
      data={Array(7).fill(10)}
      labels={DUUMYY_LABLES}
      colorData={colorData}
      className="AnalyticCharts--charts--div"
    />

color data looks like this:

[
[
    {
        "point": 0,
        "color": "red"
    },
    {
        "point": 10,
        "color": "red"
    }
],
[
    {
        "point": 0,
        "color": "red"
    },
    {
        "point": 5,
        "color": "yellow"
    },
    {
        "point": 7,
        "color": "red"
    },
    {
        "point": 10,
        "color": "red"
    }
],
[
    {
        "point": 0,
        "color": "red"
    },
    {
        "point": 10,
        "color": "red"
    }
],
[
    {
        "point": 0,
        "color": "red"
    },
    {
        "point": 10,
        "color": "red"
    }
],
[
    {
        "point": 0,
        "color": "red"
    },
    {
        "point": 10,
        "color": "red"
    }
],
[
    {
        "point": 0,
        "color": "red"
    },
    {
        "point": 10,
        "color": "red"
    }
],
[
    {
        "point": 0,
        "color": "red"
    },
    {
        "point": 10,
        "color": "red"
    }
]]

I want to see my second bar in red color from 0 to 5 and then in yellow from 5 to 7 and again red from 7 to 10

like image 792
AmirHossein_Khakshouri Avatar asked Nov 28 '25 14:11

AmirHossein_Khakshouri


1 Answers

for chart to behave correctly, I should change these lines and it will be fine:

            const gradientSegment =  
             ctx.createLinearGradient(right,0,left,0);

           let border =
              (left - x.getPixelForValue(props.colorData[i][j].point)) /
              (left - right);
like image 121
AmirHossein_Khakshouri Avatar answered Nov 30 '25 02:11

AmirHossein_Khakshouri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!