```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;
/* ... */
## 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.
* `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`
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;
chart._animationsDisabled = isAnimationDisabled(newOptions);
chart.ensureScalesHaveIDs();
chart.buildOrUpdateScales();
-
- chart.tooltip.initialize();
}
const KNOWN_POSITIONS = new Set(['top', 'bottom', 'left', 'right', 'chartArea']);
me.resize(true);
}
- me.initToolTip();
-
// After init plugin notification
plugins.notify(me, 'afterInit');
*/
reset() {
this.resetElements();
- this.tooltip.initialize();
+ plugins.notify(this, 'reset');
}
update(mode) {
layers[i].draw(me.chartArea);
}
- me._drawTooltip();
-
plugins.notify(me, 'afterDraw');
}
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
return this.canvas.toDataURL.apply(this.canvas, arguments);
}
- initToolTip() {
- this.tooltip = new Tooltip({_chart: this});
- }
-
/**
* @private
*/
*/
eventHandler(e) {
const me = this;
- const tooltip = me.tooltip;
if (plugins.notify(me, 'beforeEvent', [e]) === false) {
return;
me.handleEvent(e);
- if (tooltip) {
- tooltip.handleEvent(e);
- }
-
plugins.notify(me, 'afterEvent', [e]);
me.render();
* @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`,
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;
Chart.Scale = Scale;
Chart.scaleService = scaleService;
Chart.Ticks = Ticks;
-Chart.Tooltip = Tooltip;
// Register built-in scales
import scales from './scales';
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
};
'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;
*/
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);
+ }
+ }
+};
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();
});
});
// 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'));
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',
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();
});
];
var mockContext = window.createMockContext();
- var tooltip = new Chart.Tooltip({
+ var tooltip = new Tooltip({
_chart: {
options: {
tooltips: {