From: Evert Timberg Date: Sat, 10 Jul 2021 22:36:46 +0000 (-0400) Subject: Adjust legend hitboxes when RTL and each item has a different size (#9353) X-Git-Tag: v3.5.0~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27b91b7458d34caabf5ed50cb08ff2f5f4c6dd1e;p=thirdparty%2FChart.js.git 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 --- diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 5f431c10c..87108b881 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -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; } } diff --git a/test/fixtures/plugin.legend/horizontal-rtl-hitbox.js b/test/fixtures/plugin.legend/horizontal-rtl-hitbox.js new file mode 100644 index 000000000..99218cec2 --- /dev/null +++ b/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 + }, + } +}; diff --git a/test/fixtures/plugin.legend/horizontal-rtl-hitbox.png b/test/fixtures/plugin.legend/horizontal-rtl-hitbox.png new file mode 100644 index 000000000..a2ae13e45 Binary files /dev/null and b/test/fixtures/plugin.legend/horizontal-rtl-hitbox.png differ