From: Ben McCann <322311+benmccann@users.noreply.github.com> Date: Tue, 14 Jul 2020 21:40:32 +0000 (-0700) Subject: Tooltip: add dataPoint and rename value to formattedValue (#7618) X-Git-Tag: v3.0.0-beta.2~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=426d8debba3acc89525bd4369b11620b94284e04;p=thirdparty%2FChart.js.git Tooltip: add dataPoint and rename value to formattedValue (#7618) * Tooltip: add dataPoint and rename value to formattedValue * Add a test --- diff --git a/docs/docs/configuration/tooltip.md b/docs/docs/configuration/tooltip.md index e4b6dfb94..fcecd887e 100644 --- a/docs/docs/configuration/tooltip.md +++ b/docs/docs/configuration/tooltip.md @@ -134,8 +134,8 @@ var chart = new Chart(ctx, { if (label) { label += ': '; } - if (!helpers.isNullOrUndef(context.value)) { - label += '$' + context.value; + if (!isNaN(context.dataPoint.y)) { + label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(context.dataPoint.y); } return label; } @@ -184,8 +184,11 @@ The tooltip items passed to the tooltip callbacks implement the following interf // Label for the tooltip label: string, - // Value for the tooltip - value: string, + // Parsed data values for the given `dataIndex` and `datasetIndex` + dataPoint: object, + + // Formatted value for the tooltip + formattedValue: string, // The dataset the item comes from dataset: object diff --git a/docs/docs/general/options.md b/docs/docs/general/options.md index 42d744c3b..f70743566 100644 --- a/docs/docs/general/options.md +++ b/docs/docs/general/options.md @@ -41,6 +41,7 @@ The option context is used to give contextual information when resolving options The context object contains the following properties: - `chart`: the associated chart +- `dataPoint`: the parsed data values for the given `dataIndex` and `datasetIndex` - `dataIndex`: index of the current data - `dataset`: dataset at index `datasetIndex` - `datasetIndex`: index of the current dataset diff --git a/docs/docs/getting-started/v3-migration.md b/docs/docs/getting-started/v3-migration.md index 8db298d43..d296ea60b 100644 --- a/docs/docs/getting-started/v3-migration.md +++ b/docs/docs/getting-started/v3-migration.md @@ -186,12 +186,12 @@ Animation system was completely rewritten in Chart.js v3. Each property can now #### Tooltip -* `xLabel` and `yLabel` were removed. Please use `index` and `value` +* `xLabel` and `yLabel` were removed. Please use `label` and `formattedValue` * The `filter` option will now be passed additional parameters when called and should have the method signature `function(tooltipItem, index, tooltipItems, data)` * The `custom` callback now takes a context object that has `tooltip` and `chart` properties * All properties of tooltip model related to the tooltip options have been moved to reside within the `options` property. * The callbacks no longer are given a `data` parameter. The tooltip item parameter contains the chart and dataset instead -* The tooltip item's `index` parameter was renamed to `dataIndex` +* The tooltip item's `index` parameter was renamed to `dataIndex` and `value` was renamed to `formattedValue` ## Developer migration diff --git a/samples/scriptable/bar.html b/samples/scriptable/bar.html index cfb18f15e..d7504f97b 100644 --- a/samples/scriptable/bar.html +++ b/samples/scriptable/bar.html @@ -27,7 +27,7 @@ utils.srand(110); function colorize(opaque, ctx) { - var v = ctx.dataset.data[ctx.dataIndex]; + var v = ctx.dataPoint.y; var c = v < -50 ? '#D60000' : v < 0 ? '#F46300' : v < 50 ? '#0358B6' diff --git a/samples/scriptable/line.html b/samples/scriptable/line.html index 3de95d1c0..8116216c3 100644 --- a/samples/scriptable/line.html +++ b/samples/scriptable/line.html @@ -40,7 +40,7 @@ } function adjustRadiusBasedOnData(ctx) { - var v = ctx.dataset.data[ctx.dataIndex]; + var v = ctx.dataPoint.y; return v < 10 ? 5 : v < 25 ? 7 : v < 50 ? 9 diff --git a/samples/scriptable/pie.html b/samples/scriptable/pie.html index af7fb08db..78993a387 100644 --- a/samples/scriptable/pie.html +++ b/samples/scriptable/pie.html @@ -27,7 +27,7 @@ utils.srand(110); function colorize(opaque, hover, ctx) { - var v = ctx.dataset.data[ctx.dataIndex]; + var v = ctx.dataPoint; var c = v < -50 ? '#D60000' : v < 0 ? '#F46300' : v < 50 ? '#0358B6' diff --git a/samples/scriptable/radar.html b/samples/scriptable/radar.html index 6a58eae47..cc0d9cbe0 100644 --- a/samples/scriptable/radar.html +++ b/samples/scriptable/radar.html @@ -44,7 +44,7 @@ } function adjustRadiusBasedOnData(ctx) { - var v = ctx.dataset.data[ctx.dataIndex]; + var v = ctx.dataPoint.y; return v < 10 ? 5 : v < 25 ? 7 : v < 50 ? 9 diff --git a/samples/tooltips/callbacks.html b/samples/tooltips/callbacks.html index 453250aba..c544405e1 100644 --- a/samples/tooltips/callbacks.html +++ b/samples/tooltips/callbacks.html @@ -67,7 +67,7 @@ var sum = 0; tooltipItems.forEach(function(tooltipItem) { - sum += tooltipItem.dataset.data[tooltipItem.dataIndex]; + sum += tooltipItem.dataPoint.y; }); return 'Sum: ' + sum; }, diff --git a/src/controllers/controller.bubble.js b/src/controllers/controller.bubble.js index 3dd89e9f1..b7be677bc 100644 --- a/src/controllers/controller.bubble.js +++ b/src/controllers/controller.bubble.js @@ -113,6 +113,7 @@ export default class BubbleController extends DatasetController { // Scriptable options const context = { chart, + dataPoint: parsed, dataIndex: index, dataset, datasetIndex: me.index diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index 760428bb1..06bc21698 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -123,6 +123,7 @@ export default class PolarAreaController extends DatasetController { // Scriptable options const context = { chart: me.chart, + dataPoint: this.getParsed(index), dataIndex: index, dataset, datasetIndex: me.index @@ -219,7 +220,7 @@ PolarAreaController.defaults = { return ''; }, label(context) { - return context.chart.data.labels[context.dataIndex] + ': ' + context.value; + return context.chart.data.labels[context.dataIndex] + ': ' + context.formattedValue; } } } diff --git a/src/controllers/controller.scatter.js b/src/controllers/controller.scatter.js index 01200f86a..06f9c8425 100644 --- a/src/controllers/controller.scatter.js +++ b/src/controllers/controller.scatter.js @@ -30,7 +30,7 @@ ScatterController.defaults = { return ''; // doesn't make sense for scatter since data are formatted as a point }, label(item) { - return '(' + item.label + ', ' + item.value + ')'; + return '(' + item.label + ', ' + item.formattedValue + ')'; } } } diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index fb15a4b51..9f9213650 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -693,6 +693,7 @@ export default class DatasetController { _getContext(index, active) { return { chart: this.chart, + dataPoint: this.getParsed(index), dataIndex: index, dataset: this.getDataset(), datasetIndex: this.index, diff --git a/src/plugins/plugin.tooltip.js b/src/plugins/plugin.tooltip.js index 95d4000a3..d1fe58d99 100644 --- a/src/plugins/plugin.tooltip.js +++ b/src/plugins/plugin.tooltip.js @@ -124,7 +124,8 @@ function createTooltipItem(chart, item) { return { chart, label, - value, + dataPoint: controller.getParsed(index), + formattedValue: value, dataset, dataIndex: index, datasetIndex @@ -1085,7 +1086,7 @@ export default { if (label) { label += ': '; } - const value = tooltipItem.value; + const value = tooltipItem.formattedValue; if (!isNullOrUndef(value)) { label += value; } diff --git a/test/specs/plugin.tooltip.tests.js b/test/specs/plugin.tooltip.tests.js index 2fa26724d..a117b2d41 100644 --- a/test/specs/plugin.tooltip.tests.js +++ b/test/specs/plugin.tooltip.tests.js @@ -20,7 +20,7 @@ describe('Plugin.Tooltip', function() { datasetIndex: 0, dataset: data.datasets[0], label: 'Point 2', - value: '20' + formattedValue: '20' }; var label = Chart.defaults.plugins.tooltip.callbacks.label(tooltipItem); @@ -470,6 +470,47 @@ describe('Plugin.Tooltip', function() { jasmine.triggerMouseEvent(chart, 'mousemove', point); }); + + it('Should provide context object to user callbacks', function(done) { + const chart = window.acquireChart({ + type: 'line', + data: { + datasets: [{ + label: 'Dataset 1', + data: [{x: 1, y: 10}, {x: 2, y: 20}, {x: 3, y: 30}] + }] + }, + options: { + scales: { + x: { + type: 'linear' + } + }, + tooltips: { + mode: 'index', + callbacks: { + beforeLabel: function(ctx) { + return ctx.dataPoint.x + ',' + ctx.dataPoint.y; + } + } + } + } + }); + + // Trigger an event over top of the + const meta = chart.getDatasetMeta(0); + const point = meta.data[1]; + + afterEvent(chart, 'mousemove', function() { + const tooltip = chart.tooltip; + + expect(tooltip.body[0].before).toEqual(['2,20']); + + done(); + }); + jasmine.triggerMouseEvent(chart, 'mousemove', point); + }); + it('Should allow sorting items', function(done) { var chart = window.acquireChart({ type: 'line', @@ -840,8 +881,8 @@ describe('Plugin.Tooltip', function() { expect(tooltipItem.datasetIndex).toBe(datasetIndex); expect(typeof tooltipItem.label).toBe('string'); expect(tooltipItem.label).toBe(chart.data.labels[pointIndex]); - expect(typeof tooltipItem.value).toBe('string'); - expect(tooltipItem.value).toBe('' + chart.data.datasets[datasetIndex].data[pointIndex]); + expect(typeof tooltipItem.formattedValue).toBe('string'); + expect(tooltipItem.formattedValue).toBe('' + chart.data.datasets[datasetIndex].data[pointIndex]); done(); });