mirror of
https://github.com/chartjs/Chart.js.git
synced 2026-03-03 06:54:02 +01:00
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
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -1,75 +1,11 @@
|
||||
# Bubble
|
||||
|
||||
```js chart-editor
|
||||
// <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});
|
||||
});
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Dataset',
|
||||
handler(chart) {
|
||||
const data = chart.data;
|
||||
const dsColor = Utils.namedColor(chart.data.datasets.length);
|
||||
const newDataset = {
|
||||
label: 'Dataset ' + (data.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}),
|
||||
};
|
||||
chart.data.datasets.push(newDataset);
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Data',
|
||||
handler(chart) {
|
||||
const data = chart.data;
|
||||
if (data.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]);
|
||||
}
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Dataset',
|
||||
handler(chart) {
|
||||
chart.data.datasets.pop();
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Data',
|
||||
handler(chart) {
|
||||
chart.data.labels.splice(-1, 1); // remove the label first
|
||||
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data.pop();
|
||||
});
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
];
|
||||
// </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',
|
||||
@@ -87,6 +23,66 @@ const data = {
|
||||
};
|
||||
// </block:setup>
|
||||
|
||||
// <block:actions:2>
|
||||
const actions = [
|
||||
{
|
||||
name: 'Randomize',
|
||||
handler(chart) {
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data = Utils.bubbles({count: DATA_COUNT, rmin: 5, rmax: 15, min: 0, max: 100});
|
||||
});
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Dataset',
|
||||
handler(chart) {
|
||||
const chartData = chart.data;
|
||||
const dsColor = Utils.namedColor(chartData.datasets.length);
|
||||
const newDataset = {
|
||||
label: 'Dataset ' + (chartData.datasets.length + 1),
|
||||
backgroundColor: Utils.transparentize(dsColor, 0.5),
|
||||
borderColor: dsColor,
|
||||
data: Utils.bubbles({count: DATA_COUNT, rmin: 5, rmax: 15, min: 0, max: 100}),
|
||||
};
|
||||
chart.data.datasets.push(newDataset);
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Data',
|
||||
handler(chart) {
|
||||
const chartData = chart.data;
|
||||
if (chartData.datasets.length > 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();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Dataset',
|
||||
handler(chart) {
|
||||
chart.data.datasets.pop();
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Data',
|
||||
handler(chart) {
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data.pop();
|
||||
});
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
];
|
||||
// </block:actions>
|
||||
|
||||
// <block:config:0>
|
||||
const config = {
|
||||
type: 'bubble',
|
||||
@@ -113,4 +109,4 @@ module.exports = {
|
||||
```
|
||||
|
||||
## Docs
|
||||
* [Bubble](../../charts/bubble.html)
|
||||
* [Bubble](../../charts/bubble.html)
|
||||
|
||||
@@ -1,75 +1,11 @@
|
||||
# Scatter - Multi axis
|
||||
|
||||
```js chart-editor
|
||||
// <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});
|
||||
});
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Dataset',
|
||||
handler(chart) {
|
||||
const data = chart.data;
|
||||
const dsColor = Utils.namedColor(chart.data.datasets.length);
|
||||
const newDataset = {
|
||||
label: 'Dataset ' + (data.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}),
|
||||
};
|
||||
chart.data.datasets.push(newDataset);
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Data',
|
||||
handler(chart) {
|
||||
const data = chart.data;
|
||||
if (data.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]);
|
||||
}
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Dataset',
|
||||
handler(chart) {
|
||||
chart.data.datasets.pop();
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Data',
|
||||
handler(chart) {
|
||||
chart.data.labels.splice(-1, 1); // remove the label first
|
||||
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data.pop();
|
||||
});
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
];
|
||||
// </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',
|
||||
@@ -89,6 +25,66 @@ const data = {
|
||||
};
|
||||
// </block:setup>
|
||||
|
||||
// <block:actions:2>
|
||||
const actions = [
|
||||
{
|
||||
name: 'Randomize',
|
||||
handler(chart) {
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data = Utils.bubbles({count: DATA_COUNT, rmin: 1, rmax: 1, min: -100, max: 100});
|
||||
});
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Dataset',
|
||||
handler(chart) {
|
||||
const chartData = chart.data;
|
||||
const dsColor = Utils.namedColor(chartData.datasets.length);
|
||||
const newDataset = {
|
||||
label: 'Dataset ' + (chartData.datasets.length + 1),
|
||||
backgroundColor: Utils.transparentize(dsColor, 0.5),
|
||||
borderColor: dsColor,
|
||||
data: Utils.bubbles({count: DATA_COUNT, rmin: 1, rmax: 1, min: -100, max: 100}),
|
||||
};
|
||||
chart.data.datasets.push(newDataset);
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Data',
|
||||
handler(chart) {
|
||||
const chartData = chart.data;
|
||||
if (chartData.datasets.length > 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();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Dataset',
|
||||
handler(chart) {
|
||||
chart.data.datasets.pop();
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Data',
|
||||
handler(chart) {
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data.pop();
|
||||
});
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
];
|
||||
// </block:actions>
|
||||
|
||||
// <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)
|
||||
* [Axis Position](../../axes/cartesian/#axis-position)
|
||||
|
||||
@@ -1,75 +1,11 @@
|
||||
# Scatter
|
||||
|
||||
```js chart-editor
|
||||
// <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});
|
||||
});
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Dataset',
|
||||
handler(chart) {
|
||||
const data = chart.data;
|
||||
const dsColor = Utils.namedColor(chart.data.datasets.length);
|
||||
const newDataset = {
|
||||
label: 'Dataset ' + (data.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}),
|
||||
};
|
||||
chart.data.datasets.push(newDataset);
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Data',
|
||||
handler(chart) {
|
||||
const data = chart.data;
|
||||
if (data.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]);
|
||||
}
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Dataset',
|
||||
handler(chart) {
|
||||
chart.data.datasets.pop();
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Data',
|
||||
handler(chart) {
|
||||
chart.data.labels.splice(-1, 1); // remove the label first
|
||||
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data.pop();
|
||||
});
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
];
|
||||
// </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',
|
||||
@@ -87,6 +23,66 @@ const data = {
|
||||
};
|
||||
// </block:setup>
|
||||
|
||||
// <block:actions:2>
|
||||
const actions = [
|
||||
{
|
||||
name: 'Randomize',
|
||||
handler(chart) {
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data = Utils.bubbles({count: DATA_COUNT, rmin: 1, rmax: 1, min: 0, max: 100});
|
||||
});
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Dataset',
|
||||
handler(chart) {
|
||||
const chartData = chart.data;
|
||||
const dsColor = Utils.namedColor(chartData.datasets.length);
|
||||
const newDataset = {
|
||||
label: 'Dataset ' + (chartData.datasets.length + 1),
|
||||
backgroundColor: Utils.transparentize(dsColor, 0.5),
|
||||
borderColor: dsColor,
|
||||
data: Utils.bubbles({count: DATA_COUNT, rmin: 1, rmax: 1, min: 0, max: 100}),
|
||||
};
|
||||
chart.data.datasets.push(newDataset);
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Data',
|
||||
handler(chart) {
|
||||
const chartData = chart.data;
|
||||
if (chartData.datasets.length > 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();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Dataset',
|
||||
handler(chart) {
|
||||
chart.data.datasets.pop();
|
||||
chart.update();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Remove Data',
|
||||
handler(chart) {
|
||||
chart.data.datasets.forEach(dataset => {
|
||||
dataset.data.pop();
|
||||
});
|
||||
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
];
|
||||
// </block:actions>
|
||||
|
||||
// <block:config:0>
|
||||
const config = {
|
||||
type: 'scatter',
|
||||
@@ -113,4 +109,4 @@ module.exports = {
|
||||
```
|
||||
|
||||
## Docs
|
||||
* [Scatter](../../charts/scatter.html)
|
||||
* [Scatter](../../charts/scatter.html)
|
||||
|
||||
@@ -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 : '') + ')'
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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: []
|
||||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user