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

Fix padding of horizontal axes when labels are rotated #6021

Merged
merged 6 commits into from Feb 2, 2019

Conversation

kurkle
Copy link
Member

@kurkle kurkle commented Jan 28, 2019

I noticed a issue with layout when working with label rotations.
The left/right padding for all horizontal scales are calculated in a "minimum height" phase. That causes excess padding if long labels are present (rotation would be zero or close to it).

Side effects of this same issue has been worked by @nagix in #5961 / calculateTickRotation comment

Master:
master

This PR:
pr

The actual change is using chartHeight / 2 instead of horizontalBoxHeight in getMinimumBoxSize. Other changes are refactoring to make this function simpler.

src/core/core.layouts.js Outdated Show resolved Hide resolved
@@ -201,7 +228,7 @@ module.exports = {
var isHorizontal = box.isHorizontal();

if (isHorizontal) {
minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, horizontalBoxHeight);
minSize = box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2);
Copy link
Member

Choose a reason for hiding this comment

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

The reason this used horizontalBoxHeight is that the sum of the heights of all the horizontal boxes needs to be capped at chartHeight / 2 so that there is room for the chart. Is it possible now to have the axes take up more space because we measure them at a bigger size?

Copy link
Member Author

@kurkle kurkle Jan 28, 2019

Choose a reason for hiding this comment

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

Is it possible now to have the axes take up more space because we measure them at a bigger size?

Its been like that for a long time already (couldn't find the original change, more than 3 years ago from #1837)
Also visible in both of the attached images, axes take more space than the chart.

Because that horizontalBoxHeight is not actually used in the final layout:

box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin);

Copy link
Contributor

Choose a reason for hiding this comment

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

It took me quite awhile to understand that minSize was an ILayoutItem and not a number. Maybe we could rename it to something clearer like minBox.

chartHeight / 2 seems wrong. What if there are multiple axes? Does this value actually represent the minimum height or is ignored? Could we fix the old horizontalBoxHeight rather than removing it?

Copy link
Member Author

Choose a reason for hiding this comment

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

It took me quite awhile to understand that minSize was an ILayoutItem and not a number. Maybe we could rename it to something clearer like minBox.

I agree there's room for improvement in these names.

chartHeight / 2 seems wrong. What if there are multiple axes? Does this value actually represent the minimum height or is ignored? Could we fix the old horizontalBoxHeight rather than removing it?

It represents maximum height available for box, but I agree it seems wrong.
However, this was not something I was fixing, just the padding issue. I tried using horizontalBoxHeight instead in both places (makes more sense to me), but then issue #1766 reappears.

Copy link
Member Author

Choose a reason for hiding this comment

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

Basically we are now figuring out the minimum size of the horizontal box by using same maximum height available as in the final fit (=chartHeight / 2). I'd rather not change the chartHeight / 2 now, unless there is a issue that relates to it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Should it be chartHeight / 2 / verticalBoxes.length though? I don't understand why we can start ignoring how many axes there are

Copy link
Contributor

Choose a reason for hiding this comment

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

I had the same concern as @benmccann, but the vertical boxes include the title and legend boxes, and they don't always require horizontalBoxHeight, so the calculation of the label rotation might not work as expected if we use horizontalBoxHeight as maxHeight in update. With the proposed solution, if there are multiple axes and each axis has long labels, the total height might exceed the chart height. I wonder if we can say it's an ignorable edge case.

Copy link
Member

Choose a reason for hiding this comment

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

I think we could ignore that edge case for now. When I wrote this code the first time I wasn't considering the case of multiple horizontal axes and mostly wanted to support multiple vertical axes since that was a common use case. I think that also explains chartHeight/2 more because with 1 horizontal axis splitting the height in 2 seemed like a reasonable step.

In v3 I think I'd like to explore splitting the fit function into 2 separate methods: measure and arrange. This matches the patterns I've seen in a number of other systems, such as WPF and it means we can keep a difference between calling fit to get a size and calling fit to actually setup the internals.

If the split into 2 separate methods goes well and we could get measure performing well, we could rethink the core layout algorithm. Having 2 passes was a compromise between a slow iterative algorithm that kept looping until boxes didn't change much in size and a single pass algorithm that just assigned sizes based on heuristics.

Copy link
Contributor

Choose a reason for hiding this comment

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

That 2-pass approach makes a lot of sense to me. I'm fine with the solution in this PR for now, and the refactoring is so good.

src/core/core.layouts.js Outdated Show resolved Hide resolved
etimberg
etimberg previously approved these changes Jan 29, 2019
Copy link
Member

@simonbrunel simonbrunel left a comment

Choose a reason for hiding this comment

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

Didn't review this PR in depth (@etimberg knows this part better than me) so will just make a small comment about the form. Else, it looks really good to me :)

src/core/core.layouts.js Outdated Show resolved Hide resolved
simonbrunel
simonbrunel previously approved these changes Jan 29, 2019
@simonbrunel simonbrunel changed the title Layout Fix padding of horizontal axes when labels are rotated Jan 29, 2019
src/core/core.layouts.js Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants