Search code examples
reactjsnext.jsrecharts

Recharts: How to sort order of elements in Tooltip?


I'm using Recharts with NextJS. I have a ComposedChart of Line & Stacked Bars like this:

recharts

The Stacked Bars are being rendered from bottom to top, so the Tooltip's order also rendering in ascending order as the chart's state:

recharts

How can we change the order of the <Tooltip /> so it will render from the top of the bar to the bottom? (Ex: Yellow -> Gray -> Cyan -> Pastel Cyan)

Structure of a data object (Each one matches a stacked bar):

[
 {
  aggregated_month: "2021/08"
  deep_sleep_uu: 192 // This one is Gray
  latest_recovery_uu: 159 // Cyan
  recovery_rate: 63.6 // Yellow line
  recovery_uu: 176 // Pastel Cyan
  total_uu: 527 // Number on top
 },
 {
  aggregated_month: "2022/04"
  latest_recovery_uu: 288 // Cyan
  recovery_rate: 76.1 // Yellow
  recovery_uu: 127 // Pastel Cyan
  sleep_uu: 130 // Red bar
  total_uu: 545 // Number on top
 }
]

What I tried:

  1. <Tooltip itemSorter={() => -1} /> - This is the default
  2. <Tooltip itemSorter={() => 1} /> - This doesn't work either

Solution

  • itemSorter has this signature -> itemSorter?: (item: Payload<TValue, TName>) => number | string (code here), where payload is the following object:

    export interface Payload<TValue extends ValueType, TName extends NameType> {
      type?: TooltipType;
      color?: string;
      formatter?: Formatter<TValue, TName>;
      name?: TName;
      value?: TValue;
      unit?: ReactNode;
      dataKey?: string | number;
      payload?: any;
      chartType?: string;
    }
    

    * You can check the payload object here

    This means that you can sort the tooltip by any properties from payload.

    Some sort examples:

    SortBy name

    <Tooltip
       itemSorter={(item) => {
          return item.name as string;
       }}
    />
    

    SortBy value (ASC)

    <Tooltip
       itemSorter={(item) => {
          return item.value as number;
       }}
    />
    

    SortBy value (DESC)

    <Tooltip
       itemSorter={(item) => {
          return (item.value as number) * -1;
       }}
    />
    

    Custom sort

    <Tooltip
            itemSorter={(item) => {
              switch (item.dataKey) {
                case "recovery_rate":
                  return 0;
                case "deep_sleep_uu":
                  return 1;
                case "latest_recovery_uu":
                  return 2;
                default:
                  return 3;
              }
            }}
          />
    

    Said that, as i don´t know your entire code, i believe that what you want can be accomplish sorting by name.