Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plotly Charts: use .legend to determine legends size #4935

Merged
merged 5 commits into from
Jun 11, 2020

Conversation

gabrieldutra
Copy link
Member

@gabrieldutra gabrieldutra commented Jun 2, 2020

What type of PR is this? (check all applicable)

  • Bug Fix

Description

The bug (Preview)

Screen Shot 2020-06-02 at 16 10 07

Currently Charts that have legends moved to the bottom can "cut" part of their text.

With this fix (Preview)

Screen Shot 2020-06-02 at 16 14 17

Related Tickets & Documents

--

Mobile & Desktop Screenshots/Recordings (if there are UI changes)

See description ☝️

@arikfr arikfr requested a review from kravets-levko June 3, 2020 10:47
@kravets-levko
Copy link
Collaborator

There was a reason why I implemented this hack instead of using Plotly's features (query to reproduce):

image

I'll explain you how coordinates in Plotly work so you don't need to look for in in docs and sources. There is a plot area - it's 1x1 box with coordinates from (0.0; 0.0) to (1.0; 1.0) and everything else is placed outside of it, including axes, legend and so on. Outside of plot there are only margins (that ones we can setup in layout object). To make axes/annotations/etc. visible, Plotly modifies margins (yes, it does not treat that objects as a part of plot). If you disable automargins feature - axes may become partially invisible. But the most important thing in our case is that automargins feature does not take in account legend - there is another algorithm. When you place legend in some coordinates outside of plot - Plotly will add extra space for it. But I highlighted word "plot" on purpose - automargins algorithm and this one are independent, so legend does not "know" about axes and other stuff. Therefore legend may overlap them (or even plot in some cases).

The idea of my hack was to place horizontal legend in top-left corner of plot so Plotly will not reserve extra space for it, and then measure it and offset using CSS. There is an issue to fix this behavior in Plotly (either by fixing legend positioning algorithm or by allowing to choose coordinate system - relative to plot, or plot with axes or container/absolute). But it's still not implemented 😞

@gabrieldutra
Copy link
Member Author

gabrieldutra commented Jun 3, 2020

There was a reason why I implemented this hack instead of using Plotly's features (query to reproduce):

I figured this was the case, I could see that happening with the other graph already. I just wondered if they may had added any other feature to cover this, which would've been better to us.

I'll revert the test commit and go back with the "updating the fix" approach. I'll provide more details on that, but first I'll try to understand better other issues I found: - scrollbox taking part of the plot sometimes (Seems part of how Plotly handles the drawing, as other elements have their own sizing values); - Plots without legend don't resize (it's currently coupled to the "updatePlot" for the legends, so it makes sense to find a different flow).

Thanks for the explanation @kravets-levko 🙂

@gabrieldutra gabrieldutra changed the title Plotly Charts: use .bg to determine legends size Plotly Charts: use .legend to determine legends size Jun 4, 2020
Comment on lines -79 to -90
const bounds = reduce(
legend.querySelectorAll(".traces"),
(result, node) => {
const b = node.getBoundingClientRect();
result = result || b;
return {
top: Math.min(result.top, b.top),
bottom: Math.max(result.bottom, b.bottom),
};
},
null
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kravets-levko what's causing the bug is that there is some "margin" for the legends background, computing each of the items separately don't take it into account, so it separating less than needed and cutting part of the text. I made some tests and it seems the .legend holds the same information we had before + it also considers the margin for the background size.

I'm continuing to test this change, but so far looks fine, lmk if you see any situation where this may cause a problem.

Comment on lines +120 to +121
} else {
updatePlot(plotlyElement, pick(layout, ["width", "height"]));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This solves another issue that Charts without legends weren't updating when resized.

@gabrieldutra gabrieldutra marked this pull request as ready for review June 4, 2020 22:02
Copy link
Collaborator

@kravets-levko kravets-levko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks that this fix works. Good job! 🚀

@arikfr arikfr merged commit 56df870 into master Jun 11, 2020
@arikfr arikfr deleted the plotly-legends-below-plot branch June 11, 2020 09:30
andrewdever pushed a commit to andrewdever/redash that referenced this pull request Oct 5, 2020
* Plotly Charts: use .bg to determine legends size

* Test: remove hack for legend below plotly

* Revert "Test: remove hack for legend below plotly"

This reverts commit d8efb0c.

* Use .legend to calculate bounds

* Also update plots without legend
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants