Skip to content

Commit

Permalink
autoSkip: properly calculate space needed by tick label
Browse files Browse the repository at this point in the history
  • Loading branch information
kurkle committed Dec 17, 2018
1 parent 52b9793 commit 59be062
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
37 changes: 31 additions & 6 deletions src/core/core.scale.js
Expand Up @@ -640,9 +640,34 @@ 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 rotDeg = me.labelRotation;
var rot = helpers.toRadians(rotDeg);
var cos = Math.abs(Math.cos(rot));
var sin = Math.abs(Math.sin(rot));
var width = me.longestLabelWidth;

// TODO Add support for multiline labels
var tickFont = parseFontOptions(optionTicks);
var height = tickFont.size * 1.2;
var padding = optionTicks.autoSkipPadding;

// Calculate space needed for 1 tick in axis direction.
// When angle is under 45 degrees, label width determines space needed. Above 45 its based on height.
var tickSize = isHorizontal
? (rotDeg < 45 ? (width * cos) : (height / sin)) + padding
: (rotDeg < 45 ? (width * sin) : (height / cos)) + padding;

// 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;

Expand All @@ -655,14 +680,14 @@ module.exports = Element.extend({
if (isHorizontal) {
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));
skipRatio = Math.max(skipRatio, 1 + Math.floor(tickCount / maxTicks));
}
}

Expand Down
8 changes: 6 additions & 2 deletions test/specs/core.scale.tests.js
Expand Up @@ -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]
}]
});

Expand Down

0 comments on commit 59be062

Please sign in to comment.