]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Adjust legend hitboxes when RTL and each item has a different size (#9353)
authorEvert Timberg <evert.timberg+github@gmail.com>
Sat, 10 Jul 2021 22:36:46 +0000 (18:36 -0400)
committerGitHub <noreply@github.com>
Sat, 10 Jul 2021 22:36:46 +0000 (18:36 -0400)
* Adjust legend hitboxes when RTL and
each item has a different size

* Add test for RTL legend hitboxes

src/plugins/plugin.legend.js
test/fixtures/plugin.legend/horizontal-rtl-hitbox.js [new file with mode: 0644]
test/fixtures/plugin.legend/horizontal-rtl-hitbox.png [new file with mode: 0644]

index 5f431c10c2eefa02654fbda817ca89ba26f6a87a..87108b8815fa9d485f85957fcafaeb42699c44bb 100644 (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;
       }
     }
diff --git a/test/fixtures/plugin.legend/horizontal-rtl-hitbox.js b/test/fixtures/plugin.legend/horizontal-rtl-hitbox.js
new file mode 100644 (file)
index 0000000..99218ce
--- /dev/null
@@ -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 (file)
index 0000000..a2ae13e
Binary files /dev/null and b/test/fixtures/plugin.legend/horizontal-rtl-hitbox.png differ