recharts icon indicating copy to clipboard operation
recharts copied to clipboard

payload=[] for Tooltip when allowDuplicatedCategory={false} in XAxis

Open VladislavKsen opened this issue 4 years ago • 10 comments

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Reproduction link

Edit on CodeSandbox

Steps to reproduce

In demo link just hovering over a bar and open console. The Tooltip don't show and payload = [].

If just change this line: <XAxis dataKey="name" allowDuplicatedCategory={false} />

for this one

<XAxis dataKey="name" allowDuplicatedCategory={true} />

The Tooltip show and payload = [{ color: "#ff7300", dataKey: "count", fill: "#ff7300", formatter: undefined, name: "count", payload: { count: 32, sum: [12, 16] }, type: undefined, unit: undefined, value: 32 }].

What is expected?

The Tooltip should be displayed when hovering over a bar and payload have array with data. http://prntscr.com/w70392

What is actually happening?

Adding allowDuplicatedCategory={false} to XAxis component in BarChart makes the Tooltip stop working. The Tooltip just don't show when hovering over a bar and payload = []; http://prntscr.com/w6zywz

Environment Info
Recharts v1.8.5
React 16.13.1
System Windows 10 Home 2004
Browser Google Chrome (87.0.4280.88)

VladislavKsen avatar Dec 21 '20 09:12 VladislavKsen

Hi there.

@xile611 @dillonreedy I'm still have this issue with payload=[] for Tooltip when allowDuplicatedCategory={false} in XAxis. For recharts 2.5.0 this issue exists and here is an example of this issue Rechart issue with payload.

My Environment info

Recharts v2.5.0
React 17.0.2

I'll appreciate any help with this. Thank you

antsukanova avatar Apr 18 '23 14:04 antsukanova

Bump,

Running into same issue with recharts 2.8.0 & react 18

removing allowDuplicatedCategory fixes the issue so not large impact for me, but have to condense the duplicates myself.

ArthurTimofey avatar Oct 23 '23 15:10 ArthurTimofey

@ArthurTimofey how about in 2.9? There were some changes that might've affected this (not sure though)

ckifer avatar Oct 23 '23 15:10 ckifer

@ckifer sorry, it happens both on 2.8.0 and 2.9.0 for me :/ I can observe in the tooltip component itself that payload is alywas going to be 0 in this case.

ArthurTimofey avatar Oct 24 '23 07:10 ArthurTimofey

Just checking. Reopening

ckifer avatar Oct 24 '23 14:10 ckifer

Fix is probably here https://github.com/recharts/recharts/blob/master/src/chart/generateCategoricalChart.tsx#L234

Data has length 0 when allowDuplicatedCategory is false

the access needs to check for length in data as well as being undefined

ckifer avatar Oct 24 '23 17:10 ckifer

Hey,

Same issue around here. Has anyone know any workaround? Thanks

balbert-etraid avatar Nov 10 '23 10:11 balbert-etraid

Hey @ckifer!

I was looking for an open source project to contribute to and I came across this repo!

I started looking into the good first issue tags and started looking into this one.

From what I've been able to gather, there is one issue in the code here. data is seems to be returned as an array, so in the examples given above, the current code is checking to see if [] === undefined, which returns false and it ends up falling back to the empty array (data) because of how it is currently written.

I'm thinking this would be a better approach:

const entries = data?.length ? data : displayedData;

In the case where allowDuplicatedCategory is set to false, check if data is defined and if there is data in the array. If there is, send the data, otherwise fall back to the displayedData.

This code fix would fix the more pressing issue I believe.

However, looking at the examples given above, I'm unsure if the scope of the feature intends to support arrays for the toolTipTick.value??? That value is set to the activeLabel value which is passed into the getTooltipContent method here and that is used to compare the value passed in by the user here.

In the above code examples the data is like this:

const data = [
  { count: 100, sum: [0, 1] },
  { count: 78, sum: [1, 3] },
  { count: 62, sum: [3, 4] },
  { count: 43, sum: [4, 12] },
  { count: 32, sum: [12, 16] },
  { count: 26, sum: [16, 20] },
  { count: 21, sum: [20, 30] },
  { count: 12, sum: [30, 38] },
  { count: 8, sum: [38, 50] }
];

sum is an array and seems to be used as a proxy for min and max values. But once the entries are set properly, because the data passed back from the user is an array, once it his this comparison the payload returns undefined because the specifiedValue is a single value and the comparison is the array specified in the sum.

Looking through the docs, all of the values appear to be single values and not tuples for the charts, so I'm not sure if there is a desire to support that kind of functionality.

If the data is restructured to look like this:

const data = [
  { count: 100, min: 0, max: 1 },
  { count: 78, min: 1, max: 3 },
  { count: 62, min: 3, max: 4 },
  { count: 43, min: 4, max: 12 },
  { count: 32, min: 12, max: 16 },
  { count: 26, min: 16, max: 20 },
  { count: 21, min: 20, max: 30 },
  { count: 12, min: 30, max: 38 },
  { count: 8, min: 38, max: 50 }
];

then it will display the data in the tooltip properly with the provided example code. If there is desire to support an array of values, I estimate that would be somewhat significant lift to make that change.

Anyway, I just wanted to spell some of that out and get some feedback before I submitted any code changes. I'd be glad to submit a PR for the initial code issue above (const entries = data?.length ? data : displayedData;) as I believe that addresses the main issue with this bug.

Let me know if you have any other thoughts!

bmoore15v avatar Nov 13 '23 03:11 bmoore15v

Hi all,

I've solved my problem related to this issue.

In my code, insead of providing to the LineChart component the data prop, I was omitting it and adding it to the data prop of the Line component.

<LineChart>
    <ReLine
       key={key}
       dataKey={key}
       data={_data}
       {...rechartOptions.lineOptions}
    />
</LineChart>

With giving to the LineChart the data prop as well, solved my issue.

<LineChart data={data}>
    <ReLine
       key={key}
       dataKey={key}
       data={_data}
       {...rechartOptions.lineOptions}
    />
</LineChart>

This could be related to this fix mentioned by @ckifer.

Fix is probably here https://github.com/recharts/recharts/blob/master/src/chart/generateCategoricalChart.tsx#L234

Data has length 0 when allowDuplicatedCategory is false

the access needs to check for length in data as well as being undefined

Anyway, thanks for this contrubution to the open source with this amazing package.

balbert-etraid avatar Nov 13 '23 07:11 balbert-etraid

Hi all, I have the same problem. I am using two X axis, each axis has three lines associated to it and this is my code ` <ResponsiveContainer aspect={1.5}> <LineChart margin={{ top: 0, right: 40, left: 20, bottom: 39 }} data={[...revenu, ...revenu2]} > <CartesianGrid strokeDasharray="1" vertical={false} /> <XAxis dataKey="date" xAxisId={"first"} orientation="bottom" tick={CustomizedAxisTick} interval={period?.value === "hour" ? 0 : "preserveEnd"} allowDuplicatedCategory={false} />

            <XAxis
              dataKey="date"
              hide={period?.value === "hour" ? true : false}
              xAxisId={"second"}
              orientation="bottom"
              tick={CustomizedAxisTick}
              interval={period?.value === "hour" ? 0 : "preserveEnd"}
              axisLine={false}
              // tickLine={false}
              allowDuplicatedCategory={false}
            />
            <YAxis
              className="text-[0.7rem]"
              tickFormatter={(value) => value.toLocaleString()}
            />
            <Tooltip />
            <Legend
              verticalAlign={"top"}
              // height={compare ? 100 : 0}
              onClick={(event) =>
                toggleBarVisibility(
                  hiddenOrdersTimeLineBars,
                  setHiddenOrdersTimeLineBars,
                  event?.dataKey
                )
              }
            />
            <Line
              xAxisId={"first"}
              data={revenu}
              type="monotone"
              dataKey="totalWithTax"
              name={
                compare
                  ? t("total_with_tax_first_period")
                  : t("total_with_tax")
              }
              stroke="#6496d2"
              hide={hiddenOrdersTimeLineBars.includes("totalWithTax")}
              strokeWidth={2}
            />
            <Line
              xAxisId={"first"}
              data={revenu}
              type="monotone"
              dataKey="totalWithoutTax"
              name={
                compare
                  ? t("total_without_tax_first_period")
                  : t("total_without_tax")
              }
              hide={hiddenOrdersTimeLineBars.includes("totalWithoutTax")}
              stroke="#2F1F15"
              strokeWidth={2}
            />
            {period?.value !== "hour" && (
              <Line
                xAxisId={"first"}
                data={revenu}
                type="monotone"
                dataKey="Target Revenu"
                name={t("target_revenu")}
                stroke="#a592b5"
                hide={hiddenOrdersTimeLineBars.includes("Target Revenu")}
                strokeWidth={2}
              />
            )}

            {compare && (
              <>
                <Line
                  xAxisId={"second"}
                  data={revenu2}
                  type="monotone"
                  dataKey="totalWithTax"
                  name={t("total_with_tax_second_period")}
                  stroke="#1916d2"
                  hide={hiddenOrdersTimeLineBars.includes("totalWithTax")}
                  strokeWidth={2}
                />
                <Line
                  xAxisId={"second"}
                  data={revenu2}
                  type="monotone"
                  dataKey="totalWithoutTax"
                  name={t("total_without_tax_second_period")}
                  hide={hiddenOrdersTimeLineBars.includes(
                    "totalWithoutTax"
                  )}
                  stroke="#a592b5"
                  strokeWidth={2}
                />
                {period?.value !== "hour" && (
                  <Line
                    xAxisId={"second"}
                    data={revenu2}
                    type="monotone"
                    dataKey="Target Revenu"
                    name={t("target_revenu")}
                    stroke="#a592b5"
                    hide={hiddenOrdersTimeLineBars.includes(
                      "Target Revenu"
                    )}
                    strokeWidth={2}
                  />
                )}
              </>
            )}
          </LineChart>
        </ResponsiveContainer>`

when use allowDuplicatedCategory={false}, the Tooltip only shows data of first X axis. what the solution for that?

AkramHarazem avatar Feb 25 '24 09:02 AkramHarazem