From 50fd869334b389046986e8f69fa4741ff087fad4 Mon Sep 17 00:00:00 2001 From: RatherLogical <39105734+RatherLogical@users.noreply.github.com> Date: Tue, 29 Oct 2019 06:39:07 -0400 Subject: [PATCH] Update tooltip content and styling on update() (#6635) Update tooltip content and styling on update() --- src/core/core.controller.js | 48 +++++++++++++++++++++-------- src/core/core.tooltip.js | 27 ++++++++++++++-- test/specs/core.controller.tests.js | 8 ++--- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/core/core.controller.js b/src/core/core.controller.js index c2ef85e807f..63dfe68cd4b 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -504,8 +504,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ { // after update. me.tooltip.initialize(); - // Last active contains items that were previously in the tooltip. - // When we reset the tooltip, we need to clear it + // Last active contains items that were previously hovered. me.lastActive = []; // Do this before render so that any plugins that need final scale updates can use it @@ -522,6 +521,11 @@ helpers.extend(Chart.prototype, /** @lends Chart */ { } else { me.render(config); } + + // Replay last event from before update + if (me._lastEvent) { + me.eventHandler(me._lastEvent); + } }, /** @@ -693,14 +697,20 @@ helpers.extend(Chart.prototype, /** @lends Chart */ { */ transition: function(easingValue) { var me = this; + var i, ilen; - for (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) { + for (i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) { if (me.isDatasetVisible(i)) { me.getDatasetMeta(i).controller.transition(easingValue); } } me.tooltip.transition(easingValue); + + if (me._lastEvent && me.animating) { + // If, during animation, element under mouse changes, let's react to that. + me.handleEvent(me._lastEvent); + } }, /** @@ -982,6 +992,25 @@ helpers.extend(Chart.prototype, /** @lends Chart */ { } }, + /** + * @private + */ + _updateHoverStyles: function() { + var me = this; + var options = me.options || {}; + var hoverOptions = options.hover; + + // Remove styling for last active (even if it may still be active) + if (me.lastActive.length) { + me.updateHoverStyle(me.lastActive, hoverOptions.mode, false); + } + + // Built-in hover styling + if (me.active.length && hoverOptions.mode) { + me.updateHoverStyle(me.active, hoverOptions.mode, true); + } + }, + /** * @private */ @@ -1049,8 +1078,10 @@ helpers.extend(Chart.prototype, /** @lends Chart */ { // Find Active Elements for hover and tooltips if (e.type === 'mouseout') { me.active = []; + me._lastEvent = null; } else { me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions); + me._lastEvent = e.type === 'click' ? null : e; } // Invoke onHover hook @@ -1064,16 +1095,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ { } } - // Remove styling for last active (even if it may still be active) - if (me.lastActive.length) { - me.updateHoverStyle(me.lastActive, hoverOptions.mode, false); - } - - // Built in hover styling - if (me.active.length && hoverOptions.mode) { - me.updateHoverStyle(me.active, hoverOptions.mode, true); - } - + me._updateHoverStyles(); changed = !helpers.arrayEquals(me.active, me.lastActive); // Remember Last Actives diff --git a/src/core/core.tooltip.js b/src/core/core.tooltip.js index d4a892e2e53..f1aeee29894 100644 --- a/src/core/core.tooltip.js +++ b/src/core/core.tooltip.js @@ -77,7 +77,7 @@ defaults._set('global', { labelColor: function(tooltipItem, chart) { var meta = chart.getDatasetMeta(tooltipItem.datasetIndex); var activeElement = meta.data[tooltipItem.index]; - var view = activeElement._view; + var view = activeElement.$previousStyle || activeElement._view; return { borderColor: view.borderColor, backgroundColor: view.backgroundColor @@ -489,8 +489,25 @@ function getBeforeAfterBodyLines(callback) { var exports = Element.extend({ initialize: function() { - this._model = getBaseModel(this._options); - this._lastActive = []; + var me = this; + me._model = getBaseModel(me._options); + me._view = {}; + me._lastActive = []; + }, + + transition: function(easingValue) { + var me = this; + var options = me._options; + + if (me._lastEvent && me._chart.animating) { + // Let's react to changes during animation + me._active = me._chart.getElementsAtEventForMode(me._lastEvent, options.mode, options); + me.update(true); + me.pivot(); + me._lastActive = me.active; + } + + Element.prototype.transition.call(me, easingValue); }, // Get the title @@ -985,8 +1002,12 @@ var exports = Element.extend({ // Find Active Elements for tooltips if (e.type === 'mouseout') { me._active = []; + me._lastEvent = null; } else { me._active = me._chart.getElementsAtEventForMode(e, options.mode, options); + if (e.type !== 'click') { + me._lastEvent = e.type === 'click' ? null : e; + } if (options.reverse) { me._active.reverse(); } diff --git a/test/specs/core.controller.tests.js b/test/specs/core.controller.tests.js index e41f24a4db6..5b09d975ef3 100644 --- a/test/specs/core.controller.tests.js +++ b/test/specs/core.controller.tests.js @@ -1142,7 +1142,7 @@ describe('Chart', function() { expect(chart.tooltip._options).toEqual(jasmine.objectContaining(newTooltipConfig)); }); - it ('should reset the tooltip on update', function() { + it ('should update the tooltip on update', function() { var chart = acquireChart({ type: 'line', data: { @@ -1172,10 +1172,10 @@ describe('Chart', function() { expect(chart.lastActive).toEqual([point]); expect(tooltip._lastActive).toEqual([point]); - // Update and confirm tooltip is reset + // Update and confirm tooltip is updated chart.update(); - expect(chart.lastActive).toEqual([]); - expect(tooltip._lastActive).toEqual([]); + expect(chart.lastActive).toEqual([point]); + expect(tooltip._lastActive).toEqual([point]); }); it ('should update the metadata', function() {