From: Evert Timberg Date: Thu, 25 Jun 2020 17:51:34 +0000 (-0400) Subject: Update tooltip when the display position changes (#7469) X-Git-Tag: v3.0.0-beta.2~71 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba5c9e01c63072a4c44c129e0f15b3f1c64b15bb;p=thirdparty%2FChart.js.git Update tooltip when the display position changes (#7469) --- diff --git a/src/plugins/plugin.tooltip.js b/src/plugins/plugin.tooltip.js index 4016fd808..6f239f64b 100644 --- a/src/plugins/plugin.tooltip.js +++ b/src/plugins/plugin.tooltip.js @@ -1023,8 +1023,14 @@ export class Tooltip extends Element { } } + // When there are multiple items shown, but the tooltip position is nearest mode + // an update may need to be made because our position may have changed even though + // the items are the same as before. + const position = positioners[options.position].call(me, active, e); + const positionChanged = this.caretX !== position.x || this.caretY !== position.y; + // Remember Last Actives - changed = replay || !_elementsEqual(active, lastActive); + changed = replay || !_elementsEqual(active, lastActive) || positionChanged; // Only handle target event on tooltip change if (changed) { diff --git a/test/specs/plugin.tooltip.tests.js b/test/specs/plugin.tooltip.tests.js index 3ead8db7b..3478102b2 100644 --- a/test/specs/plugin.tooltip.tests.js +++ b/test/specs/plugin.tooltip.tests.js @@ -884,7 +884,7 @@ describe('Core.Tooltip', function() { var firstPoint = meta.data[1]; var tooltip = chart.tooltip; - spyOn(tooltip, 'update'); + spyOn(tooltip, 'update').and.callThrough(); afterEvent(chart, 'mousemove', function() { expect(tooltip.update).toHaveBeenCalledWith(true); @@ -904,6 +904,74 @@ describe('Core.Tooltip', function() { jasmine.triggerMouseEvent(chart, 'mousemove', firstPoint); }); + it('Should update if active elements are the same, but the position has changed', function(done) { + const chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + label: 'Dataset 1', + data: [10, 20, 30], + pointHoverBorderColor: 'rgb(255, 0, 0)', + pointHoverBackgroundColor: 'rgb(0, 255, 0)' + }, { + label: 'Dataset 2', + data: [40, 40, 40], + pointHoverBorderColor: 'rgb(0, 0, 255)', + pointHoverBackgroundColor: 'rgb(0, 255, 255)' + }], + labels: ['Point 1', 'Point 2', 'Point 3'] + }, + options: { + scales: { + x: { + stacked: true, + }, + y: { + stacked: true + } + }, + tooltips: { + mode: 'nearest', + position: 'nearest', + intersect: true, + callbacks: { + title: function() { + return 'registering callback...'; + } + } + } + } + }); + + // Trigger an event over top of the + const meta = chart.getDatasetMeta(0); + const firstPoint = meta.data[1]; + + const meta2 = chart.getDatasetMeta(1); + const secondPoint = meta2.data[1]; + + const tooltip = chart.tooltip; + spyOn(tooltip, 'update'); + + afterEvent(chart, 'mousemove', function() { + expect(tooltip.update).toHaveBeenCalledWith(true); + + // Reset calls + tooltip.update.calls.reset(); + + afterEvent(chart, 'mousemove', function() { + expect(tooltip.update).toHaveBeenCalledWith(true); + + done(); + }); + // Second dispatch change event (same event), should update tooltip + // because position mode is 'nearest' + jasmine.triggerMouseEvent(chart, 'mousemove', secondPoint); + }); + // First dispatch change event, should update tooltip + jasmine.triggerMouseEvent(chart, 'mousemove', firstPoint); + }); + describe('positioners', function() { it('Should call custom positioner with correct parameters and scope', function(done) { @@ -945,7 +1013,7 @@ describe('Core.Tooltip', function() { var fn = tooltipPlugin.positioners.test; afterEvent(chart, 'mousemove', function() { - expect(fn.calls.count()).toBe(1); + expect(fn.calls.count()).toBe(2); expect(fn.calls.first().args[0] instanceof Array).toBe(true); expect(Object.prototype.hasOwnProperty.call(fn.calls.first().args[1], 'x')).toBe(true); expect(Object.prototype.hasOwnProperty.call(fn.calls.first().args[1], 'y')).toBe(true);