]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Fix: relative position in FF (#7792)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Sun, 13 Sep 2020 21:20:14 +0000 (00:20 +0300)
committerGitHub <noreply@github.com>
Sun, 13 Sep 2020 21:20:14 +0000 (17:20 -0400)
* Fix: relative position in FF
* Add tests

src/helpers/helpers.dom.js
test/specs/helpers.dom.tests.js

index 1a2376a05f512a163c8bf4329504546c716bc272..34052002a4c9093bd9d698bf45e9e6593b029472 100644 (file)
@@ -93,16 +93,28 @@ export function getRelativePosition(evt, chart) {
        const e = evt.originalEvent || evt;
        const touches = e.touches;
        const source = touches && touches.length ? touches[0] : e;
-       const clientX = source.clientX;
-       const clientY = source.clientY;
+       const {offsetX, offsetY, layerX, layerY, target} = source;
 
-       const x = source.offsetX || source.layerX || clientX;
-       const y = source.offsetY || source.layerY || clientY;
+       if (offsetX > 0 || offsetY > 0) {
+               return {
+                       x: offsetX,
+                       y: offsetY
+               };
+       }
 
-       if (x !== clientX && y !== clientY) {
-               return {x, y};
+       if (layerX > 0 || layerY > 0) {
+               return {
+                       x: layerX - target.offsetLeft,
+                       y: layerY - target.offsetTop
+               };
        }
 
+       return calculateRelativePositionFromClientXY(source, chart);
+}
+
+function calculateRelativePositionFromClientXY(source, chart) {
+       const {clientX: x, clientY: y} = source;
+
        const canvasElement = chart.canvas;
        const devicePixelRatio = chart.currentDevicePixelRatio;
        const boundingRect = canvasElement.getBoundingClientRect();
index ab614deeea176e917d3c83220798b31b534eac07..454322dbec97182daaf4c64d43fffea24b88beb9 100644 (file)
@@ -256,4 +256,83 @@ describe('DOM helpers tests', function() {
                expect(canvas.style.width).toBe('400px');
        });
 
+       describe('getRelativePosition', function() {
+               it('should use offsetX/Y when available', function() {
+                       const event = {offsetX: 0, offsetY: 10};
+                       const chart = undefined;
+                       expect(helpers.getRelativePosition(event, chart)).toEqual({x: 0, y: 10});
+               });
+
+               it('should use layerX/Y - target offsets when available', function() {
+                       const chart = undefined;
+
+                       const event1 = {
+                               layerX: 0,
+                               layerY: 10,
+                               target: {
+                                       offsetLeft: 0,
+                                       offsetTop: 5
+                               }
+                       };
+                       expect(helpers.getRelativePosition(event1, chart)).toEqual({x: 0, y: 5});
+
+                       const event2 = {
+                               offsetX: 0,
+                               offsetY: 0,
+                               layerX: 10,
+                               layerY: 10,
+                               target: {
+                                       offsetLeft: 0,
+                                       offsetTop: 5
+                               }
+                       };
+                       expect(helpers.getRelativePosition(event2, chart)).toEqual({x: 10, y: 5});
+               });
+
+               it('should calculate from clientX/Y if offset/layer coords are not available', function() {
+                       const chart = window.acquireChart({}, {
+                               canvas: {
+                                       height: 200,
+                                       width: 200,
+                               }
+                       });
+
+                       const event = {
+                               clientX: 50,
+                               clientY: 100
+                       };
+
+                       const rect = chart.canvas.getBoundingClientRect();
+                       expect(helpers.getRelativePosition(event, chart)).toEqual({
+                               x: Math.round(event.clientX - rect.x),
+                               y: Math.round(event.clientY - rect.y)
+                       });
+
+                       const chart2 = window.acquireChart({}, {
+                               canvas: {
+                                       height: 200,
+                                       width: 200,
+                                       style: 'padding: 10px'
+                               }
+                       });
+                       const rect2 = chart2.canvas.getBoundingClientRect();
+                       expect(helpers.getRelativePosition(event, chart2)).toEqual({
+                               x: Math.round((event.clientX - rect2.x - 10) / 180 * 200),
+                               y: Math.round((event.clientY - rect2.y - 10) / 180 * 200)
+                       });
+
+                       const chart3 = window.acquireChart({}, {
+                               canvas: {
+                                       height: 200,
+                                       width: 200,
+                                       style: 'width: 400px, height: 400px; padding: 10px'
+                               }
+                       });
+                       const rect3 = chart3.canvas.getBoundingClientRect();
+                       expect(helpers.getRelativePosition(event, chart3)).toEqual({
+                               x: Math.round((event.clientX - rect3.x - 10) / 360 * 400),
+                               y: Math.round((event.clientY - rect3.y - 10) / 360 * 400)
+                       });
+               });
+       });
 });