Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Charts - Display pie chart despite zero values (Equally distribute sections and display colorized chart when all the values are zero)

So react-charts-js-2 by default hides the chart when both values are zero. We're trying to avoid 'No data available' sort of messages or displaying icons that represent no value. What we desire to achieve is to display the chart regardless of whether the values are zero or not, halve the chart (preserve the calculated colors (one primary color and one lightened up color)) and also display the zero values on hover.

Is this achievable ?

*This occurs only when BOTH values are zero. (All N values, in my case N === 2)

The desired output when all the values are zero is attached below

enter image description here

import { Pie } from "react-chartjs-2";
import { ArcElement, Chart as ChartJS, Legend, Tooltip } from "chart.js";
ChartJS.register(ArcElement, Tooltip, Legend);


const LimitChart = ({ data, sectorNameBySectorCode }: { data: ISectorLimit, sectorNameBySectorCode: string }) => {

  const { t } = useTranslation();

  const bothZero = !data.remainingLimit && !data.usedLimit;

  const chartData = React.useMemo(() => {
    return {
      labels: [t("label.remainingLimit"), t("label.usedLimit")],
      datasets: [
        {
          data: [data.remainingLimit || 0.1, data.usedLimit || 0.1],
          backgroundColor: [
            chartColorLookup[sectorNameBySectorCode as SectorNames].secondary,
            chartColorLookup[sectorNameBySectorCode as SectorNames].primary
          ],
          borderWidth: 2,
        },
      ],
    };
  }, [data]);

  return (
    <Pie data={chartData} width={200} height={200}/>
  );
};
like image 697
emre-ozgun Avatar asked Sep 20 '25 13:09

emre-ozgun


1 Answers

Conditionally rendering super small values resolved my issue.

  const bothZero = !data.remainingLimit && !data.usedLimit
  const conditionalData = bothZero
    ? [1e-10, 1e-10]
    : [data.remainingLimit, data.usedLimit];

  const chartData = React.useMemo(() => {
    return {
      labels: [t("label.remainingLimit"), t("label.usedLimit")],
      datasets: [
        {
          data: conditionalData,
          backgroundColor: [secondary, primary],
          hoverBackgroundColor: [secondary, primary],
          borderWidth: 4,
        },
      ],
    };
  }, [data]);
// Standardized solution for N values (Might be handy if the number of fields is not known ahead of time) - Assumes that data is object

const allZero = Object.values(data).every(value => isZero(value));

const conditionalData = allZero
  ? Array(Object.keys(data).length).fill(1e-10)
  : Object.values(data);

enter image description here

like image 123
emre-ozgun Avatar answered Sep 22 '25 10:09

emre-ozgun