-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
Conversation
@@ -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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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:
Chart.js/src/core/core.layouts.js
Line 272 in abe74a6
box.update(box.fullWidth ? chartWidth : maxChartAreaWidth, chartHeight / 2, scaleMargin); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 anILayoutItem
and not anumber
. Maybe we could rename it to something clearer likeminBox
.
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 oldhorizontalBoxHeight
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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 :)
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
commentMaster:
This PR:
The actual change is using
chartHeight / 2
instead ofhorizontalBoxHeight
ingetMinimumBoxSize
. Other changes are refactoring to make this function simpler.