From 8dfcf1c443d4f783699dd53679f174d0309f3d9d Mon Sep 17 00:00:00 2001 From: stockiNail Date: Thu, 9 Feb 2023 15:26:11 +0100 Subject: [PATCH] Use maxTicksLimit option to calculate the labels size on ticks (#11069) * Use maxTicksLimit option to calculate the labels size on ticks * apply review --- src/core/core.scale.js | 10 +++-- .../max-ticks-limit-norotation.js | 37 ++++++++++++++++++ .../max-ticks-limit-norotation.png | Bin 0 -> 18046 bytes 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/scale.category/max-ticks-limit-norotation.js create mode 100644 test/fixtures/scale.category/max-ticks-limit-norotation.png diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 562ab21b654..50ddca8724c 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -8,6 +8,7 @@ import {autoSkip} from './core.scale.autoskip.js'; const reverseAlign = (align) => align === 'left' ? 'right' : align === 'right' ? 'left' : align; const offsetFromEdge = (scale, edge, offset) => edge === 'top' || edge === 'left' ? scale[edge] + offset : scale[edge] - offset; +const getTicksLimit = (ticksLength, maxTicksLimit) => Math.min(maxTicksLimit || ticksLength, ticksLength); /** * @typedef { import('./core.controller.js').default } Chart @@ -585,7 +586,7 @@ export default class Scale extends Element { calculateLabelRotation() { const options = this.options; const tickOpts = options.ticks; - const numTicks = this.ticks.length; + const numTicks = getTicksLimit(this.ticks.length, options.ticks.maxTicksLimit); const minRotation = tickOpts.minRotation || 0; const maxRotation = tickOpts.maxRotation; let labelRotation = minRotation; @@ -803,7 +804,7 @@ export default class Scale extends Element { ticks = sample(ticks, sampleSize); } - this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length); + this._labelSizes = labelSizes = this._computeLabelSizes(ticks, ticks.length, this.options.ticks.maxTicksLimit); } return labelSizes; @@ -815,15 +816,16 @@ export default class Scale extends Element { * @return {{ first: object, last: object, widest: object, highest: object, widths: Array, heights: array }} * @private */ - _computeLabelSizes(ticks, length) { + _computeLabelSizes(ticks, length, maxTicksLimit) { const {ctx, _longestTextCache: caches} = this; const widths = []; const heights = []; + const increment = Math.floor(length / getTicksLimit(length, maxTicksLimit)); let widestLabelSize = 0; let highestLabelSize = 0; let i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel; - for (i = 0; i < length; ++i) { + for (i = 0; i < length; i += increment) { label = ticks[i].label; tickFont = this._resolveTickFontOptions(i); ctx.font = fontString = tickFont.string; diff --git a/test/fixtures/scale.category/max-ticks-limit-norotation.js b/test/fixtures/scale.category/max-ticks-limit-norotation.js new file mode 100644 index 00000000000..d9c86c53727 --- /dev/null +++ b/test/fixtures/scale.category/max-ticks-limit-norotation.js @@ -0,0 +1,37 @@ +const data = Array.from({length: 42}, (_, i) => i + 1); +const labels = data.map(v => 'tick' + v); + +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/10856', + config: { + type: 'bar', + data: { + datasets: [{ + data + }], + labels + }, + options: { + scales: { + x: { + ticks: { + display: true, + maxTicksLimit: 6 + }, + grid: { + color: 'red' + } + }, + y: {display: false} + }, + layout: { + padding: { + right: 2 + } + } + } + }, + options: { + spriteText: true + } +}; diff --git a/test/fixtures/scale.category/max-ticks-limit-norotation.png b/test/fixtures/scale.category/max-ticks-limit-norotation.png new file mode 100644 index 0000000000000000000000000000000000000000..063f06d1a965f5361efc6a7e759daa7ce489ff73 GIT binary patch literal 18046 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