plotters
plotters copied to clipboard
New chart layout algorithm
I am working on a new chart layout algorithm that may be slightly controversial, so I wanted to get some feedback before I make a PR.
My goal is to make charts appear nicer by default. For example, to have margins/padding automatically computed based on font size and to prevent axis labels from printing off the edge as in
The idea I had was to use the stretch library, which performs flex-box calculations in Rust (and is WASM compatible and supposedly very efficient). Then, a chart could be laid out as a series of nested flex boxes, and a layout could be computed when needed, instead of immediately as in the current ChartBuilder
api.
If a layout is set up and then computed, this means it can have default font sizes, etc, which can be overwritten, instead of everything having to be set upfront. Size calculations can then be done dynamically.
So far I have decomposed a chart into regions as follows:
Any region can have a size set to zero and it will disappear from the layout. I believe the above decomposition will be able to handle all current use cases. Please correct me if I'm wrong!
Is this something that would make it into standard plotters
? Behind a config flag maybe?
Hi, thanks for working on this. In general this sounds great to me, and it would be awesome if Plotters can do some automatic adjustment by default. There are few things coming out from my mind at this time:
- We probably can have this behind some feature switch until we reach next major release - Basically we don't want any existing downstream code see a lot of layout changing by default (some of them may be disaster especially for criterion)
- There are one tweak may be interesting: Plotters allows the label area float over the chart area by passing a negative label_area_size. Also the negative tick mark size make them drawn inward.
- Sometimes we want to have the layout stable for realtime plotting - I mean for each frame, we basically want to have exactly same layout for each frame. By doing so, we can only updating the chart_area without redraw rest part of the image.
Also, I am curious is the new layout algorithm able to automatically layout multi-panel charts?
BTW, as the scratch crate doesn't introduces tons of dependencies, I would like to make it default in next major release if everything goes well.
Really appreciate for the contribution!
Great :-). The new algorithm will exist in parallel to the old one, since it cannot be a drop-in replacement (it cannot eagerly return a sub drawing area). stretch
can use the standard margin
and padding
HTML attributes, so negative margins should work just fine!
Can you explain more what's needed for "real time" mode?
Can you explain more what's needed for "real time" mode?
In real time mode, the trick is we only update the actual chart area, but keep those axes and labels untouched when possible. So we need to make sure that new layout algorithm will not move/resize while the dynamic chart is updating.
Oh, an irrelevant question if you don't mind. As long as the new algorithm is based on layout boxes, so I am also curious the possibility of interactivity based on this new algorithm? For example, dispatching the UI event to particular label and axis based on the box model ? See discussion under #13. Forgive me if you feel this is out of your scope.
In real time mode, the trick is we only update the actual chart area, but keep those axes and labels untouched when possible. So we need to make sure that new layout algorithm will not move/resize while the dynamic chart is updating.
This should work fine with the new algorithm. The chart_area
shouldn't change size unless the axis labels, etc. also change.
Oh, an irrelevant question if you don't mind. As long as the new algorithm is based on layout boxes, so I am also curious the possibility of interactivity based on this new algorithm? For example, dispatching the UI event to particular label and axis based on the box model ? See discussion under #13. Forgive me if you feel this is out of your scope.
Yes. With a box model, it should be fairly easy to translate pixel locations into lists of elements below that pixel.