if (label) {
label += ': ';
}
- if (!helpers.isNullOrUndef(context.value)) {
- label += '$' + context.value;
+ if (!isNaN(context.dataPoint.y)) {
+ label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(context.dataPoint.y);
}
return label;
}
// Label for the tooltip
label: string,
- // Value for the tooltip
- value: string,
+ // Parsed data values for the given `dataIndex` and `datasetIndex`
+ dataPoint: object,
+
+ // Formatted value for the tooltip
+ formattedValue: string,
// The dataset the item comes from
dataset: object
The context object contains the following properties:
- `chart`: the associated chart
+- `dataPoint`: the parsed data values for the given `dataIndex` and `datasetIndex`
- `dataIndex`: index of the current data
- `dataset`: dataset at index `datasetIndex`
- `datasetIndex`: index of the current dataset
#### Tooltip
-* `xLabel` and `yLabel` were removed. Please use `index` and `value`
+* `xLabel` and `yLabel` were removed. Please use `label` and `formattedValue`
* The `filter` option will now be passed additional parameters when called and should have the method signature `function(tooltipItem, index, tooltipItems, data)`
* The `custom` callback now takes a context object that has `tooltip` and `chart` properties
* All properties of tooltip model related to the tooltip options have been moved to reside within the `options` property.
* The callbacks no longer are given a `data` parameter. The tooltip item parameter contains the chart and dataset instead
-* The tooltip item's `index` parameter was renamed to `dataIndex`
+* The tooltip item's `index` parameter was renamed to `dataIndex` and `value` was renamed to `formattedValue`
## Developer migration
utils.srand(110);
function colorize(opaque, ctx) {
- var v = ctx.dataset.data[ctx.dataIndex];
+ var v = ctx.dataPoint.y;
var c = v < -50 ? '#D60000'
: v < 0 ? '#F46300'
: v < 50 ? '#0358B6'
}
function adjustRadiusBasedOnData(ctx) {
- var v = ctx.dataset.data[ctx.dataIndex];
+ var v = ctx.dataPoint.y;
return v < 10 ? 5
: v < 25 ? 7
: v < 50 ? 9
utils.srand(110);
function colorize(opaque, hover, ctx) {
- var v = ctx.dataset.data[ctx.dataIndex];
+ var v = ctx.dataPoint;
var c = v < -50 ? '#D60000'
: v < 0 ? '#F46300'
: v < 50 ? '#0358B6'
}
function adjustRadiusBasedOnData(ctx) {
- var v = ctx.dataset.data[ctx.dataIndex];
+ var v = ctx.dataPoint.y;
return v < 10 ? 5
: v < 25 ? 7
: v < 50 ? 9
var sum = 0;
tooltipItems.forEach(function(tooltipItem) {
- sum += tooltipItem.dataset.data[tooltipItem.dataIndex];
+ sum += tooltipItem.dataPoint.y;
});
return 'Sum: ' + sum;
},
// Scriptable options
const context = {
chart,
+ dataPoint: parsed,
dataIndex: index,
dataset,
datasetIndex: me.index
// Scriptable options
const context = {
chart: me.chart,
+ dataPoint: this.getParsed(index),
dataIndex: index,
dataset,
datasetIndex: me.index
return '';
},
label(context) {
- return context.chart.data.labels[context.dataIndex] + ': ' + context.value;
+ return context.chart.data.labels[context.dataIndex] + ': ' + context.formattedValue;
}
}
}
return ''; // doesn't make sense for scatter since data are formatted as a point
},
label(item) {
- return '(' + item.label + ', ' + item.value + ')';
+ return '(' + item.label + ', ' + item.formattedValue + ')';
}
}
}
_getContext(index, active) {
return {
chart: this.chart,
+ dataPoint: this.getParsed(index),
dataIndex: index,
dataset: this.getDataset(),
datasetIndex: this.index,
return {
chart,
label,
- value,
+ dataPoint: controller.getParsed(index),
+ formattedValue: value,
dataset,
dataIndex: index,
datasetIndex
if (label) {
label += ': ';
}
- const value = tooltipItem.value;
+ const value = tooltipItem.formattedValue;
if (!isNullOrUndef(value)) {
label += value;
}
datasetIndex: 0,
dataset: data.datasets[0],
label: 'Point 2',
- value: '20'
+ formattedValue: '20'
};
var label = Chart.defaults.plugins.tooltip.callbacks.label(tooltipItem);
jasmine.triggerMouseEvent(chart, 'mousemove', point);
});
+
+ it('Should provide context object to user callbacks', function(done) {
+ const chart = window.acquireChart({
+ type: 'line',
+ data: {
+ datasets: [{
+ label: 'Dataset 1',
+ data: [{x: 1, y: 10}, {x: 2, y: 20}, {x: 3, y: 30}]
+ }]
+ },
+ options: {
+ scales: {
+ x: {
+ type: 'linear'
+ }
+ },
+ tooltips: {
+ mode: 'index',
+ callbacks: {
+ beforeLabel: function(ctx) {
+ return ctx.dataPoint.x + ',' + ctx.dataPoint.y;
+ }
+ }
+ }
+ }
+ });
+
+ // Trigger an event over top of the
+ const meta = chart.getDatasetMeta(0);
+ const point = meta.data[1];
+
+ afterEvent(chart, 'mousemove', function() {
+ const tooltip = chart.tooltip;
+
+ expect(tooltip.body[0].before).toEqual(['2,20']);
+
+ done();
+ });
+ jasmine.triggerMouseEvent(chart, 'mousemove', point);
+ });
+
it('Should allow sorting items', function(done) {
var chart = window.acquireChart({
type: 'line',
expect(tooltipItem.datasetIndex).toBe(datasetIndex);
expect(typeof tooltipItem.label).toBe('string');
expect(tooltipItem.label).toBe(chart.data.labels[pointIndex]);
- expect(typeof tooltipItem.value).toBe('string');
- expect(tooltipItem.value).toBe('' + chart.data.datasets[datasetIndex].data[pointIndex]);
+ expect(typeof tooltipItem.formattedValue).toBe('string');
+ expect(tooltipItem.formattedValue).toBe('' + chart.data.datasets[datasetIndex].data[pointIndex]);
done();
});