Fix: display stacked bar with multiple x-Axis (#12070)

This commit is contained in:
Xavier Leune 2025-06-05 17:27:56 +02:00 committed by GitHub
parent bcc7681ba1
commit 8ea47cad19
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 92 additions and 4 deletions

View File

@ -486,6 +486,27 @@ export default class BarController extends DatasetController {
return this._getStacks(undefined, index).length;
}
_getAxisCount() {
return this._getAxis().length;
}
getFirstScaleIdForIndexAxis() {
const scales = this.chart.scales;
const indexScaleId = this.chart.options.indexAxis;
return Object.keys(scales).filter(key => scales[key].axis === indexScaleId).shift();
}
_getAxis() {
const axis = {};
const firstScaleAxisId = this.getFirstScaleIdForIndexAxis();
for (const dataset of this.chart.data.datasets) {
axis[valueOrDefault(
this.chart.options.indexAxis === 'x' ? dataset.xAxisID : dataset.yAxisID, firstScaleAxisId
)] = true;
}
return Object.keys(axis);
}
/**
* Returns the stack index for the given dataset based on groups and bar visibility.
* @param {number} [datasetIndex] - The dataset index
@ -618,13 +639,15 @@ export default class BarController extends DatasetController {
const skipNull = options.skipNull;
const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity);
let center, size;
const axisCount = this._getAxisCount();
if (ruler.grouped) {
const stackCount = skipNull ? this._getStackCount(index) : ruler.stackCount;
const range = options.barThickness === 'flex'
? computeFlexCategoryTraits(index, ruler, options, stackCount)
: computeFitCategoryTraits(index, ruler, options, stackCount);
const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined);
? computeFlexCategoryTraits(index, ruler, options, stackCount * axisCount)
: computeFitCategoryTraits(index, ruler, options, stackCount * axisCount);
const axisID = this.chart.options.indexAxis === 'x' ? this.getDataset().xAxisID : this.getDataset().yAxisID;
const axisNumber = this._getAxis().indexOf(valueOrDefault(axisID, this.getFirstScaleIdForIndexAxis()));
const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined) + axisNumber;
center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
size = Math.min(maxBarThickness, range.chunk * range.ratio);
} else {
@ -633,6 +656,7 @@ export default class BarController extends DatasetController {
size = Math.min(maxBarThickness, ruler.min * ruler.ratio);
}
return {
base: center - size / 2,
head: center + size / 2,

View File

@ -0,0 +1,64 @@
module.exports = {
config: {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'Dataset 1',
data: [100, 90, 100, 50, 99, 87, 34],
backgroundColor: 'rgba(255,99,132,0.8)',
stack: 'a',
xAxisID: 'x'
},
{
label: 'Dataset 2',
data: [20, 25, 30, 32, 58, 14, 12],
backgroundColor: 'rgba(54,162,235,0.8)',
stack: 'b',
xAxisID: 'x2'
},
{
label: 'Dataset 3',
data: [80, 30, 40, 60, 70, 80, 47],
backgroundColor: 'rgba(75,192,192,0.8)',
stack: 'a',
xAxisID: 'x3'
},
{
label: 'Dataset 4',
data: [80, 30, 40, 60, 70, 80, 47],
backgroundColor: 'rgba(54,162,235,0.8)',
stack: 'a',
xAxisID: 'x3'
},
]
},
options: {
plugins: false,
barThickness: 'flex',
scales: {
x: {
stacked: true,
display: false,
},
x2: {
labels: ['January 2024', 'February 2024', 'March 2024', 'April 2024', 'May 2024', 'June 2024', 'July 2024'],
stacked: true,
display: false,
},
x3: {
labels: ['January 2025', 'February 2025', 'March 2025', 'April 2025', 'May 2025', 'June 2025', 'July 2025'],
stacked: true,
display: false,
},
y: {
stacked: true,
display: false,
}
}
}
},
options: {
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB