Skip to content

Commit 8ea47ca

Browse files
authored
Fix: display stacked bar with multiple x-Axis (#12070)
1 parent bcc7681 commit 8ea47ca

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

src/controllers/controller.bar.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,27 @@ export default class BarController extends DatasetController {
486486
return this._getStacks(undefined, index).length;
487487
}
488488

489+
_getAxisCount() {
490+
return this._getAxis().length;
491+
}
492+
493+
getFirstScaleIdForIndexAxis() {
494+
const scales = this.chart.scales;
495+
const indexScaleId = this.chart.options.indexAxis;
496+
return Object.keys(scales).filter(key => scales[key].axis === indexScaleId).shift();
497+
}
498+
499+
_getAxis() {
500+
const axis = {};
501+
const firstScaleAxisId = this.getFirstScaleIdForIndexAxis();
502+
for (const dataset of this.chart.data.datasets) {
503+
axis[valueOrDefault(
504+
this.chart.options.indexAxis === 'x' ? dataset.xAxisID : dataset.yAxisID, firstScaleAxisId
505+
)] = true;
506+
}
507+
return Object.keys(axis);
508+
}
509+
489510
/**
490511
* Returns the stack index for the given dataset based on groups and bar visibility.
491512
* @param {number} [datasetIndex] - The dataset index
@@ -618,13 +639,15 @@ export default class BarController extends DatasetController {
618639
const skipNull = options.skipNull;
619640
const maxBarThickness = valueOrDefault(options.maxBarThickness, Infinity);
620641
let center, size;
642+
const axisCount = this._getAxisCount();
621643
if (ruler.grouped) {
622644
const stackCount = skipNull ? this._getStackCount(index) : ruler.stackCount;
623645
const range = options.barThickness === 'flex'
624-
? computeFlexCategoryTraits(index, ruler, options, stackCount)
625-
: computeFitCategoryTraits(index, ruler, options, stackCount);
626-
627-
const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined);
646+
? computeFlexCategoryTraits(index, ruler, options, stackCount * axisCount)
647+
: computeFitCategoryTraits(index, ruler, options, stackCount * axisCount);
648+
const axisID = this.chart.options.indexAxis === 'x' ? this.getDataset().xAxisID : this.getDataset().yAxisID;
649+
const axisNumber = this._getAxis().indexOf(valueOrDefault(axisID, this.getFirstScaleIdForIndexAxis()));
650+
const stackIndex = this._getStackIndex(this.index, this._cachedMeta.stack, skipNull ? index : undefined) + axisNumber;
628651
center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);
629652
size = Math.min(maxBarThickness, range.chunk * range.ratio);
630653
} else {
@@ -633,6 +656,7 @@ export default class BarController extends DatasetController {
633656
size = Math.min(maxBarThickness, ruler.min * ruler.ratio);
634657
}
635658

659+
636660
return {
637661
base: center - size / 2,
638662
head: center + size / 2,
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
module.exports = {
2+
config: {
3+
type: 'bar',
4+
data: {
5+
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
6+
datasets: [
7+
{
8+
label: 'Dataset 1',
9+
data: [100, 90, 100, 50, 99, 87, 34],
10+
backgroundColor: 'rgba(255,99,132,0.8)',
11+
stack: 'a',
12+
xAxisID: 'x'
13+
},
14+
{
15+
label: 'Dataset 2',
16+
data: [20, 25, 30, 32, 58, 14, 12],
17+
backgroundColor: 'rgba(54,162,235,0.8)',
18+
stack: 'b',
19+
xAxisID: 'x2'
20+
},
21+
{
22+
label: 'Dataset 3',
23+
data: [80, 30, 40, 60, 70, 80, 47],
24+
backgroundColor: 'rgba(75,192,192,0.8)',
25+
stack: 'a',
26+
xAxisID: 'x3'
27+
},
28+
{
29+
label: 'Dataset 4',
30+
data: [80, 30, 40, 60, 70, 80, 47],
31+
backgroundColor: 'rgba(54,162,235,0.8)',
32+
stack: 'a',
33+
xAxisID: 'x3'
34+
},
35+
]
36+
},
37+
options: {
38+
plugins: false,
39+
barThickness: 'flex',
40+
scales: {
41+
x: {
42+
stacked: true,
43+
display: false,
44+
},
45+
x2: {
46+
labels: ['January 2024', 'February 2024', 'March 2024', 'April 2024', 'May 2024', 'June 2024', 'July 2024'],
47+
stacked: true,
48+
display: false,
49+
},
50+
x3: {
51+
labels: ['January 2025', 'February 2025', 'March 2025', 'April 2025', 'May 2025', 'June 2025', 'July 2025'],
52+
stacked: true,
53+
display: false,
54+
},
55+
y: {
56+
stacked: true,
57+
display: false,
58+
}
59+
}
60+
}
61+
},
62+
options: {
63+
}
64+
};
Loading

0 commit comments

Comments
 (0)