From c6d57de63c9cb6095dbc904e13436a94928b3d2e Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Mon, 17 Dec 2018 03:15:57 +0200 Subject: [PATCH] autoSkip: properly calculate space needed by tick label --- src/core/core.scale.js | 48 +++++++++++++++++++++++++--------- test/specs/core.scale.tests.js | 8 ++++-- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 45ba93bd739..47593fef019 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -640,9 +640,33 @@ module.exports = Element.extend({ var isHorizontal = me.isHorizontal(); var optionTicks = me.options.ticks.minor; var tickCount = ticks.length; - var labelRotationRadians = helpers.toRadians(me.labelRotation); - var cosRotation = Math.cos(labelRotationRadians); - var longestRotatedLabel = me.longestLabelWidth * cosRotation; + + // Calculate space needed by label in axis direction. + // Idea from https://github.com/chartjs/Chart.js/pull/5252/files#r207742171 + var rot = helpers.toRadians(me.labelRotation); + var cos = Math.abs(Math.cos(rot)); + var sin = Math.abs(Math.sin(rot)); + + var padding = optionTicks.autoSkipPadding; + var w = me.longestLabelWidth + padding || 0; + + // FIXME: Add support for multiline labels + var tickFont = parseFontOptions(optionTicks); + var h = tickFont.size * 1.2 + padding; + + // Calculate space needed for 1 tick in axis direction. + var tickSize = isHorizontal + ? (h * cos > w * sin ? w / cos : h / sin) + : (h * sin < w * cos ? h / cos : w / sin); + + // Total space needed to display all ticks. First and last ticks are drawn as their center at end of axis, so tickCount-1 + var ticksLength = tickSize * (tickCount - 1); + + // Axis length + var axisLength = isHorizontal + ? me.width - (me.paddingLeft + me.paddingRight) + : me.height - (me.paddingTop + me.PaddingBottom); + var result = []; var i, tick; @@ -652,18 +676,16 @@ module.exports = Element.extend({ maxTicks = optionTicks.maxTicksLimit; } - if (isHorizontal) { - skipRatio = false; + skipRatio = false; - if ((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount > (me.width - (me.paddingLeft + me.paddingRight))) { - skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * tickCount) / (me.width - (me.paddingLeft + me.paddingRight))); - } + if (ticksLength > axisLength) { + skipRatio = 1 + Math.floor(ticksLength / axisLength); + } - // if they defined a max number of optionTicks, - // increase skipRatio until that number is met - if (maxTicks && tickCount > maxTicks) { - skipRatio = Math.max(skipRatio, Math.floor(tickCount / maxTicks)); - } + // if they defined a max number of optionTicks, + // increase skipRatio until that number is met + if (maxTicks && tickCount > maxTicks) { + skipRatio = Math.max(skipRatio, 1 + Math.floor(tickCount / maxTicks)); } for (i = 0; i < tickCount; i++) { diff --git a/test/specs/core.scale.tests.js b/test/specs/core.scale.tests.js index 35ef3d6babb..4a7827d60e4 100644 --- a/test/specs/core.scale.tests.js +++ b/test/specs/core.scale.tests.js @@ -63,10 +63,14 @@ describe('Core.scale', function() { labels: [ 'January 2018', 'February 2018', 'March 2018', 'April 2018', 'May 2018', 'June 2018', 'July 2018', 'August 2018', - 'September 2018', 'October 2018', 'November 2018', 'December 2018' + 'September 2018', 'October 2018', 'November 2018', 'December 2018', + 'January 2019', 'February 2019', 'March 2019', 'April 2019', + 'May 2019', 'June 2019', 'July 2019', 'August 2019', + 'September 2019', 'October 2019', 'November 2019', 'December 2019', + 'January 2020', 'February 2020' ], datasets: [{ - data: [12, 19, 3, 5, 2, 3, 7, 8, 9, 10, 11, 12] + data: [12, 19, 3, 5, 2, 3, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] }] });