mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.03k stars 1.24k forks source link

[charts] Support long text #10928

Open alexfauquette opened 10 months ago

alexfauquette commented 10 months ago

Long text can quickly become an issue in legend and in axis tick labels. For the legend, it push the legend onto the chart, and for the label, they overflow the SVG area

image image

Solution from other libraries

Ideas

Outside of this scop, the way to format values and labels should be documented and exhaustive. From the series/axis definition, I should be able to render whatever I want for the tooltip, the legend and the axis. For now the value formater are common to all the components

Search keywords: charts, legend, labels, overflow

michaelpward commented 10 months ago

@alexfauquette Thank you! 🙂

It may be informative for you to create versions of these charts with, for example, 25 items in the legend to see how they render. It will not be good.

There are at least 2 cases to consider:

Below is a partial screenshot of a dashboard in production in our app (a marketing automation platform).

These charts use Chart.js. Chart.js shrinks the "plot area" (I don't know what to call it, the area where the actual chart is) if the legend is large. It gives the legend the space it needs first, then plots the chart in the remaining space. As a developer, there is nothing I need to do. It just works.

If I have to calculate or find the size of the legend so I can set the size of the plot area... I'll just use Chart.js because it does it for me.

That said there is a shortcoming with Chart.js. If the number of items in the legend is very large (let's say 60 or more), the plot area is so small that the chart is useless.

This is a real use case. Set a 12 month date range on that dashboard (which our customers absolutely want to do) and the chart becomes worthless because there are so many marketing channels in a long date range (unless I render it in a much larger container).

A great solution would be a legend that can "overflow":

Thanks for listening 🙂

image
alexfauquette commented 6 months ago

Duplicate wit good insights: #12157

alexfauquette commented 2 months ago

The satori project that map HTML to SVG has its full codebase for text here: https://github.com/vercel/satori/tree/main/src/text

They have a font engine that loads fonts and allows to get the bounding box of text elements.

string can be splited by word or graphen using the segment helper which relies on the Intl.Segmenter to support multiple locales

Then it's a question of mesuring each world, and adapt their placement according to some CSS rules.