When an axis needs padding due to a long, rotated, label it should be added inside the layout system rather than in each axis.

This commit is contained in:
Evert Timberg
2016-10-24 21:43:52 -04:00
parent fd2e40ce11
commit eaf109c2b1
4 changed files with 41 additions and 14 deletions

View File

@@ -148,15 +148,26 @@ module.exports = function(Chart) {
minBoxSizes.push({
horizontal: isHorizontal,
minSize: minSize,
box: box
box: box,
});
}
helpers.each(leftBoxes.concat(rightBoxes, topBoxes, bottomBoxes), getMinimumBoxSize);
// If a box has padding, we move the left scale over to avoid ugly charts (see issue #2478)
var maxHorizontalLeftPadding = 0;
var maxHorizontalRightPadding = 0;
helpers.each(topBoxes.concat(bottomBoxes), function(horizontalBox) {
if (horizontalBox.getPadding) {
var boxPadding = horizontalBox.getPadding();
maxHorizontalLeftPadding = Math.max(maxHorizontalLeftPadding, boxPadding.left);
maxHorizontalRightPadding = Math.max(maxHorizontalRightPadding, boxPadding.right);
}
});
// At this point, maxChartAreaHeight and maxChartAreaWidth are the size the chart area could
// be if the axes are drawn at their minimum sizes.
// Steps 5 & 6
var totalLeftBoxesWidth = leftPadding;
var totalRightBoxesWidth = rightPadding;
@@ -172,8 +183,8 @@ module.exports = function(Chart) {
if (minBoxSize) {
if (box.isHorizontal()) {
var scaleMargin = {
left: totalLeftBoxesWidth,
right: totalRightBoxesWidth,
left: Math.max(totalLeftBoxesWidth, maxHorizontalLeftPadding),
right: Math.max(totalRightBoxesWidth, maxHorizontalRightPadding),
top: 0,
bottom: 0
};
@@ -251,6 +262,13 @@ module.exports = function(Chart) {
totalBottomBoxesHeight += box.height;
});
// We may be adding some padding to account for rotated x axis labels
var leftPaddingAddition = Math.max(maxHorizontalLeftPadding - totalLeftBoxesWidth, 0);
var rightPaddingAddition = Math.max(maxHorizontalRightPadding - totalRightBoxesWidth, 0);
totalLeftBoxesWidth += leftPaddingAddition;
totalRightBoxesWidth += rightPaddingAddition;
// Figure out if our chart area changed. This would occur if the dataset layout label rotation
// changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do
// without calling `fit` again
@@ -283,7 +301,7 @@ module.exports = function(Chart) {
}
// Step 7 - Position the boxes
var left = leftPadding;
var left = leftPadding + leftPaddingAddition;
var top = topPadding;
function placeBox(box) {

View File

@@ -51,8 +51,17 @@ module.exports = function(Chart) {
};
Chart.Scale = Chart.Element.extend({
getPadding: function() {
var me = this;
return {
left: me.paddingLeft || 0,
top: me.paddingTop || 0,
right: me.paddingRight || 0,
bottom: me.paddingBottom || 0
};
},
// These methods are ordered by lifecycle. Utilities then follow.
// These methods are ordered by lifecyle. Utilities then follow.
// Any function defined here is inherited by all scale types.
// Any function can be extended by the scale type

View File

@@ -718,8 +718,8 @@ describe('Linear Scale', function() {
expect(xScale.paddingTop).toBeCloseToPixel(0);
expect(xScale.paddingBottom).toBeCloseToPixel(0);
expect(xScale.paddingLeft).toBeCloseToPixel(0);
expect(xScale.paddingRight).toBeCloseToPixel(13.5);
expect(xScale.width).toBeCloseToPixel(471);
expect(xScale.paddingRight).toBeCloseToPixel(0);
expect(xScale.width).toBeCloseToPixel(457.5);
expect(xScale.height).toBeCloseToPixel(28);
var yScale = chart.scales.yScale0;
@@ -738,8 +738,8 @@ describe('Linear Scale', function() {
expect(xScale.paddingTop).toBeCloseToPixel(0);
expect(xScale.paddingBottom).toBeCloseToPixel(0);
expect(xScale.paddingLeft).toBeCloseToPixel(0);
expect(xScale.paddingRight).toBeCloseToPixel(13.5);
expect(xScale.width).toBeCloseToPixel(453);
expect(xScale.paddingRight).toBeCloseToPixel(0);
expect(xScale.width).toBeCloseToPixel(439.5);
expect(xScale.height).toBeCloseToPixel(46);
expect(yScale.paddingTop).toBeCloseToPixel(0);

View File

@@ -717,14 +717,14 @@ describe('Logarithmic Scale tests', function() {
});
var xScale = chart.scales.xScale;
expect(xScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(495); // right - paddingRight
expect(xScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(481.5); // right - paddingRight
expect(xScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(48); // left + paddingLeft
expect(xScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(283); // halfway
expect(xScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(276); // halfway
expect(xScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(48); // 0 is invalid, put it on the left.
expect(xScale.getValueForPixel(495)).toBeCloseTo(80, 1e-4);
expect(xScale.getValueForPixel(481.5)).toBeCloseTo(80, 1e-4);
expect(xScale.getValueForPixel(48)).toBeCloseTo(1, 1e-4);
expect(xScale.getValueForPixel(283)).toBeCloseTo(10, 1e-4);
expect(xScale.getValueForPixel(276)).toBeCloseTo(10, 1e-4);
var yScale = chart.scales.yScale;
expect(yScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(32); // top + paddingTop