Torc
Torc

Reputation: 1322

Prevent Recharts Tick Marks from Overlapping

I am developing an application which allows a user to select dynamically queried data which can then be used in Recharts visualizations. There are certain edge cases where the default formatting / rendering within recharts produces an ugly result. For example, if there are many unique values passed to the <XAxis /> component then the chart produced will likely have overlapping text for the ticks.

There does not seem to be any good "render as many ticks as possible, without overlapping" option described in the documentation. These appear to be the only options:

  1. Render all ticks (obviously leads to too many ticks)
            <XAxis
              dataKey={xAxisField.name}
              name={getXAxisLabel(xAxisField, chartType)}
              tickFormatter={
                getMetaDataType(xAxisField) ===
                "DATE"
                  ? tickEpochFormatter // force numbers to be displayed as 'YYYY-MM-DD'
                  : tickNumberFormatter
              }
              allowDataOverflow={false}
              ticks={xValues.sort()} // gets all of the values
              interval={0} // display all of values, instead of the default 5
              angle={-90} // force text to be 90, reading towards the graph
              textAnchor="end" // rather than setting "dy={50}" or something
            >
  1. Render only the start / end / start & end, which depends (seemingly) entirely on the width of the text, prior to rotation.
            <XAxis
              dataKey={xAxisField.name}
              name={getXAxisLabel(xAxisField, chartType)}
              tickFormatter={
                getMetaDataType(xAxisField) ===
                "DATE"
                  ? tickEpochFormatter // force numbers to be displayed as 'YYYY-MM-DD'
                  : tickNumberFormatter
              }
              allowDataOverflow={false}
              ticks={xValues.sort()} // gets all of the values
              interval="preserveStart" // ensure that everything can be read, giving preference to the "left"???
              angle={-90} // force text to be 90, reading towards the graph
              textAnchor="end" // rather than setting "dy={50}" or something
            >
  1. Hardcode the number of intervals to ensure a maximum? I'm not sure if this is a viable option since I would need to know how many ticks are truly overlapping. Just seems like a crude approach.

Is it even possible to have Recharts render as many things as possible, even if they are rotated 90 degrees, and then selectively choose what has enough space to display? Is it possible to have the angle property dynamically update based on the length of the tick mark texts?

Here is a list of links, none of which seems to answer these questions:

Recharts Docs

Github Recharts repo

StackOverflow Posts

Here's a picture of the problematic rendering I want to clean up:

All ticks rendered and overlapping

Also, please note that normally I would prefer to stick to the same library that I have been using, but if another library is better suited for this use-case, I would like to consider switching!

Upvotes: 12

Views: 16000

Answers (1)

Ivan Yulin
Ivan Yulin

Reputation: 1046

I had the same problem, ended up removing the interval property which set the ticks to be sort-of-dynamic but had only 4 or 5 ticks.

So I set the minTickGap to some negative value. the result was that more ticks appeared on the axis

 <XAxis dataKey="date"
        angle={45}
        dx={15}
        dy={20}
        minTickGap={-200}
        axisLine={false}/>

before before

after: after

Upvotes: 4

Related Questions