Correctly determine min/max for Float Bar (#7398)

This commit is contained in:
Jukka Kurkela 2020-06-10 00:15:05 +03:00 committed by GitHub
parent 87a0653e57
commit 026482a0cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 35 deletions

View File

@ -220,6 +220,19 @@ export default class BarController extends DatasetController {
return parsed;
}
/**
* @protected
*/
updateRangeFromParsed(range, scale, parsed, stack) {
super.updateRangeFromParsed(range, scale, parsed, stack);
const custom = parsed._custom;
if (custom) {
// float bar: only one end of the bar is considered by `super`
range.min = Math.min(range.min, custom.min);
range.max = Math.max(range.max, custom.max);
}
}
/**
* @protected
*/

View File

@ -584,35 +584,39 @@ export default class DatasetController {
return applyStack(stack, value, meta.index);
}
/**
* @protected
*/
updateRangeFromParsed(range, scale, parsed, stack) {
let value = parsed[scale.axis];
const values = stack && parsed._stacks[scale.axis];
if (stack && values) {
stack.values = values;
// Need to consider individual stack values for data range,
// in addition to the stacked value
range.min = Math.min(range.min, value);
range.max = Math.max(range.max, value);
value = applyStack(stack, value, this._cachedMeta.index, true);
}
range.min = Math.min(range.min, value);
range.max = Math.max(range.max, value);
}
/**
* @protected
*/
getMinMax(scale, canStack) {
const meta = this._cachedMeta;
const me = this;
const meta = me._cachedMeta;
const _parsed = meta._parsed;
const sorted = meta._sorted && scale === meta.iScale;
const ilen = _parsed.length;
const otherScale = this._getOtherScale(scale);
const stack = canStack && meta._stacked && {keys: getSortedDatasetIndices(this.chart, true), values: null};
let min = Number.POSITIVE_INFINITY;
let max = Number.NEGATIVE_INFINITY;
const otherScale = me._getOtherScale(scale);
const stack = canStack && meta._stacked && {keys: getSortedDatasetIndices(me.chart, true), values: null};
const range = {min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY};
const {min: otherMin, max: otherMax} = getUserBounds(otherScale);
let i, value, parsed, otherValue;
function _compute() {
const values = stack && parsed._stacks[scale.axis];
if (stack && values) {
stack.values = values;
// Need to consider individual stack values for data range,
// in addition to the stacked value
min = Math.min(min, value);
max = Math.max(max, value);
value = applyStack(stack, value, meta.index, true);
}
min = Math.min(min, value);
max = Math.max(max, value);
}
function _skip() {
parsed = _parsed[i];
value = parsed[scale.axis];
@ -624,21 +628,23 @@ export default class DatasetController {
if (_skip()) {
continue;
}
_compute();
me.updateRangeFromParsed(range, scale, parsed, stack);
if (sorted) {
// if the data is sorted, we don't need to check further from this end of array
break;
}
}
if (sorted) {
// in the sorted case, find first non-skipped value from other end of array
for (i = ilen - 1; i >= 0; --i) {
if (_skip()) {
continue;
}
_compute();
me.updateRangeFromParsed(range, scale, parsed, stack);
break;
}
}
return {min, max};
return range;
}
getAllParsedValues(scale) {

View File

@ -411,7 +411,7 @@ export default class Scale extends Element {
const me = this;
// eslint-disable-next-line prefer-const
let {min, max, minDefined, maxDefined} = me.getUserBounds();
let minmax;
let range;
if (minDefined && maxDefined) {
return {min, max};
@ -419,12 +419,12 @@ export default class Scale extends Element {
const metas = me.getMatchingVisibleMetas();
for (let i = 0, ilen = metas.length; i < ilen; ++i) {
minmax = metas[i].controller.getMinMax(me, canStack);
range = metas[i].controller.getMinMax(me, canStack);
if (!minDefined) {
min = Math.min(min, minmax.min);
min = Math.min(min, range.min);
}
if (!maxDefined) {
max = Math.max(max, minmax.max);
max = Math.max(max, range.max);
}
}

View File

@ -13,9 +13,7 @@ class LinearScale extends LinearScaleBase {
determineDataLimits() {
const me = this;
const options = me.options;
const minmax = me.getMinMax(true);
const min = minmax.min;
const max = minmax.max;
const {min, max} = me.getMinMax(true);
me.min = isFinite(min) ? min : valueOrDefault(options.suggestedMin, 0);
me.max = isFinite(max) ? max : valueOrDefault(options.suggestedMax, 1);

View File

@ -81,9 +81,7 @@ class LogarithmicScale extends Scale {
determineDataLimits() {
const me = this;
const minmax = me.getMinMax(true);
const min = minmax.min;
const max = minmax.max;
const {min, max} = me.getMinMax(true);
me.min = isFinite(min) ? Math.max(0, min) : null;
me.max = isFinite(max) ? Math.max(0, max) : null;

View File

@ -323,9 +323,7 @@ class RadialLinearScale extends LinearScaleBase {
determineDataLimits() {
const me = this;
const minmax = me.getMinMax(false);
const min = minmax.min;
const max = minmax.max;
const {min, max} = me.getMinMax(false);
me.min = isFinite(min) && !isNaN(min) ? min : 0;
me.max = isFinite(max) && !isNaN(max) ? max : 0;

View File

@ -1629,4 +1629,20 @@ describe('Chart.controllers.bar', function() {
expect(data[0].base + minBarLength).toEqual(data[0].x);
expect(data[1].base - minBarLength).toEqual(data[1].x);
});
describe('Float bar', function() {
it('Should return correct values from getMinMax', function() {
var chart = window.acquireChart({
type: 'bar',
data: {
labels: ['a'],
datasets: [{
data: [[10, -10]]
}]
}
});
expect(chart.scales.y.getMinMax()).toEqual({min: -10, max: 10});
});
});
});