Search code examples
javascriptrecharts

Trouble rendering data in custom tooltip in rechart


I am trying to render the tooltip of a container on top of it on mouse over.

A lot of inspiration is taken from this post: https://stackoverflow.com/a/69623087/17066023

so I set up my code as follows:


let [barGraphData, setBarGraphData] = useState({})

    let tooltip;
    const CustomTooltip = ({ active, payload }) => {
        if (!active || !tooltip)    return null
        for (const bar of payload)
            if (bar.dataKey === tooltip)
                return <div>{ `Team: ${bar.name}` }<br/>{ `Members: ${bar.value.toFixed(0)}`}</div>
        return null
    }

and my bar chart like so:

<ResponsiveContainer width={'100%'} height={'100%'}>
        <BarChart width={600} height={300} data={data} margin={{top: 60, right: 20, bottom: 5, left: 0}}>
            <XAxis dataKey={'Date_Posted'}
                   tickFormatter={monthTickFormatter}/>

            <XAxis
                dataKey={'Date_Posted'}
                axisLine={false}
                tickLine={false}
                interval={0}
                tick={renderQuarterTick}
                height={1}
                scale="band"
                xAxisId="quarter"
            />
            {teams.map((team) => (
                // eslint-disable-next-line react/jsx-key
                <Bar dataKey={team} fill={'#38bdf8'}


                      onMouseOver={(data) =>{
                          setBarGraphData(data);
                          tooltip = team;
                      }}
                />

            ))}

            <CartesianGrid stroke="#ccc" />

            <YAxis />

            <Tooltip  content={CustomTooltip}
                      cursor={false}
                      wrapperStyle={
                          {
                              border: "2px solid #fda4af",
                              borderRadius: "5px",
                              backgroundColor: "white",
                              boxShadow: "0px 0px 5px #e5e7eb",
                              paddingLeft: 10,
                              paddingRight: 10,
                      }}
                      // position={{x: 0, y:0}}
                      position={{ x: barGraphData.x, y: barGraphData.y - 40 }}

            />

        </BarChart>


    </ResponsiveContainer>

now the issue I am running into is I believe in this block of code here:

            {teams.map((team) => (
                // eslint-disable-next-line react/jsx-key
                <Bar dataKey={team} fill={'#38bdf8'}


                      onMouseOver={(data) =>{
                          setBarGraphData(data);
                          tooltip = team;
                      }}
                />

by setting the state here to the data of the Bar it stops the rendering of my tooltip. So, what I am getting when I pass in that block of code is this: example of the issue

but when I pass in the following code I get the tooltip rendered but because I do not pass in the data object the tooltip does not render above each individual bar.

{teams.map((team) => (
                // eslint-disable-next-line react/jsx-key
                <Bar dataKey={team} fill={'#38bdf8'}


                      onMouseOver={() =>{
                        
                          tooltip = team;
                      }}
                />

image of the tooltip rendered but unable to follow the mouseOver event

What am I doing wrong here? Because to me it looks as if the State is the thing that is messing up the tooltip render.


Solution

  • The "let tooltip" line is setting tooltip to undefined in every render. Set tooltip up as state and that oughta do it.