]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
fix: same-looking tooltips on charts (#10548)
authorDan Onoshko <danon0404@gmail.com>
Thu, 18 Aug 2022 11:34:35 +0000 (15:34 +0400)
committerGitHub <noreply@github.com>
Thu, 18 Aug 2022 11:34:35 +0000 (07:34 -0400)
* 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

16 files changed:
docs/migration/v4-migration.md
docs/samples/other-charts/bubble.md
docs/samples/other-charts/scatter-multi-axis.md
docs/samples/other-charts/scatter.md
src/controllers/controller.bubble.js
src/controllers/controller.doughnut.js
src/controllers/controller.polarArea.js
src/controllers/controller.scatter.js
test/specs/controller.bar.tests.js
test/specs/controller.bubble.tests.js
test/specs/controller.doughnut.tests.js
test/specs/controller.line.tests.js
test/specs/controller.polarArea.tests.js
test/specs/controller.radar.tests.js
test/specs/controller.scatter.tests.js
test/specs/global.defaults.tests.js

index 255fa9cec1c0b38bddc3754a6c3804e31c51b289..743c6bc14dab64eea755a4caa34fad924129e2c6 100644 (file)
@@ -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.
index 92a452574883f2744fb3e44dc058f3f99943e2f1..5170387ebbf8b733ae5971756bac896bed82ced6 100644 (file)
@@ -1,13 +1,35 @@
 # Bubble
 
 ```js chart-editor
+// <block:setup:1>
+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),
+    }
+  ]
+};
+// </block:setup>
+
 // <block:actions:2>
 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 = [
 ];
 // </block:actions>
 
-// <block:setup:1>
-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),
-    }
-  ]
-};
-// </block:setup>
-
 // <block:config:0>
 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)
index a350c4462c805fb772855b4607b8ec428973174f..32eb822c84c2a48d1c7b529a83bad30f210cbf67 100644 (file)
@@ -1,13 +1,37 @@
 # Scatter - Multi axis
 
 ```js chart-editor
+// <block:setup:1>
+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',
+    }
+  ]
+};
+// </block:setup>
+
 // <block:actions:2>
 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 = [
 ];
 // </block:actions>
 
-// <block:setup:1>
-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',
-    }
-  ]
-};
-// </block:setup>
-
 // <block:config:0>
 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)
index 50831f0d4cc89e654fa29a0a7229b5b48f4eabb4..c2fb43c9b5af1eb2ae85cfd5bba1441e2c5d06f5 100644 (file)
@@ -1,13 +1,35 @@
 # Scatter
 
 ```js chart-editor
+// <block:setup:1>
+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),
+    }
+  ]
+};
+// </block:setup>
+
 // <block:actions:2>
 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 = [
 ];
 // </block:actions>
 
-// <block:setup:1>
-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),
-    }
-  ]
-};
-// </block:setup>
-
 // <block:config:0>
 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)
index cd212f625ed9abe434cc71f5f6e2ae4dbe3e3b6d..c5cfa827d012f2cd91951eee8c07e2f8cfc4f0be 100644 (file)
@@ -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 : '') + ')'
     };
   }
index 4b036d9d72202583d9250b9ce7b606ada7841d98..53666b8bc0e4a28111990ca63c6e9e333e672fe6 100644 (file)
@@ -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;
-          }
-        }
       }
     }
   };
index fb96606a62d37a97f22e8a4694f695e8d9316116..54f522271c2cb27281b3365183b6bf66b441bb1e 100644 (file)
@@ -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;
-          }
-        }
       }
     },
 
index f2bdb0f37489cad7547032491c4b2a8056a7590e..44fc59276582086217351c4e5a0744001bd67a65 100644 (file)
@@ -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;
index 53a99b99107a6bbbb504db2a6d6c51dd8f116623..53a4738477c908cc9f608bf9371fa4d14215f410 100644 (file)
@@ -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: []
+    }]);
+  });
 });
index 50589aa4c7d5bdb0ad5feeb330db0a2d115bc800..ed15ec5f0c8f051dff1ce593764eb067fb3695a6 100644 (file)
@@ -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: []
+    }]);
+  });
 });
index c3bb1d9f2be5287443a1ac758998061b16f739d2..a4596b69024ba2134142d225281ce12d8214d2b6 100644 (file)
@@ -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: []
+    }]);
+  });
 });
index c4f2fcd61f750333a70a1402a1070a208d6dd76b..2a758f649c8068f26fcd4291ac70463171a33d87 100644 (file)
@@ -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: []
+    }]);
+  });
 });
index a5266e215214ffa4a17dea5c378ec0fcdc437b53..394cdb57340217b378eed996455eab5d0c007515 100644 (file)
@@ -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: []
+    }]);
+  });
 });
index 7e691d01cb2b38fd267475278070aba6a7a6f19b..154b548219d1fe15fd0e150a5314029d5d355c38 100644 (file)
@@ -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: []
+    }]);
+  });
 });
index 1e89849a40f0c1c4f534ed237b91782aff3e8476..b8bcbc297c45e3bf071e7c79cba18c03ce74032e 100644 (file)
@@ -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: []
+    }]);
+  });
 });
index 31b763b7eabdd02353336d43d343f99a56cbe214..c46ef3a9fddbe4174ac0cc8bf74a358d8d223aed 100644 (file)
@@ -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',