Skip to content

Commit

Permalink
Adjust legend hitboxes when RTL and each item has a different size (#…
Browse files Browse the repository at this point in the history
…9353)

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

* Add test for RTL legend hitboxes
  • Loading branch information
etimberg committed Jul 10, 2021
1 parent 6ab2e8c commit 27b91b7
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 20 deletions.
23 changes: 3 additions & 20 deletions src/plugins/plugin.legend.js
Expand Up @@ -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]);
Expand All @@ -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);
Expand All @@ -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;
}
}
Expand Down
52 changes: 52 additions & 0 deletions test/fixtures/plugin.legend/horizontal-rtl-hitbox.js
@@ -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
},
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 27b91b7

Please sign in to comment.