13

Being not well-versed with Typescript yet, I am trying to create a custom Tooltip content for my Recharts chart in my React app with Typescript. @types/recharts has already been installed as one of the a devDependencies.

However, when I define the CustomTooltip function as shown below, Typescript is throwing an error

Binding element 'active' implicitly has an 'any' type. TS7031

How can we solve this issue?

const CustomTooltip = ({ active, payload, label }) => {
    if (active) {
        return (
        <div className="custom-tooltip">
            <p className="label">{`${label} : ${payload[0].value}`}</p>
            <p className="desc">Anything you want can be displayed here.</p>
        </div>
        );
    }

    return null;
}

return (
    <ComposedChart data={data}>
        ...
        <Tooltip content={<CustomTooltip />} />
    </ComposedChart>
)

Tried defining an interface, but got another error

Type '{}' is missing the following properties from type 'ICustomToolip': active, payload, label TS2739

interface ICustomToolip {
    active: any;
    payload: any;
    label: any;
}

const CustomTooltip = ({ active, payload, label }: ICustomToolip) => {
    if (active) {
        return (
        <div className="custom-tooltip">
            <p className="label">{`${label} : ${payload[0].value}`}</p>
            <p className="desc">Anything you want can be displayed here.</p>
        </div>
        );
    }

    return null;
}
Athena Wisdom
  • 6,101
  • 9
  • 36
  • 60

7 Answers7

31

Try to do the following (using rechart's types).

import { TooltipProps } from 'recharts';
// for recharts v2.1 and above
import {
    ValueType,
    NameType,
} from 'recharts/types/component/DefaultTooltipContent';
// for recharts versions below v2.1
import {
    ValueType,
    NameType,
} from 'recharts/src/component/DefaultTooltipContent';

const CustomTooltip = ({
    active,
    payload,
    label,
}: TooltipProps<ValueType, NameType>) => {
    if (active) {
    return (
        <div className="custom-tooltip">
        <p className="label">{`${label} : ${payload?.[0].value}`}</p>
        <p className="desc">Anything you want can be displayed here.</p>
        </div>
    );
    }

    return null;
};

return (
    <ComposedChart data={data}>
    ...
    <Tooltip content={<CustomTooltip />} />
    </ComposedChart>
);
Pavindu
  • 2,684
  • 6
  • 44
  • 77
Daria Babakova
  • 336
  • 2
  • 3
  • Thank you! This is what I needed to resolve my type errors. – Austin B Mar 17 '23 at 16:40
  • import { NameType, ValueType } from 'recharts/types/component/DefaultTooltipContent'; Need to import types from this path with version 2.5.0 – StoneLam Apr 18 '23 at 10:13
9

Use:

const CustomTooltip = ({ active, payload, label }: TooltipProps<number, string>): JSX.Element => {

Change number and string to your data types. You can also use it with the ValueType and NameType, but it makes more sense to declare it with your types.

const CustomTooltip = ({ active, payload, label }: TooltipProps<ValueType, NameType>): JSX.Element => {
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
Tob
  • 627
  • 6
  • 9
2

usually

TooltipProps<number, string>

but depends on you graph data, so generically

TooltipProps<ValueType, NameType>
CESCO
  • 7,305
  • 8
  • 51
  • 83
1

@Daria Babakova's answer almost covers it, but the only thing to note - is that you shouldn't import from "src".

So, instead of

import {
  ValueType,
  NameType,
} from 'recharts/src/component/DefaultTooltipContent';

better to write

import {
  ValueType,
  NameType,
} from 'recharts/types/component/DefaultTooltipContent';

at least on recharts 2.1.12 it works well.

Serge Vin
  • 13
  • 6
0

Here's some code that may help people. I'm using typescript btw. I did this without an explicit interface, just an any type like so.

                `{ 
                    'time': item.DateTime.getTime(),
                    'data': 1,
                    'change_type': "some_string",
                }`

In your TSX, make sure to pass in undefined like so. The example on the website was fine without explicitly saying that, but my editor complained about some error. <Tooltip content={<CustomTooltip active={undefined} payload={undefined} label={undefined}/>} />

For CustomToolTip, this was tricky for me to understand. The payload has to have index of 0. Then call dot operator as there's a payload class there to access your custom properties like time, data, and change_type

    const CustomTooltip = ({ active, payload, label }) => {
    if (active && payload && payload.length) {
      return (
        <div className="custom-tooltip">
          <p className="label">{`${label} : ${payload[0].payload.time}`}</p>
          <p className="label">{`${label} : ${payload[0].payload.data}`}</p>
          <p className="label">{`${payload[0].payload.change_type}`}</p>
          <p className="desc">Anything you want can be displayed here.</p>
        </div>
      );
    }
  
    return null;
  };

Then it should pop up in correctly without any issues on hover.

beeeliu
  • 99
  • 1
  • 1
  • 6
0

const CustomTooltip = ({
  active,
  payload,
  label,
}: {
  active: boolean;
  label: string;
  payload: {
    payload: {
      value: number
    }
  }[];
}) => {
  if (active) {
    return ( <
      div className = "custom-tooltip" >
      <
      p className = "label" > {
        `${label} : ${payload[0].value}`
      } < /p> <
      p className = "desc" > Anything you want can be displayed here. < /p> <
      /div>
    );
  }

  return null;
};

return ( <
  ComposedChart data = {
    data
  } >
  ...
  <
  Tooltip content = { < CustomTooltip active = {
      false
    }
    payload = {
      []
    }
    label = "" / >
  }
  /> <
  /ComposedChart>
);
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 25 '22 at 10:41
-4

It usually works for me,but other way could be:

const CustomTooltip = ({ active, payload, label }: any) => {
Sakshi
  • 1,464
  • 2
  • 8
  • 15