mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
fix: respect minBarLength in stacked bar chart (#10766)
This commit is contained in:
parent
36fb08c946
commit
667b28beca
@ -538,7 +538,7 @@ export default class BarController extends DatasetController {
|
||||
* @private
|
||||
*/
|
||||
_calculateBarValuePixels(index) {
|
||||
const {_cachedMeta: {vScale, _stacked}, options: {base: baseValue, minBarLength}} = this;
|
||||
const {_cachedMeta: {vScale, _stacked, index: datasetIndex}, options: {base: baseValue, minBarLength}} = this;
|
||||
const actualBase = baseValue || 0;
|
||||
const parsed = this.getParsed(index);
|
||||
const custom = parsed._custom;
|
||||
@ -586,6 +586,11 @@ export default class BarController extends DatasetController {
|
||||
const max = Math.max(startPixel, endPixel);
|
||||
base = Math.max(Math.min(base, max), min);
|
||||
head = base + size;
|
||||
|
||||
if (_stacked && !floating) {
|
||||
// visual data coordinates after applying minBarLength
|
||||
parsed._stacks[vScale.axis]._visualValues[datasetIndex] = vScale.getValueForPixel(head) - vScale.getValueForPixel(base);
|
||||
}
|
||||
}
|
||||
|
||||
if (base === vScale.getPixelForValue(actualBase)) {
|
||||
|
||||
@ -158,6 +158,9 @@ function updateStacks(controller, parsed) {
|
||||
|
||||
stack._top = getLastIndexInStack(stack, vScale, true, meta.type);
|
||||
stack._bottom = getLastIndexInStack(stack, vScale, false, meta.type);
|
||||
|
||||
const visualValues = stack._visualValues || (stack._visualValues = {});
|
||||
visualValues[datasetIndex] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,6 +210,9 @@ function clearStacks(meta, items) {
|
||||
return;
|
||||
}
|
||||
delete stacks[axis][datasetIndex];
|
||||
if (stacks[axis]._visualValues !== undefined && stacks[axis]._visualValues[datasetIndex] !== undefined) {
|
||||
delete stacks[axis]._visualValues[datasetIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -578,7 +584,7 @@ export default class DatasetController {
|
||||
const value = parsed[scale.axis];
|
||||
const stack = {
|
||||
keys: getSortedDatasetIndices(chart, true),
|
||||
values: parsed._stacks[scale.axis]
|
||||
values: parsed._stacks[scale.axis]._visualValues
|
||||
};
|
||||
return applyStack(stack, value, meta.index, {mode});
|
||||
}
|
||||
|
||||
55
test/fixtures/controller.bar/minBarLength/horizontal-stacked-no-overlap.js
vendored
Normal file
55
test/fixtures/controller.bar/minBarLength/horizontal-stacked-no-overlap.js
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
const minBarLength = 50;
|
||||
|
||||
module.exports = {
|
||||
config: {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [1, 2, 3, 4],
|
||||
datasets: [
|
||||
{
|
||||
data: [1, -1, 1, 20],
|
||||
backgroundColor: '#bb000066',
|
||||
minBarLength
|
||||
},
|
||||
{
|
||||
data: [1, -1, -1, -20],
|
||||
backgroundColor: '#00bb0066',
|
||||
minBarLength
|
||||
},
|
||||
{
|
||||
data: [1, -1, 1, 40],
|
||||
backgroundColor: '#0000bb66',
|
||||
minBarLength
|
||||
},
|
||||
{
|
||||
data: [1, -1, -1, -40],
|
||||
backgroundColor: '#00000066',
|
||||
minBarLength
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
indexAxis: 'y',
|
||||
scales: {
|
||||
x: {
|
||||
display: false,
|
||||
stacked: true
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
position: 'left',
|
||||
stacked: true,
|
||||
ticks: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 512,
|
||||
width: 512
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/controller.bar/minBarLength/horizontal-stacked-no-overlap.png
vendored
Normal file
BIN
test/fixtures/controller.bar/minBarLength/horizontal-stacked-no-overlap.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
54
test/fixtures/controller.bar/minBarLength/vertical-stacked-no-overlap.js
vendored
Normal file
54
test/fixtures/controller.bar/minBarLength/vertical-stacked-no-overlap.js
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
const minBarLength = 50;
|
||||
|
||||
module.exports = {
|
||||
config: {
|
||||
type: 'bar',
|
||||
data: {
|
||||
labels: [1, 2, 3, 4],
|
||||
datasets: [
|
||||
{
|
||||
data: [1, -1, 1, 20],
|
||||
backgroundColor: '#bb000066',
|
||||
minBarLength
|
||||
},
|
||||
{
|
||||
data: [1, -1, -1, -20],
|
||||
backgroundColor: '#00bb0066',
|
||||
minBarLength
|
||||
},
|
||||
{
|
||||
data: [1, -1, 1, 40],
|
||||
backgroundColor: '#0000bb66',
|
||||
minBarLength
|
||||
},
|
||||
{
|
||||
data: [1, -1, -1, -40],
|
||||
backgroundColor: '#00000066',
|
||||
minBarLength
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
x: {
|
||||
display: false,
|
||||
stacked: true
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
position: 'left',
|
||||
stacked: true,
|
||||
ticks: {
|
||||
display: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 512,
|
||||
width: 512
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/controller.bar/minBarLength/vertical-stacked-no-overlap.png
vendored
Normal file
BIN
test/fixtures/controller.bar/minBarLength/vertical-stacked-no-overlap.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -768,12 +768,12 @@ describe('Chart.DatasetController', function() {
|
||||
|
||||
expect(chart._stacks).toEqual({
|
||||
'x.y.1': {
|
||||
0: {0: 1, 2: 3, _top: 2, _bottom: null},
|
||||
1: {0: 10, 2: 30, _top: 2, _bottom: null}
|
||||
0: {0: 1, 2: 3, _top: 2, _bottom: null, _visualValues: {0: 1, 2: 3}},
|
||||
1: {0: 10, 2: 30, _top: 2, _bottom: null, _visualValues: {0: 10, 2: 30}}
|
||||
},
|
||||
'x.y.2': {
|
||||
0: {1: 2, _top: 1, _bottom: null},
|
||||
1: {1: 20, _top: 1, _bottom: null}
|
||||
0: {1: 2, _top: 1, _bottom: null, _visualValues: {1: 2}},
|
||||
1: {1: 20, _top: 1, _bottom: null, _visualValues: {1: 20}}
|
||||
}
|
||||
});
|
||||
|
||||
@ -782,12 +782,12 @@ describe('Chart.DatasetController', function() {
|
||||
|
||||
expect(chart._stacks).toEqual({
|
||||
'x.y.1': {
|
||||
0: {0: 1, _top: 2, _bottom: null},
|
||||
1: {0: 10, _top: 2, _bottom: null}
|
||||
0: {0: 1, _top: 2, _bottom: null, _visualValues: {0: 1}},
|
||||
1: {0: 10, _top: 2, _bottom: null, _visualValues: {0: 10}}
|
||||
},
|
||||
'x.y.2': {
|
||||
0: {1: 2, 2: 3, _top: 2, _bottom: null},
|
||||
1: {1: 20, 2: 30, _top: 2, _bottom: null}
|
||||
0: {1: 2, 2: 3, _top: 2, _bottom: null, _visualValues: {1: 2, 2: 3}},
|
||||
1: {1: 20, 2: 30, _top: 2, _bottom: null, _visualValues: {1: 20, 2: 30}}
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -812,12 +812,12 @@ describe('Chart.DatasetController', function() {
|
||||
|
||||
expect(chart._stacks).toEqual({
|
||||
'x.y.1': {
|
||||
0: {0: 1, 2: 3, _top: 2, _bottom: null},
|
||||
1: {0: 10, 2: 30, _top: 2, _bottom: null}
|
||||
0: {0: 1, 2: 3, _top: 2, _bottom: null, _visualValues: {0: 1, 2: 3}},
|
||||
1: {0: 10, 2: 30, _top: 2, _bottom: null, _visualValues: {0: 10, 2: 30}}
|
||||
},
|
||||
'x.y.2': {
|
||||
0: {1: 2, _top: 1, _bottom: null},
|
||||
1: {1: 20, _top: 1, _bottom: null}
|
||||
0: {1: 2, _top: 1, _bottom: null, _visualValues: {1: 2}},
|
||||
1: {1: 20, _top: 1, _bottom: null, _visualValues: {1: 20}}
|
||||
}
|
||||
});
|
||||
|
||||
@ -826,12 +826,12 @@ describe('Chart.DatasetController', function() {
|
||||
|
||||
expect(chart._stacks).toEqual({
|
||||
'x.y.1': {
|
||||
0: {0: 1, 2: 4, _top: 2, _bottom: null},
|
||||
1: {0: 10, _top: 2, _bottom: null}
|
||||
0: {0: 1, 2: 4, _top: 2, _bottom: null, _visualValues: {0: 1, 2: 4}},
|
||||
1: {0: 10, _top: 2, _bottom: null, _visualValues: {0: 10}}
|
||||
},
|
||||
'x.y.2': {
|
||||
0: {1: 2, _top: 1, _bottom: null},
|
||||
1: {1: 20, _top: 1, _bottom: null}
|
||||
0: {1: 2, _top: 1, _bottom: null, _visualValues: {1: 2}},
|
||||
1: {1: 20, _top: 1, _bottom: null, _visualValues: {1: 20}}
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -947,7 +947,7 @@ describe('Chart.DatasetController', function() {
|
||||
});
|
||||
|
||||
var meta = chart.getDatasetMeta(0);
|
||||
expect(meta._parsed[0]._stacks).toEqual(jasmine.objectContaining({y: {0: 10, 1: 20, _top: 1, _bottom: null}}));
|
||||
expect(meta._parsed[0]._stacks).toEqual(jasmine.objectContaining({y: {0: 10, 1: 20, _top: 1, _bottom: null, _visualValues: {0: 10, 1: 20}}}));
|
||||
});
|
||||
|
||||
describe('resolveDataElementOptions', function() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user