Search code examples
reactjsrecharts

React reacharts barchart not showing LabelList on first time render


import React, { Fragment, useCallback } from "react";
import {
  BarChart,
  Bar,
  ResponsiveContainer,
  Cell,
  LabelList,
  YAxis,
} from "recharts";
import { fontSizes, textColors } from "styles/theme";

const CustomLabelImage = (props: any) => {
  const { x, y, value } = props;
  return (
    <Fragment key={`${Math.random()}`}>
      <image
        x={+x! - 5}
        clipPath={"circle(40%)"}
        y={y - 105}
        width={55}
        height={55}
        href={value}
      />
    </Fragment>
  );
};
const CustomLabel = (props: any) => {
  const { x, y, value } = props;
  return (
    <Fragment key={`${Math.random()}`}>
      <text
        x={x}
        y={y}
        className="grotesk"
        style={{
          fontWeight: 600,
          fontSize: fontSizes.f20,
        }}
        dx={10}
        dy={-10}
        textAnchor="top"
        fill={textColors.sceptreBlue}
      >
        {value}
      </text>
    </Fragment>
  );
};

const CustomLabelName = (props: any) => {
  const { x, y, value } = props;
  return (
    <Fragment key={`${Math.random()}`}>
      <text
        x={x}
        y={y}
        className="grotesk"
        style={{
          fontWeight: 300,
          fontSize: fontSizes.f10,
        }}
        dx={-4}
        dy={-35}
        textAnchor="top"
        fill={textColors.sceptreBlue}
      >
        {value?.split(" ")[0]} {value?.split(" ")[1]?.slice(0, 1)}
      </text>
    </Fragment>
  );
};

export default function BarChartRedList({
  data,
  color,
}: {
  data: { time: string; lost: number; avatar?: string }[];
  withLabel?: boolean;
  withAvatar?: boolean;
  color?: string;
}) {
  const renderItems = useCallback(() => {
    return (
      <Fragment>
        {data.map((item, index) => {
          return (
            <Fragment key={`${item.lost}_${index}`}>
              <LabelList
                dataKey="avatar"
                position="top"
                key={`cell3-${index}`}
                width={100}
                offset={10}
                content={<CustomLabelImage />}
              />
              <LabelList
                dataKey="time"
                key={`cell2-${index}`}
                position="top"
                offset={10}
                width={100}
                content={<CustomLabelName />}
              />
              <LabelList
                dataKey="lost"
                position="top"
                key={`cell1-${index}`}
                offset={5}
                width={"100px"}
                content={<CustomLabel />}
              />
              <Cell
                radius={8}
                key={`cell-${index}`}
                width={40}
                offset={20}
                fill="url(#barGradient)"
              />
            </Fragment>
          );
        })}
      </Fragment>
    );
  }, [data]);

  return (
    <div>
      <ResponsiveContainer height={350}>
        <BarChart
          width={500}
          height={200}
          data={data}
          margin={{
            top: 120,
            right: 0,
            left: 0,
            bottom: 20,
          }}
        >
          <defs>
            <linearGradient id="barGradient" x1="0" y1="0" x2="0" y2="1">
              <stop offset="5%" stopColor={color} stopOpacity={1} />
              <stop offset="95%" stopColor={color} stopOpacity={0.2} />
            </linearGradient>
          </defs>
          <Bar yAxisId="left" dataKey="lost">
            {renderItems()}
          </Bar>
        </BarChart>
      </ResponsiveContainer>
    </div>
  );
}

First time after window loaded After button clicks

I trying to render barchart with image but it is not worked as i expected. First time after window loaded image and texts not visible but after some actions it will be visible. I cannot fix this. Help me how can I fix this issue?

my packages versions "recharts": "^2.4.3", "next": "13.4.7", "react": "18.2.0",


Solution

  • After some research I have found solution

    <Bar 
       yAxisId="left"
       dataKey="lost"
       isAnimationActive={false} //added this
    >
      {renderItems()}
    </Bar>