Skip to content

Tooltip/Legend colors don't match pie chart when using custom shape #6966

Description

@mryan-centigrade

What is the current behavior?

WIth the deprecation of the Cell component in v3.7.0, I followed the guide here to migrate to using the shape prop. However, after doing so, I found that the Legend and Tooltip components no longer display the expected colors.

I have a workaround, which I'll post below, but the issue seems to be that the payload the Tooltip and Legend content renderers receive is empty. This does not occur when using the Cell component.

Image

What is the expected behavior?

Image

Please provide a demo of the problem in a sandbox

https://stackblitz.com/edit/mgsuqetn?file=src%2FExample.tsx

Which versions of Recharts, and which browser / OS are affected by this issue? Did this work in previous versions of Recharts?

Affected version: v3.7.0 (using the shape prop)

Current workaround

Below is a snippet of code from the project I'm working on. For Legend, I'm mapping the chart data to the payload shape that DefaultLegendContent expects and rendering it manually. For Tooltip, I'm using activeIndex to find the data I'm interested in.

import {
  Tooltip,
  Legend,
  PieChart,
  Pie,
  Sector,
  DefaultLegendContent,
} from 'recharts'

<PieChart width={320} height={210}>
  <Pie
    cx="45%"
    cy="50%"
    innerRadius={65}
    outerRadius={100}
    paddingAngle={2}
    dataKey="value"
    data={chartData}
    shape={(props) => (
      <Sector
        {...props}
        className="chart-cell"
        fill={colors[props.name] ?? '#8884d8'}
      />
    )}
  />
  <Legend
    layout="vertical"
    iconType="square"
    iconSize={6}
    formatter={(value) => (
      <span className="ml-xs body-sm text-secondary capitalize">{value}</span>
    )}
    align="right"
    verticalAlign="middle"
    itemSorter={(item) => {
      const index = chartData.findIndex((entry) => entry.name === item.value)
      return index !== -1 ? index : Infinity
    }}
    content={(props) => {
      const payload = chartData.map((entry) => ({
        color: colors[entry.name] ?? '#8884d8',
        payload: entry,
        type: props.iconType,
        value: entry.name,
      }))
      return <DefaultLegendContent {...props} payload={payload} />
    }}
  />
  <Tooltip
    content={(props) => {
      const activeIndex = props.activeIndex ? Number(props.activeIndex) : -1
      const entry = activeIndex !== -1 ? chartData[activeIndex] : null
      return (
        <div
          className="chart-tooltip"
          style={{
            visibility: entry ? 'visible' : 'hidden',
          }}
        >
          <div className="flex items-center">
            <div
              className="w-sm h-sm rounded-full mr-xs"
              style={{
                backgroundColor: colors[entry.name] ?? '#8884d8',
              }}
            />
            <span className="capitalize">{entry?.name}</span>
          </div>
          <span className="font-semibold">{entry?.value.toLocaleString()}</span>
        </div>
      )
    }}
  />
</PieChart>

Metadata

Metadata

Assignees

Labels

bugGeneral bug label

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions