From c9b38b63dcd4bd198fbf8efca70466e9b9a95243 Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Fri, 16 Oct 2020 15:04:22 +0300 Subject: [PATCH] Share min sample size with all bars on same scale (#7897) Share min sample size with all bars on same scale --- src/controllers/controller.bar.js | 39 ++++++++++++---- src/core/core.scale.js | 5 +- .../bar-thickness-min-interval-multi.json | 44 ++++++++++++++++++ .../bar-thickness-min-interval-multi.png | Bin 0 -> 3898 bytes 4 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 test/fixtures/controller.bar/bar-thickness-min-interval-multi.json create mode 100644 test/fixtures/controller.bar/bar-thickness-min-interval-multi.png diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 562de6350..aafe80856 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -1,24 +1,43 @@ import DatasetController from '../core/core.datasetController'; -import {clipArea, unclipArea} from '../helpers/helpers.canvas'; -import {isArray, isNullOrUndef, valueOrDefault, resolveObjectKey} from '../helpers/helpers.core'; -import {_limitValue, sign} from '../helpers/helpers.math'; +import { + clipArea, unclipArea, _arrayUnique, isArray, isNullOrUndef, + valueOrDefault, resolveObjectKey, _limitValue, sign +} from '../helpers'; + +function getAllScaleValues(scale) { + if (!scale._cache.$bar) { + const metas = scale.getMatchingVisibleMetas('bar'); + let values = []; + + for (let i = 0, ilen = metas.length; i < ilen; i++) { + values = values.concat(metas[i].controller.getAllParsedValues(scale)); + } + scale._cache.$bar = _arrayUnique(values.sort((a, b) => a - b)); + } + return scale._cache.$bar; +} /** * Computes the "optimal" sample size to maintain bars equally sized while preventing overlap. * @private */ -function computeMinSampleSize(scale, pixels) { +function computeMinSampleSize(scale) { + const values = getAllScaleValues(scale); let min = scale._length; - let prev, curr, i, ilen; + let i, ilen, curr, prev; + const updateMinAndPrev = () => { + min = Math.min(min, i && Math.abs(curr - prev) || min); + prev = curr; + }; - for (i = 1, ilen = pixels.length; i < ilen; ++i) { - min = Math.min(min, Math.abs(pixels[i] - pixels[i - 1])); + for (i = 0, ilen = values.length; i < ilen; ++i) { + curr = scale.getPixelForValue(values[i]); + updateMinAndPrev(); } for (i = 0, ilen = scale.ticks.length; i < ilen; ++i) { curr = scale.getPixelForTick(i); - min = i > 0 ? Math.min(min, Math.abs(curr - prev)) : min; - prev = curr; + updateMinAndPrev(); } return min; @@ -365,7 +384,7 @@ export default class BarController extends DatasetController { // only if the barThickness option is defined // Since a scriptable option may return null or undefined that // means the option would have to be of type number - const min = computeMinSampleSize(iScale, pixels); + const min = computeMinSampleSize(iScale); return { min, diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 14225354d..82433fc19 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -344,6 +344,7 @@ export default class Scale extends Element { this._userMin = undefined; this._ticksLength = 0; this._borderValue = 0; + this._cache = {}; } /** @@ -418,7 +419,9 @@ export default class Scale extends Element { return {min, max}; } - invalidateCaches() {} + invalidateCaches() { + this._cache = {}; + } /** * Get the padding needed for the scale diff --git a/test/fixtures/controller.bar/bar-thickness-min-interval-multi.json b/test/fixtures/controller.bar/bar-thickness-min-interval-multi.json new file mode 100644 index 000000000..6868b8e99 --- /dev/null +++ b/test/fixtures/controller.bar/bar-thickness-min-interval-multi.json @@ -0,0 +1,44 @@ +{ + "config": { + "type": "bar", + "data": { + "datasets": [{ + "backgroundColor": "#FF6384", + "barPercentage": 1, + "categoryPercentage": 1, + "data": [{"x": "2001", "y": 1}, {"x": "2099", "y": 5}] + }, { + "backgroundColor": "#8463FF", + "barPercentage": 1, + "categoryPercentage": 1, + "data": [{"x": "2019", "y": 2}, {"x": "2020", "y": 3}] + }] + }, + "options": { + "responsive": false, + "legend": false, + "title": false, + "scales": { + "x": { + "type": "time", + "display": false, + "min": "2000", + "max": "2100", + "time": { + "parser": "YYYY" + } + }, + "y": { + "display": false, + "beginAtZero": true + } + } + } + }, + "options": { + "canvas": { + "height": 256, + "width": 512 + } + } +} diff --git a/test/fixtures/controller.bar/bar-thickness-min-interval-multi.png b/test/fixtures/controller.bar/bar-thickness-min-interval-multi.png new file mode 100644 index 0000000000000000000000000000000000000000..01ad1fa1614ae4dbb6aeb7f18dd860f22aeda841 GIT binary patch literal 3898 zcmeHK|4&m_6u3~_zoal+6@+^oda!i}B&|`AS6Aew@SFpp3}6W{grQ zX-q8a{@jn%$KYy?SFtw~-mG|42@?K}{mE6AzQ3Zla?u^Dt0?bv$K*sGV~c|YVT2mZ z)@OJg3!GP0Ttkbq!w;RV#i?JO&flol#5S>2W`w6iBe$MizLt*06_aZvW@#fvP&uJ| z#y~Yl8C0dfNsDOa?oBajtLeJ}pd&a*%UfU=er3&wz)YZH<`|#3J2;*SfJnfLQenth zKh%v3F7Z3**iBmUKeX+DB6yy`d5z!VyukL|P`o4x8oTHdw=5*ooo44Iil*M9G49Y| zjO%w#2&M0$$cR#^w^p9TC7D(iaNV%oh)zv@k52g<4}jX35~xHGQvLoUOc?c-8vwUp zL$;8PWYy8WaG(f3F={d%?*>q|pgdj5yOKv_<&UPRMHY9spgXGfi!%Q(RHYa&J7s zh_+l0BP~^}U2nm9?)$^0Hc6jp%wzkyMZlOtm1q!;*#Poj?h~AJ_0sIDxb1UtYUT{|1pg|9i1fH zEvyTG{S=f)qSwxq3rx?g>Qp6T`DqIQAm%QGc^&XZ;N?bub_y6*hj#T@X`iRJauST7XbSQt7J^YUiO=z z6Ezd}ibDzGfuTJhrY3Y=2fPt@$q`r`6)=TZ)a~LY4t(bs_$Nk+0|ygLGIjNT@bq`K literal 0 HcmV?d00001