From: Dan Onoshko Date: Thu, 18 Aug 2022 11:34:35 +0000 (+0400) Subject: fix: same-looking tooltips on charts (#10548) X-Git-Tag: v4.0.0~53 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e7372ade240ea67769ed218cd420129bac403dfa;p=thirdparty%2FChart.js.git fix: same-looking tooltips on charts (#10548) * fix: same-looking tooltips on multiseries charts * fix: same-looknig tooltips on all chart types * chore: restore tooltip plugin * docs: additions to migration guide * docs: remove labels from scatter and bubble examples * docs: review fix --- diff --git a/docs/migration/v4-migration.md b/docs/migration/v4-migration.md index 255fa9cec..743c6bc14 100644 --- a/docs/migration/v4-migration.md +++ b/docs/migration/v4-migration.md @@ -4,6 +4,10 @@ Chart.js 4.0 introduces a number of breaking changes. We tried keeping the amoun ## End user migration +### Charts + +* Charts don't override the default tooltip callbacks, so all chart types have the same-looking tooltips. + ### Options A number of changes were made to the configuration options passed to the `Chart` constructor. Those changes are documented below. diff --git a/docs/samples/other-charts/bubble.md b/docs/samples/other-charts/bubble.md index 92a452574..5170387eb 100644 --- a/docs/samples/other-charts/bubble.md +++ b/docs/samples/other-charts/bubble.md @@ -1,13 +1,35 @@ # Bubble ```js chart-editor +// +const DATA_COUNT = 7; +const NUMBER_CFG = {count: DATA_COUNT, rmin: 5, rmax: 15, min: 0, max: 100}; + +const data = { + datasets: [ + { + label: 'Dataset 1', + data: Utils.bubbles(NUMBER_CFG), + borderColor: Utils.CHART_COLORS.red, + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5), + }, + { + label: 'Dataset 2', + data: Utils.bubbles(NUMBER_CFG), + borderColor: Utils.CHART_COLORS.orange, + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5), + } + ] +}; +// + // const actions = [ { name: 'Randomize', handler(chart) { chart.data.datasets.forEach(dataset => { - dataset.data = Utils.bubbles({count: chart.data.labels.length, rmin: 5, rmax: 15, min: 0, max: 100}); + dataset.data = Utils.bubbles({count: DATA_COUNT, rmin: 5, rmax: 15, min: 0, max: 100}); }); chart.update(); } @@ -15,13 +37,13 @@ const actions = [ { name: 'Add Dataset', handler(chart) { - const data = chart.data; - const dsColor = Utils.namedColor(chart.data.datasets.length); + const chartData = chart.data; + const dsColor = Utils.namedColor(chartData.datasets.length); const newDataset = { - label: 'Dataset ' + (data.datasets.length + 1), + label: 'Dataset ' + (chartData.datasets.length + 1), backgroundColor: Utils.transparentize(dsColor, 0.5), borderColor: dsColor, - data: Utils.bubbles({count: data.labels.length, rmin: 5, rmax: 15, min: 0, max: 100}), + data: Utils.bubbles({count: DATA_COUNT, rmin: 5, rmax: 15, min: 0, max: 100}), }; chart.data.datasets.push(newDataset); chart.update(); @@ -30,11 +52,11 @@ const actions = [ { name: 'Add Data', handler(chart) { - const data = chart.data; - if (data.datasets.length > 0) { + const chartData = chart.data; + if (chartData.datasets.length > 0) { - for (let index = 0; index < data.datasets.length; ++index) { - data.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 5, rmax: 15, min: 0, max: 100})[0]); + for (let index = 0; index < chartData.datasets.length; ++index) { + chartData.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 5, rmax: 15, min: 0, max: 100})[0]); } chart.update(); @@ -51,8 +73,6 @@ const actions = [ { name: 'Remove Data', handler(chart) { - chart.data.labels.splice(-1, 1); // remove the label first - chart.data.datasets.forEach(dataset => { dataset.data.pop(); }); @@ -63,30 +83,6 @@ const actions = [ ]; // -// -const DATA_COUNT = 7; -const NUMBER_CFG = {count: DATA_COUNT, rmin: 5, rmax: 15, min: 0, max: 100}; - -const labels = Utils.months({count: 7}); -const data = { - labels: labels, - datasets: [ - { - label: 'Dataset 1', - data: Utils.bubbles(NUMBER_CFG), - borderColor: Utils.CHART_COLORS.red, - backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5), - }, - { - label: 'Dataset 2', - data: Utils.bubbles(NUMBER_CFG), - borderColor: Utils.CHART_COLORS.orange, - backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5), - } - ] -}; -// - // const config = { type: 'bubble', @@ -113,4 +109,4 @@ module.exports = { ``` ## Docs -* [Bubble](../../charts/bubble.html) \ No newline at end of file +* [Bubble](../../charts/bubble.html) diff --git a/docs/samples/other-charts/scatter-multi-axis.md b/docs/samples/other-charts/scatter-multi-axis.md index a350c4462..32eb822c8 100644 --- a/docs/samples/other-charts/scatter-multi-axis.md +++ b/docs/samples/other-charts/scatter-multi-axis.md @@ -1,13 +1,37 @@ # Scatter - Multi axis ```js chart-editor +// +const DATA_COUNT = 7; +const NUMBER_CFG = {count: DATA_COUNT, rmin: 1, rmax: 1, min: -100, max: 100}; + +const data = { + datasets: [ + { + label: 'Dataset 1', + data: Utils.bubbles(NUMBER_CFG), + borderColor: Utils.CHART_COLORS.red, + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5), + yAxisID: 'y', + }, + { + label: 'Dataset 2', + data: Utils.bubbles(NUMBER_CFG), + borderColor: Utils.CHART_COLORS.orange, + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5), + yAxisID: 'y2', + } + ] +}; +// + // const actions = [ { name: 'Randomize', handler(chart) { chart.data.datasets.forEach(dataset => { - dataset.data = Utils.bubbles({count: chart.data.labels.length, rmin: 1, rmax: 1, min: -100, max: 100}); + dataset.data = Utils.bubbles({count: DATA_COUNT, rmin: 1, rmax: 1, min: -100, max: 100}); }); chart.update(); } @@ -15,13 +39,13 @@ const actions = [ { name: 'Add Dataset', handler(chart) { - const data = chart.data; - const dsColor = Utils.namedColor(chart.data.datasets.length); + const chartData = chart.data; + const dsColor = Utils.namedColor(chartData.datasets.length); const newDataset = { - label: 'Dataset ' + (data.datasets.length + 1), + label: 'Dataset ' + (chartData.datasets.length + 1), backgroundColor: Utils.transparentize(dsColor, 0.5), borderColor: dsColor, - data: Utils.bubbles({count: data.labels.length, rmin: 1, rmax: 1, min: -100, max: 100}), + data: Utils.bubbles({count: DATA_COUNT, rmin: 1, rmax: 1, min: -100, max: 100}), }; chart.data.datasets.push(newDataset); chart.update(); @@ -30,11 +54,11 @@ const actions = [ { name: 'Add Data', handler(chart) { - const data = chart.data; - if (data.datasets.length > 0) { + const chartData = chart.data; + if (chartData.datasets.length > 0) { - for (let index = 0; index < data.datasets.length; ++index) { - data.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 1, rmax: 1, min: -100, max: 100})[0]); + for (let index = 0; index < chartData.datasets.length; ++index) { + chartData.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 1, rmax: 1, min: -100, max: 100})[0]); } chart.update(); @@ -51,8 +75,6 @@ const actions = [ { name: 'Remove Data', handler(chart) { - chart.data.labels.splice(-1, 1); // remove the label first - chart.data.datasets.forEach(dataset => { dataset.data.pop(); }); @@ -63,32 +85,6 @@ const actions = [ ]; // -// -const DATA_COUNT = 7; -const NUMBER_CFG = {count: DATA_COUNT, rmin: 1, rmax: 1, min: -100, max: 100}; - -const labels = Utils.months({count: 7}); -const data = { - labels: labels, - datasets: [ - { - label: 'Dataset 1', - data: Utils.bubbles(NUMBER_CFG), - borderColor: Utils.CHART_COLORS.red, - backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5), - yAxisID: 'y', - }, - { - label: 'Dataset 2', - data: Utils.bubbles(NUMBER_CFG), - borderColor: Utils.CHART_COLORS.orange, - backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5), - yAxisID: 'y2', - } - ] -}; -// - // const config = { type: 'scatter', @@ -137,4 +133,4 @@ module.exports = { ## Docs * [Scatter](../../charts/scatter.html) * [Cartesian Axes](../../axes/cartesian/) - * [Axis Position](../../axes/cartesian/#axis-position) \ No newline at end of file + * [Axis Position](../../axes/cartesian/#axis-position) diff --git a/docs/samples/other-charts/scatter.md b/docs/samples/other-charts/scatter.md index 50831f0d4..c2fb43c9b 100644 --- a/docs/samples/other-charts/scatter.md +++ b/docs/samples/other-charts/scatter.md @@ -1,13 +1,35 @@ # Scatter ```js chart-editor +// +const DATA_COUNT = 7; +const NUMBER_CFG = {count: DATA_COUNT, rmin: 1, rmax: 1, min: 0, max: 100}; + +const data = { + datasets: [ + { + label: 'Dataset 1', + data: Utils.bubbles(NUMBER_CFG), + borderColor: Utils.CHART_COLORS.red, + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5), + }, + { + label: 'Dataset 2', + data: Utils.bubbles(NUMBER_CFG), + borderColor: Utils.CHART_COLORS.orange, + backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5), + } + ] +}; +// + // const actions = [ { name: 'Randomize', handler(chart) { chart.data.datasets.forEach(dataset => { - dataset.data = Utils.bubbles({count: chart.data.labels.length, rmin: 1, rmax: 1, min: 0, max: 100}); + dataset.data = Utils.bubbles({count: DATA_COUNT, rmin: 1, rmax: 1, min: 0, max: 100}); }); chart.update(); } @@ -15,13 +37,13 @@ const actions = [ { name: 'Add Dataset', handler(chart) { - const data = chart.data; - const dsColor = Utils.namedColor(chart.data.datasets.length); + const chartData = chart.data; + const dsColor = Utils.namedColor(chartData.datasets.length); const newDataset = { - label: 'Dataset ' + (data.datasets.length + 1), + label: 'Dataset ' + (chartData.datasets.length + 1), backgroundColor: Utils.transparentize(dsColor, 0.5), borderColor: dsColor, - data: Utils.bubbles({count: data.labels.length, rmin: 1, rmax: 1, min: 0, max: 100}), + data: Utils.bubbles({count: DATA_COUNT, rmin: 1, rmax: 1, min: 0, max: 100}), }; chart.data.datasets.push(newDataset); chart.update(); @@ -30,11 +52,11 @@ const actions = [ { name: 'Add Data', handler(chart) { - const data = chart.data; - if (data.datasets.length > 0) { + const chartData = chart.data; + if (chartData.datasets.length > 0) { - for (let index = 0; index < data.datasets.length; ++index) { - data.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 1, rmax: 1, min: 0, max: 100})[0]); + for (let index = 0; index < chartData.datasets.length; ++index) { + chartData.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 1, rmax: 1, min: 0, max: 100})[0]); } chart.update(); @@ -51,8 +73,6 @@ const actions = [ { name: 'Remove Data', handler(chart) { - chart.data.labels.splice(-1, 1); // remove the label first - chart.data.datasets.forEach(dataset => { dataset.data.pop(); }); @@ -63,30 +83,6 @@ const actions = [ ]; // -// -const DATA_COUNT = 7; -const NUMBER_CFG = {count: DATA_COUNT, rmin: 1, rmax: 1, min: 0, max: 100}; - -const labels = Utils.months({count: 7}); -const data = { - labels: labels, - datasets: [ - { - label: 'Dataset 1', - data: Utils.bubbles(NUMBER_CFG), - borderColor: Utils.CHART_COLORS.red, - backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5), - }, - { - label: 'Dataset 2', - data: Utils.bubbles(NUMBER_CFG), - borderColor: Utils.CHART_COLORS.orange, - backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5), - } - ] -}; -// - // const config = { type: 'scatter', @@ -113,4 +109,4 @@ module.exports = { ``` ## Docs -* [Scatter](../../charts/scatter.html) \ No newline at end of file +* [Scatter](../../charts/scatter.html) diff --git a/src/controllers/controller.bubble.js b/src/controllers/controller.bubble.js index cd212f625..c5cfa827d 100644 --- a/src/controllers/controller.bubble.js +++ b/src/controllers/controller.bubble.js @@ -31,16 +31,6 @@ export default class BubbleController extends DatasetController { y: { type: 'linear' } - }, - plugins: { - tooltip: { - callbacks: { - title() { - // Title doesn't make sense for scatter since we format the data as a point - return ''; - } - } - } } }; @@ -105,6 +95,7 @@ export default class BubbleController extends DatasetController { */ getLabelAndValue(index) { const meta = this._cachedMeta; + const labels = this.chart.data.labels || []; const {xScale, yScale} = meta; const parsed = this.getParsed(index); const x = xScale.getLabelForValue(parsed.x); @@ -112,7 +103,7 @@ export default class BubbleController extends DatasetController { const r = parsed._custom; return { - label: meta.label, + label: labels[index] || '', value: '(' + x + ', ' + y + (r ? ', ' + r : '') + ')' }; } diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index 4b036d9d7..53666b8bc 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -1,5 +1,5 @@ import DatasetController from '../core/core.datasetController'; -import {isArray, isObject, resolveObjectKey, toPercentage, toDimension, valueOrDefault} from '../helpers/helpers.core'; +import {isObject, resolveObjectKey, toPercentage, toDimension, valueOrDefault} from '../helpers/helpers.core'; import {formatNumber} from '../helpers/helpers.intl'; import {toRadians, PI, TAU, HALF_PI, _angleBetween} from '../helpers/helpers.math'; @@ -119,28 +119,6 @@ export default class DoughnutController extends DatasetController { legend.chart.toggleDataVisibility(legendItem.index); legend.chart.update(); } - }, - tooltip: { - callbacks: { - title() { - return ''; - }, - label(tooltipItem) { - let dataLabel = tooltipItem.label; - const value = ': ' + tooltipItem.formattedValue; - - if (isArray(dataLabel)) { - // show value on first line of multiline label - // need to clone because we are changing the value - dataLabel = dataLabel.slice(); - dataLabel[0] += value; - } else { - dataLabel += value; - } - - return dataLabel; - } - } } } }; diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index fb96606a6..54f522271 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -63,18 +63,6 @@ export default class PolarAreaController extends DatasetController { legend.chart.toggleDataVisibility(legendItem.index); legend.chart.update(); } - }, - - // Need to override these to give a nice default - tooltip: { - callbacks: { - title() { - return ''; - }, - label(context) { - return context.chart.data.labels[context.dataIndex] + ': ' + context.formattedValue; - } - } } }, diff --git a/src/controllers/controller.scatter.js b/src/controllers/controller.scatter.js index f2bdb0f37..44fc59276 100644 --- a/src/controllers/controller.scatter.js +++ b/src/controllers/controller.scatter.js @@ -26,19 +26,6 @@ export default class ScatterController extends DatasetController { mode: 'point' }, - plugins: { - tooltip: { - callbacks: { - title() { - return ''; // doesn't make sense for scatter since data are formatted as a point - }, - label(item) { - return '(' + item.label + ', ' + item.formattedValue + ')'; - } - } - } - }, - scales: { x: { type: 'linear' @@ -49,6 +36,23 @@ export default class ScatterController extends DatasetController { } }; + /** + * @protected + */ + getLabelAndValue(index) { + const meta = this._cachedMeta; + const labels = this.chart.data.labels || []; + const {xScale, yScale} = meta; + const parsed = this.getParsed(index); + const x = xScale.getLabelForValue(parsed.x); + const y = yScale.getLabelForValue(parsed.y); + + return { + label: labels[index] || '', + value: '(' + x + ', ' + y + ')' + }; + } + update(mode) { const meta = this._cachedMeta; const {data: points = []} = meta; diff --git a/test/specs/controller.bar.tests.js b/test/specs/controller.bar.tests.js index 53a99b991..53a473847 100644 --- a/test/specs/controller.bar.tests.js +++ b/test/specs/controller.bar.tests.js @@ -1675,4 +1675,50 @@ describe('Chart.controllers.bar', function() { expect(unevenChart).not.toThrow(); }); + + it('should not override tooltip title and label callbacks', async() => { + const chart = window.acquireChart({ + type: 'bar', + data: { + labels: ['Label 1', 'Label 2'], + datasets: [{ + data: [21, 79], + label: 'Dataset 1' + }, { + data: [33, 67], + label: 'Dataset 2' + }] + }, + options: { + responsive: true, + maintainAspectRatio: true, + } + }); + const {tooltip} = chart; + const point = chart.getDatasetMeta(0).data[0]; + + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Label 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Dataset 1: 21'], + after: [] + }]); + + chart.options.plugins.tooltip = {mode: 'dataset'}; + chart.update(); + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Dataset 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Label 1: 21'], + after: [] + }, { + before: [], + lines: ['Label 2: 79'], + after: [] + }]); + }); }); diff --git a/test/specs/controller.bubble.tests.js b/test/specs/controller.bubble.tests.js index 50589aa4c..ed15ec5f0 100644 --- a/test/specs/controller.bubble.tests.js +++ b/test/specs/controller.bubble.tests.js @@ -359,4 +359,68 @@ describe('Chart.controllers.bubble', function() { expect(point.options.radius).toBe(20); }); }); + + it('should not override tooltip title and label callbacks', async() => { + const chart = window.acquireChart({ + type: 'bubble', + data: { + labels: ['Label 1', 'Label 2'], + datasets: [{ + data: [{ + x: 10, + y: 15, + r: 15 + }, + { + x: 12, + y: 10, + r: 10 + }], + label: 'Dataset 1' + }, { + data: [{ + x: 20, + y: 10, + r: 5 + }, + { + x: 4, + y: 8, + r: 30 + }], + label: 'Dataset 2' + }] + }, + options: { + responsive: true, + maintainAspectRatio: true, + } + }); + const {tooltip} = chart; + const point = chart.getDatasetMeta(0).data[0]; + + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Label 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Dataset 1: (10, 15, 15)'], + after: [] + }]); + + chart.options.plugins.tooltip = {mode: 'dataset'}; + chart.update(); + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Dataset 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Label 1: (10, 15, 15)'], + after: [] + }, { + before: [], + lines: ['Label 2: (12, 10, 10)'], + after: [] + }]); + }); }); diff --git a/test/specs/controller.doughnut.tests.js b/test/specs/controller.doughnut.tests.js index c3bb1d9f2..a4596b690 100644 --- a/test/specs/controller.doughnut.tests.js +++ b/test/specs/controller.doughnut.tests.js @@ -398,4 +398,50 @@ describe('Chart.controllers.doughnut', function() { expect(arc.options.borderWidth).toBe(2); }); }); + + it('should not override tooltip title and label callbacks', async() => { + const chart = window.acquireChart({ + type: 'doughnut', + data: { + labels: ['Label 1', 'Label 2'], + datasets: [{ + data: [21, 79], + label: 'Dataset 1' + }, { + data: [33, 67], + label: 'Dataset 2' + }] + }, + options: { + responsive: true, + maintainAspectRatio: true, + } + }); + const {tooltip} = chart; + const point = chart.getDatasetMeta(0).data[0]; + + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Label 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Dataset 1: 21'], + after: [] + }]); + + chart.options.plugins.tooltip = {mode: 'dataset'}; + chart.update(); + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Dataset 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Label 1: 21'], + after: [] + }, { + before: [], + lines: ['Label 2: 79'], + after: [] + }]); + }); }); diff --git a/test/specs/controller.line.tests.js b/test/specs/controller.line.tests.js index c4f2fcd61..2a758f649 100644 --- a/test/specs/controller.line.tests.js +++ b/test/specs/controller.line.tests.js @@ -1063,4 +1063,50 @@ describe('Chart.controllers.line', function() { chart._handleEvent(event, false, true); }, 500); + + it('should not override tooltip title and label callbacks', async() => { + const chart = window.acquireChart({ + type: 'line', + data: { + labels: ['Label 1', 'Label 2'], + datasets: [{ + data: [21, 79], + label: 'Dataset 1' + }, { + data: [33, 67], + label: 'Dataset 2' + }] + }, + options: { + responsive: true, + maintainAspectRatio: true, + } + }); + const {tooltip} = chart; + const point = chart.getDatasetMeta(0).data[0]; + + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Label 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Dataset 1: 21'], + after: [] + }]); + + chart.options.plugins.tooltip = {mode: 'dataset'}; + chart.update(); + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Dataset 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Label 1: 21'], + after: [] + }, { + before: [], + lines: ['Label 2: 79'], + after: [] + }]); + }); }); diff --git a/test/specs/controller.polarArea.tests.js b/test/specs/controller.polarArea.tests.js index a5266e215..394cdb573 100644 --- a/test/specs/controller.polarArea.tests.js +++ b/test/specs/controller.polarArea.tests.js @@ -347,4 +347,50 @@ describe('Chart.controllers.polarArea', function() { expect(arc.options.borderWidth).toBe(2); }); }); + + it('should not override tooltip title and label callbacks', async() => { + const chart = window.acquireChart({ + type: 'polarArea', + data: { + labels: ['Label 1', 'Label 2'], + datasets: [{ + data: [21, 79], + label: 'Dataset 1' + }, { + data: [33, 67], + label: 'Dataset 2' + }] + }, + options: { + responsive: true, + maintainAspectRatio: true, + } + }); + const {tooltip} = chart; + const point = chart.getDatasetMeta(0).data[0]; + + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Label 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Dataset 1: 21'], + after: [] + }]); + + chart.options.plugins.tooltip = {mode: 'dataset'}; + chart.update(); + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Dataset 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Label 1: 21'], + after: [] + }, { + before: [], + lines: ['Label 2: 79'], + after: [] + }]); + }); }); diff --git a/test/specs/controller.radar.tests.js b/test/specs/controller.radar.tests.js index 7e691d01c..154b54821 100644 --- a/test/specs/controller.radar.tests.js +++ b/test/specs/controller.radar.tests.js @@ -406,4 +406,50 @@ describe('Chart.controllers.radar', function() { var meta = chart.getDatasetMeta(0); expect(meta.vScale.id).toBe('test'); }); + + it('should not override tooltip title and label callbacks', async() => { + const chart = window.acquireChart({ + type: 'radar', + data: { + labels: ['Label 1', 'Label 2'], + datasets: [{ + data: [21, 79], + label: 'Dataset 1' + }, { + data: [33, 67], + label: 'Dataset 2' + }] + }, + options: { + responsive: true, + maintainAspectRatio: true, + } + }); + const {tooltip} = chart; + const point = chart.getDatasetMeta(0).data[0]; + + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Label 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Dataset 1: 21'], + after: [] + }]); + + chart.options.plugins.tooltip = {mode: 'dataset'}; + chart.update(); + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Dataset 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Label 1: 21'], + after: [] + }, { + before: [], + lines: ['Label 2: 79'], + after: [] + }]); + }); }); diff --git a/test/specs/controller.scatter.tests.js b/test/specs/controller.scatter.tests.js index 1e89849a4..b8bcbc297 100644 --- a/test/specs/controller.scatter.tests.js +++ b/test/specs/controller.scatter.tests.js @@ -5,28 +5,6 @@ describe('Chart.controllers.scatter', function() { expect(typeof Chart.controllers.scatter).toBe('function'); }); - it('should test default tooltip callbacks', async function() { - var chart = window.acquireChart({ - type: 'scatter', - data: { - datasets: [{ - data: [{ - x: 10, - y: 15 - }], - label: 'dataset1' - }], - }, - options: {} - }); - var point = chart.getDatasetMeta(0).data[0]; - - await jasmine.triggerMouseEvent(chart, 'mousemove', point); - // Title should be empty - expect(chart.tooltip.title.length).toBe(0); - expect(chart.tooltip.body[0].lines).toEqual(['(10, 15)']); - }); - it('should only show a single point in the tooltip on multiple datasets', async function() { var chart = window.acquireChart({ type: 'scatter', @@ -164,4 +142,64 @@ describe('Chart.controllers.scatter', function() { var meta = chart.getDatasetMeta(0); expect(meta.dataset instanceof Chart.elements.LineElement).toBe(true); }); + + it('should not override tooltip title and label callbacks', async() => { + const chart = window.acquireChart({ + type: 'scatter', + data: { + labels: ['Label 1', 'Label 2'], + datasets: [{ + data: [{ + x: 10, + y: 15 + }, + { + x: 12, + y: 10 + }], + label: 'Dataset 1' + }, { + data: [{ + x: 20, + y: 10 + }, + { + x: 4, + y: 8 + }], + label: 'Dataset 2' + }] + }, + options: { + responsive: true, + maintainAspectRatio: true, + } + }); + const {tooltip} = chart; + const point = chart.getDatasetMeta(0).data[0]; + + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Label 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Dataset 1: (10, 15)'], + after: [] + }]); + + chart.options.plugins.tooltip = {mode: 'dataset'}; + chart.update(); + await jasmine.triggerMouseEvent(chart, 'mousemove', point); + + expect(tooltip.title).toEqual(['Dataset 1']); + expect(tooltip.body).toEqual([{ + before: [], + lines: ['Label 1: (10, 15)'], + after: [] + }, { + before: [], + lines: ['Label 2: (12, 10)'], + after: [] + }]); + }); }); diff --git a/test/specs/global.defaults.tests.js b/test/specs/global.defaults.tests.js index 31b763b7e..c46ef3a9f 100644 --- a/test/specs/global.defaults.tests.js +++ b/test/specs/global.defaults.tests.js @@ -1,87 +1,5 @@ describe('Default Configs', function() { - describe('Bubble Chart', function() { - it('should return correct tooltip strings', function() { - var chart = window.acquireChart({ - type: 'bubble', - data: { - datasets: [{ - label: 'My dataset', - data: [{ - x: 10, - y: 12, - r: 5 - }] - }] - }, - }); - - // fake out the tooltip hover and force the tooltip to update - chart.tooltip._active = [{element: chart.getDatasetMeta(0).data[0], datasetIndex: 0, index: 0}]; - chart.tooltip.update(); - - // Title is always blank - expect(chart.tooltip.title).toEqual([]); - expect(chart.tooltip.body).toEqual([{ - before: [], - lines: ['My dataset: (10, 12, 5)'], - after: [] - }]); - }); - }); - describe('Doughnut Chart', function() { - it('should return correct tooltip strings', function() { - var chart = window.acquireChart({ - type: 'doughnut', - data: { - labels: ['label1', 'label2', 'label3'], - datasets: [{ - data: [10, 20, 30], - }] - }, - }); - - // fake out the tooltip hover and force the tooltip to update - chart.tooltip._active = [{element: chart.getDatasetMeta(0).data[1], datasetIndex: 0, index: 1}]; - chart.tooltip.update(); - - // Title is always blank - expect(chart.tooltip.title).toEqual([]); - expect(chart.tooltip.body).toEqual([{ - before: [], - lines: ['label2: 20'], - after: [] - }]); - }); - - it('should return correct tooltip string for a multiline label', function() { - var chart = window.acquireChart({ - type: 'doughnut', - data: { - labels: ['label1', ['row1', 'row2', 'row3'], 'label3'], - datasets: [{ - data: [10, 20, 30], - }] - }, - }); - - // fake out the tooltip hover and force the tooltip to update - chart.tooltip._active = [{element: chart.getDatasetMeta(0).data[1], datasetIndex: 0, index: 1}]; - chart.tooltip.update(); - - // Title is always blank - expect(chart.tooltip.title).toEqual([]); - expect(chart.tooltip.body).toEqual([{ - before: [], - lines: [ - 'row1: 20', - 'row2', - 'row3' - ], - after: [] - }]); - }); - it('should return correct legend label objects', function() { var chart = window.acquireChart({ type: 'doughnut', @@ -155,30 +73,6 @@ describe('Default Configs', function() { }); describe('Polar Area Chart', function() { - it('should return correct tooltip strings', function() { - var chart = window.acquireChart({ - type: 'polarArea', - data: { - labels: ['label1', 'label2', 'label3'], - datasets: [{ - data: [10, 20, 30], - }] - }, - }); - - // fake out the tooltip hover and force the tooltip to update - chart.tooltip._active = [{element: chart.getDatasetMeta(0).data[1], datasetIndex: 0, index: 1}]; - chart.tooltip.update(); - - // Title is always blank - expect(chart.tooltip.title).toEqual([]); - expect(chart.tooltip.body).toEqual([{ - before: [], - lines: ['label2: 20'], - after: [] - }]); - }); - it('should return correct legend label objects', function() { var chart = window.acquireChart({ type: 'polarArea',