]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Update tooltip content and styling on update() (#6635)
authorRatherLogical <39105734+RatherLogical@users.noreply.github.com>
Tue, 29 Oct 2019 10:39:07 +0000 (06:39 -0400)
committerEvert Timberg <evert.timberg+github@gmail.com>
Tue, 29 Oct 2019 10:39:07 +0000 (06:39 -0400)
Update tooltip content and styling on update()

src/core/core.controller.js
src/core/core.tooltip.js
test/specs/core.controller.tests.js

index c2ef85e807fa44038e58bb2d4377dc7b3163ef90..63dfe68cd4bb02003404c6758037fef89de683ae 100644 (file)
@@ -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
index d4a892e2e53970e951680401eae78f4105539c97..f1aeee29894f870c01b8a7161535cc7199e78c6a 100644 (file)
@@ -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();
                        }
index e41f24a4db6af964b9292a0f322a23a68556ba56..5b09d975ef3b3738dc74f8310f10b77411ba7098 100644 (file)
@@ -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() {