Adjust legend hitboxes when RTL and each item has a different size (#9353)

* Adjust legend hitboxes when RTL and
each item has a different size

* Add test for RTL legend hitboxes
This commit is contained in:
Evert Timberg 2021-07-10 18:36:46 -04:00 committed by GitHub
parent 6ab2e8cdcd
commit 27b91b7458
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 20 deletions

View File

@ -234,6 +234,7 @@ export class Legend extends Element {
}
const titleHeight = me._computeTitleHeight();
const {legendHitBoxes: hitboxes, options: {align, labels: {padding}, rtl}} = me;
const rtlHelper = getRtlAdapter(rtl, me.left, me.width);
if (this.isHorizontal()) {
let row = 0;
let left = _alignStartEnd(align, me.left + padding, me.right - me.lineWidths[row]);
@ -243,28 +244,9 @@ export class Legend extends Element {
left = _alignStartEnd(align, me.left + padding, me.right - me.lineWidths[row]);
}
hitbox.top += me.top + titleHeight + padding;
hitbox.left = left;
hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(left), hitbox.width);
left += hitbox.width + padding;
}
if (rtl) {
// When the legend is in RTL mode, each row starts at the right
// To ensure that click handling works correctly, we need to ensure that the items in the
// hitboxes array line up with how the legend items are drawn (this hack is required until V4)
const boxMap = hitboxes.reduce((map, box) => {
map[box.row] = map[box.row] || [];
map[box.row].push(box);
return map;
}, {});
const newBoxes = [];
Object.keys(boxMap).forEach(key => {
boxMap[key].reverse();
newBoxes.push(...boxMap[key]);
});
me.legendHitBoxes = newBoxes;
}
} else {
let col = 0;
let top = _alignStartEnd(align, me.top + titleHeight + padding, me.bottom - me.columnSizes[col].height);
@ -275,6 +257,7 @@ export class Legend extends Element {
}
hitbox.top = top;
hitbox.left += me.left + padding;
hitbox.left = rtlHelper.leftForLtr(rtlHelper.x(hitbox.left), hitbox.width);
top += hitbox.height + padding;
}
}

View File

@ -0,0 +1,52 @@
module.exports = {
description: 'https://github.com/chartjs/Chart.js/issues/9278',
config: {
type: 'pie',
data: {
labels: ['aaa', 'bb', 'c'],
datasets: [{
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
backgroundColor: 'red'
}]
},
options: {
plugins: {
legend: {
position: 'top',
rtl: 'true',
}
},
layout: {
padding: {
top: 50,
left: 30,
right: 30,
bottom: 50
}
}
},
plugins: [{
id: 'legend-hit-box',
afterDraw(chart) {
const ctx = chart.ctx;
ctx.save();
ctx.strokeStyle = 'green';
ctx.lineWidth = 1;
const legend = chart.legend;
legend.legendHitBoxes.forEach(box => {
ctx.strokeRect(box.left, box.top, box.width, box.height);
});
ctx.restore();
}
}]
},
options: {
spriteText: true,
canvas: {
width: 400,
height: 300
},
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB