Skip to content

Commit

Permalink
Fix controller.getMinMax for stacked charts (#9766)
Browse files Browse the repository at this point in the history
  • Loading branch information
kurkle committed Oct 13, 2021
1 parent 6f7e095 commit 9a47395
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
19 changes: 8 additions & 11 deletions src/core/core.datasetController.js
Expand Up @@ -67,7 +67,7 @@ function getSortedDatasetIndices(chart, filterVisible) {
return keys;
}

function applyStack(stack, value, dsIndex, options) {
function applyStack(stack, value, dsIndex, options = {}) {
const keys = stack.keys;
const singleMode = options.mode === 'single';
let i, ilen, datasetIndex, otherValue;
Expand Down Expand Up @@ -212,6 +212,8 @@ function clearStacks(meta, items) {

const isDirectUpdateMode = (mode) => mode === 'reset' || mode === 'none';
const cloneIfNotShared = (cached, shared) => shared ? cached : Object.assign({}, cached);
const createStack = (canStack, meta, chart) => canStack && !meta.hidden && meta._stacked
&& {keys: getSortedDatasetIndices(chart, true), values: null};

export default class DatasetController {

Expand Down Expand Up @@ -567,11 +569,7 @@ export default class DatasetController {
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, parsedValue, this._cachedMeta.index, {all: true});
value = applyStack(stack, parsedValue, this._cachedMeta.index);
}
range.min = Math.min(range.min, value);
range.max = Math.max(range.max, value);
Expand All @@ -586,16 +584,15 @@ export default class DatasetController {
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};
const stack = createStack(canStack, meta, this.chart);
const range = {min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY};
const {min: otherMin, max: otherMax} = getUserBounds(otherScale);
let i, value, parsed, otherValue;
let i, parsed;

function _skip() {
parsed = _parsed[i];
value = parsed[scale.axis];
otherValue = parsed[otherScale.axis];
return !isFinite(value) || otherMin > otherValue || otherMax < otherValue;
const otherValue = parsed[otherScale.axis];
return !isFinite(parsed[scale.axis]) || otherMin > otherValue || otherMax < otherValue;
}

for (i = 0; i < ilen; ++i) {
Expand Down
Binary file modified test/fixtures/controller.line/stacking/bounds-data.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions test/specs/controller.line.tests.js
Expand Up @@ -59,6 +59,32 @@ describe('Chart.controllers.line', function() {
expect(createChart).not.toThrow();
});

it('should find min and max for stacked chart', function() {
var chart = window.acquireChart({
type: 'line',
data: {
datasets: [{
data: [10, 11, 12, 13]
}, {
data: [1, 2, 3, 4]
}],
labels: ['a', 'b', 'c', 'd']
},
options: {
scales: {
y: {
stacked: true
}
}
}
});
expect(chart.getDatasetMeta(0).controller.getMinMax(chart.scales.y, true)).toEqual({min: 10, max: 13});
expect(chart.getDatasetMeta(1).controller.getMinMax(chart.scales.y, true)).toEqual({min: 11, max: 17});
chart.hide(0);
expect(chart.getDatasetMeta(0).controller.getMinMax(chart.scales.y, true)).toEqual({min: 10, max: 13});
expect(chart.getDatasetMeta(1).controller.getMinMax(chart.scales.y, true)).toEqual({min: 1, max: 4});
});

it('Should create line elements and point elements for each data item during initialization', function() {
var chart = window.acquireChart({
type: 'line',
Expand Down

0 comments on commit 9a47395

Please sign in to comment.