]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Convert Tooltip to a plugin (#6990)
authorEvert Timberg <evert.timberg+github@gmail.com>
Tue, 21 Jan 2020 11:36:53 +0000 (06:36 -0500)
committerGitHub <noreply@github.com>
Tue, 21 Jan 2020 11:36:53 +0000 (06:36 -0500)
* Convert Tooltip to a plugin
* code review feedback
* Update docs. Convert positioners map to be on the plugin directly

docs/configuration/tooltip.md
docs/getting-started/v3-migration.md
src/core/core.controller.js
src/core/core.plugins.js
src/index.js
src/plugins/index.js
src/plugins/plugin.tooltip.js [moved from src/core/core.tooltip.js with 96% similarity]
test/specs/global.namespace.tests.js
test/specs/plugin.tooltip.tests.js [moved from test/specs/core.tooltip.tests.js with 98% similarity]

index d57568b7f4feb5d04c2aeb254f6b55cdf29790bf..3d59d469016901e3d46371f85aa17fd7840c0162 100644 (file)
@@ -61,13 +61,14 @@ Example:
 ```javascript
 /**
  * Custom positioner
- * @function Chart.Tooltip.positioners.custom
+ * @function Tooltip.positioners.custom
  * @param elements {Chart.Element[]} the tooltip elements
  * @param eventPosition {Point} the position of the event in canvas coordinates
  * @returns {Point} the tooltip position
  */
-Chart.Tooltip.positioners.custom = function(elements, eventPosition) {
-    /** @type {Chart.Tooltip} */
+const tooltipPlugin = Chart.plugins.getAll().find(p => p.id === 'tooltip');
+tooltipPlugin.positioners.custom = function(elements, eventPosition) {
+    /** @type {Tooltip} */
     var tooltip = this;
 
     /* ... */
@@ -99,7 +100,7 @@ Allows filtering of [tooltip items](#tooltip-item-interface). Must implement at
 
 ## Tooltip Callbacks
 
-The tooltip label configuration is nested below the tooltip configuration using the `callbacks` key. The tooltip has the following callbacks for providing text. For all functions, `this` will be the tooltip object created from the `Chart.Tooltip` constructor.
+The tooltip label configuration is nested below the tooltip configuration using the `callbacks` key. The tooltip has the following callbacks for providing text. For all functions, `this` will be the tooltip object created from the `Tooltip` constructor.
 
 All functions are called with the same arguments: a [tooltip item](#tooltip-item-interface) and the `data` object passed to the chart. All functions must return either a string or an array of strings. Arrays of strings are treated as multiple lines of text.
 
index d11ccb1f760c343c2fc280f118c2190db277cd45..c1ce806003ef6e8b932668e541fef06a23f6666d 100644 (file)
@@ -79,6 +79,7 @@ Animation system was completely rewritten in Chart.js v3. Each property can now
 * `Chart.Controller`
 * `Chart.prototype.generateLegend`
 * `Chart.types`
+* `Chart.Tooltip` is now provided by the tooltip plugin. The positioners can be accessed from `tooltipPlugin.positioners`
 * `DatasetController.addElementAndReset`
 * `DatasetController.createMetaData`
 * `DatasetController.createMetaDataset`
index 488f81e98f7a4293e46467009e19eef59daff278..3f1749f2f98d09c07d6f29bef1294028933a129e 100644 (file)
@@ -9,7 +9,6 @@ import layouts from './core.layouts';
 import platform from '../platforms/platform';
 import plugins from './core.plugins';
 import scaleService from '../core/core.scaleService';
-import Tooltip from './core.tooltip';
 
 const valueOrDefault = helpers.valueOrDefault;
 
@@ -117,8 +116,6 @@ function updateConfig(chart) {
        chart._animationsDisabled = isAnimationDisabled(newOptions);
        chart.ensureScalesHaveIDs();
        chart.buildOrUpdateScales();
-
-       chart.tooltip.initialize();
 }
 
 const KNOWN_POSITIONS = new Set(['top', 'bottom', 'left', 'right', 'chartArea']);
@@ -218,8 +215,6 @@ class Chart {
                        me.resize(true);
                }
 
-               me.initToolTip();
-
                // After init plugin notification
                plugins.notify(me, 'afterInit');
 
@@ -466,7 +461,7 @@ class Chart {
        */
        reset() {
                this.resetElements();
-               this.tooltip.initialize();
+               plugins.notify(this, 'reset');
        }
 
        update(mode) {
@@ -638,8 +633,6 @@ class Chart {
                        layers[i].draw(me.chartArea);
                }
 
-               me._drawTooltip();
-
                plugins.notify(me, 'afterDraw');
        }
 
@@ -723,27 +716,6 @@ class Chart {
                plugins.notify(me, 'afterDatasetDraw', [args]);
        }
 
-       /**
-        * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw`
-        * hook, in which case, plugins will not be called on `afterTooltipDraw`.
-        * @private
-        */
-       _drawTooltip() {
-               const me = this;
-               const tooltip = me.tooltip;
-               const args = {
-                       tooltip: tooltip
-               };
-
-               if (plugins.notify(me, 'beforeTooltipDraw', [args]) === false) {
-                       return;
-               }
-
-               tooltip.draw(me.ctx);
-
-               plugins.notify(me, 'afterTooltipDraw', [args]);
-       }
-
        /**
         * Get the single element that was clicked on
         * @return An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
@@ -866,10 +838,6 @@ class Chart {
                return this.canvas.toDataURL.apply(this.canvas, arguments);
        }
 
-       initToolTip() {
-               this.tooltip = new Tooltip({_chart: this});
-       }
-
        /**
         * @private
         */
@@ -958,7 +926,6 @@ class Chart {
         */
        eventHandler(e) {
                const me = this;
-               const tooltip = me.tooltip;
 
                if (plugins.notify(me, 'beforeEvent', [e]) === false) {
                        return;
@@ -966,10 +933,6 @@ class Chart {
 
                me.handleEvent(e);
 
-               if (tooltip) {
-                       tooltip.handleEvent(e);
-               }
-
                plugins.notify(me, 'afterEvent', [e]);
 
                me.render();
index 6772637af03d6b4a66d811610a03e2a3cd80acfd..4f7a03d2faadbdd0d837ef19cac3597ca3ecb5d8 100644 (file)
@@ -200,6 +200,13 @@ export default {
  * @param {Chart.Controller} chart - The chart instance.
  * @param {object} options - The plugin options.
  */
+/**
+ * @method IPlugin#reset
+ * @desc Called during chart reset
+ * @param {Chart.Controller} chart - The chart instance.
+ * @param {object} options - The plugin options.
+ * @since version 3.0.0
+ */
 /**
  * @method IPlugin#beforeDatasetsUpdate
  * @desc Called before updating the `chart` datasets. If any plugin returns `false`,
index 8e8ef17e1bae84124b506db701548ad9c66260cd..e472b1528fa55326abe495e42bc23714d202ebe1 100644 (file)
@@ -20,7 +20,6 @@ import pluginsCore from './core/core.plugins';
 import Scale from './core/core.scale';
 import scaleService from './core/core.scaleService';
 import Ticks from './core/core.ticks';
-import Tooltip from './core/core.tooltip';
 
 Chart.helpers = helpers;
 Chart._adapters = _adapters;
@@ -39,7 +38,6 @@ Chart.plugins = pluginsCore;
 Chart.Scale = Scale;
 Chart.scaleService = scaleService;
 Chart.Ticks = Ticks;
-Chart.Tooltip = Tooltip;
 
 // Register built-in scales
 import scales from './scales';
index 1cd2a03638cdc031974be9c8e926c424187c3c55..939df980f6d739ea7a8daa5f337ca5b90651b7e3 100644 (file)
@@ -3,9 +3,11 @@
 import filler from './plugin.filler';
 import legend from './plugin.legend';
 import title from './plugin.title';
+import tooltip from './plugin.tooltip';
 
 export default {
        filler,
        legend,
-       title
+       title,
+       tooltip
 };
similarity index 96%
rename from src/core/core.tooltip.js
rename to src/plugins/plugin.tooltip.js
index 5aff16c63e06e05d858a7a3bbf5f60228cd443d5..0c5bc1eed5e088eedcab017b2a2970d95a930ded 100644 (file)
@@ -1,9 +1,10 @@
 'use strict';
 
-import defaults from './core.defaults';
-import Element from './core.element';
+import Animations from '../core/core.animations';
+import defaults from '../core/core.defaults';
+import Element from '../core/core.element';
+import plugins from '../core/core.plugins';
 import helpers from '../helpers/index';
-import Animations from './core.animations';
 
 const valueOrDefault = helpers.valueOrDefault;
 const getRtlHelper = helpers.rtl.getRtlAdapter;
@@ -1001,4 +1002,49 @@ class Tooltip extends Element {
  */
 Tooltip.positioners = positioners;
 
-export default Tooltip;
+export default {
+       id: 'tooltip',
+       _element: Tooltip,
+       positioners,
+
+       afterInit: function(chart) {
+               const tooltipOpts = chart.options.tooltips;
+
+               if (tooltipOpts) {
+                       chart.tooltip = new Tooltip({_chart: chart});
+               }
+       },
+
+       beforeUpdate: function(chart) {
+               if (chart.tooltip) {
+                       chart.tooltip.initialize();
+               }
+       },
+
+       reset: function(chart) {
+               if (chart.tooltip) {
+                       chart.tooltip.initialize();
+               }
+       },
+
+       afterDraw: function(chart) {
+               const tooltip = chart.tooltip;
+               const args = {
+                       tooltip
+               };
+
+               if (plugins.notify(chart, 'beforeTooltipDraw', [args]) === false) {
+                       return;
+               }
+
+               tooltip.draw(chart.ctx);
+
+               plugins.notify(chart, 'afterTooltipDraw', [args]);
+       },
+
+       afterEvent: function(chart, e) {
+               if (chart.tooltip) {
+                       chart.tooltip.handleEvent(e);
+               }
+       }
+};
index 89f8cad5b60a4f92ac58ecf9336332dd92402d91..8e4ffa5e7e705fa45e9b8a04d52190e80eba7c18 100644 (file)
@@ -16,8 +16,6 @@ describe('Chart namespace', function() {
                        expect(Chart.Scale instanceof Object).toBeTruthy();
                        expect(Chart.scaleService instanceof Object).toBeTruthy();
                        expect(Chart.Ticks instanceof Object).toBeTruthy();
-                       expect(Chart.Tooltip instanceof Object).toBeTruthy();
-                       expect(Chart.Tooltip.positioners instanceof Object).toBeTruthy();
                });
        });
 
similarity index 98%
rename from test/specs/core.tooltip.tests.js
rename to test/specs/plugin.tooltip.tests.js
index b1f9cc2b403683943b19a41ce0a719929ad36a2f..b890922e4229138fef55487540615e83ce8b7573 100644 (file)
@@ -1,4 +1,7 @@
 // Test the rectangle element
+const tooltipPlugin = Chart.plugins.getAll().find(p => p.id === 'tooltip');
+const Tooltip = tooltipPlugin._element;
+
 describe('Core.Tooltip', function() {
        describe('auto', jasmine.fixture.specs('core.tooltip'));
 
@@ -890,11 +893,11 @@ describe('Core.Tooltip', function() {
        describe('positioners', function() {
                it('Should call custom positioner with correct parameters and scope', function(done) {
 
-                       Chart.Tooltip.positioners.test = function() {
+                       tooltipPlugin.positioners.test = function() {
                                return {x: 0, y: 0};
                        };
 
-                       spyOn(Chart.Tooltip.positioners, 'test').and.callThrough();
+                       spyOn(tooltipPlugin.positioners, 'test').and.callThrough();
 
                        var chart = window.acquireChart({
                                type: 'line',
@@ -925,14 +928,14 @@ describe('Core.Tooltip', function() {
                        var datasetIndex = 0;
                        var meta = chart.getDatasetMeta(datasetIndex);
                        var point = meta.data[pointIndex];
-                       var fn = Chart.Tooltip.positioners.test;
+                       var fn = tooltipPlugin.positioners.test;
 
                        afterEvent(chart, 'mousemove', function() {
                                expect(fn.calls.count()).toBe(1);
                                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);
-                               expect(fn.calls.first().object instanceof Chart.Tooltip).toBe(true);
+                               expect(fn.calls.first().object instanceof Tooltip).toBe(true);
 
                                done();
                        });
@@ -1261,7 +1264,7 @@ describe('Core.Tooltip', function() {
                ];
 
                var mockContext = window.createMockContext();
-               var tooltip = new Chart.Tooltip({
+               var tooltip = new Tooltip({
                        _chart: {
                                options: {
                                        tooltips: {