Skip to content

Commit

Permalink
Configurable tooltip box padding (#9625)
Browse files Browse the repository at this point in the history
  • Loading branch information
etimberg committed Sep 6, 2021
1 parent 3f23aab commit f5c9a65
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/configuration/tooltip.md
Expand Up @@ -37,6 +37,7 @@ Namespace: `options.plugins.tooltip`, the global options for the chart tooltips
| `displayColors` | `boolean` | `true` | If true, color boxes are shown in the tooltip.
| `boxWidth` | `number` | `bodyFont.size` | Width of the color box if displayColors is true.
| `boxHeight` | `number` | `bodyFont.size` | Height of the color box if displayColors is true.
| `boxPadding` | `number` | `1` | Padding between the color box and the text.
| `usePointStyle` | `boolean` | `false` | Use the corresponding point style (from dataset options) instead of color boxes, ex: star, triangle etc. (size is based on the minimum value between boxWidth and boxHeight).
| `borderColor` | [`Color`](../general/colors.md) | `'rgba(0, 0, 0, 0)'` | Color of the border.
| `borderWidth` | `number` | `0` | Size of the border.
Expand Down
13 changes: 7 additions & 6 deletions src/plugins/plugin.tooltip.js
Expand Up @@ -187,7 +187,7 @@ function getTooltipSize(tooltip, options) {
each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth);

// Body lines may include some extra width due to the color box
widthPadding = options.displayColors ? (boxWidth + 2) : 0;
widthPadding = options.displayColors ? (boxWidth + 2 + options.boxPadding) : 0;
each(body, (bodyItem) => {
each(bodyItem.before, maxLineWidth);
each(bodyItem.lines, maxLineWidth);
Expand Down Expand Up @@ -681,7 +681,7 @@ export class Tooltip extends Element {
const me = this;
const labelColors = me.labelColors[i];
const labelPointStyle = me.labelPointStyles[i];
const {boxHeight, boxWidth} = options;
const {boxHeight, boxWidth, boxPadding} = options;
const bodyFont = toFont(options.bodyFont);
const colorX = getAlignedX(me, 'left', options);
const rtlColorX = rtlHelper.x(colorX);
Expand Down Expand Up @@ -717,8 +717,8 @@ export class Tooltip extends Element {
ctx.lineDashOffset = labelColors.borderDashOffset || 0;

// Fill a white rect so that colours merge nicely if the opacity is < 1
const outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth);
const innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - 2);
const outerX = rtlHelper.leftForLtr(rtlColorX, boxWidth - boxPadding);
const innerX = rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - boxPadding - 2);
const borderRadius = toTRBLCorners(labelColors.borderRadius);

if (Object.values(borderRadius).some(v => v !== 0)) {
Expand Down Expand Up @@ -763,7 +763,7 @@ export class Tooltip extends Element {
drawBody(pt, ctx, options) {
const me = this;
const {body} = me;
const {bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth} = options;
const {bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth, boxPadding} = options;
const bodyFont = toFont(options.bodyFont);
let bodyLineHeight = bodyFont.lineHeight;
let xLinePadding = 0;
Expand All @@ -789,7 +789,7 @@ export class Tooltip extends Element {
each(me.beforeBody, fillLineOfText);

xLinePadding = displayColors && bodyAlignForCalculation !== 'right'
? bodyAlign === 'center' ? (boxWidth / 2 + 1) : (boxWidth + 2)
? bodyAlign === 'center' ? (boxWidth / 2 + boxPadding) : (boxWidth + 2 + boxPadding)
: 0;

// Draw body lines now
Expand Down Expand Up @@ -1166,6 +1166,7 @@ export default {
boxWidth: (ctx, opts) => opts.bodyFont.size,
multiKeyBackground: '#fff',
displayColors: true,
boxPadding: 0,
borderColor: 'rgba(0,0,0,0)',
borderWidth: 0,
animation: {
Expand Down
71 changes: 71 additions & 0 deletions test/fixtures/plugin.tooltip/box-padding.js
@@ -0,0 +1,71 @@
const data = [];
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
data.push({x, y});
}
}

module.exports = {
config: {
type: 'scatter',
data: {
datasets: [{
data,
backgroundColor: 'red',
radius: 1,
hoverRadius: 0
}],
},
options: {
scales: {
x: {display: false},
y: {display: false}
},
plugins: {
legend: false,
title: false,
filler: false,
tooltip: {
mode: 'point',
intersect: true,
// spriteText: use white background to hide any gaps between fonts
backgroundColor: 'white',
borderColor: 'black',
borderWidth: 1,
callbacks: {
label: () => 'label',
},
boxPadding: 30
},
},
},
plugins: [{
afterDraw: function(chart) {
const canvas = chart.canvas;
const rect = canvas.getBoundingClientRect();
const meta = chart.getDatasetMeta(0);
let point, event;

for (let i = 0; i < data.length; i++) {
point = meta.data[i];
event = {
type: 'mousemove',
target: canvas,
clientX: rect.left + point.x,
clientY: rect.top + point.y
};
chart._handleEvent(event);
chart.tooltip.handleEvent(event);
chart.tooltip.draw(chart.ctx);
}
}
}]
},
options: {
spriteText: true,
canvas: {
height: 400,
width: 500
}
}
};
Binary file added test/fixtures/plugin.tooltip/box-padding.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions types/index.esm.d.ts
Expand Up @@ -2216,6 +2216,11 @@ export interface LegendOptions<TType extends ChartType> {
* @default fontSize
*/
boxHeight: number;
/**
* Padding between the color box and the text
* @default 1
*/
boxPadding: number;
/**
* Color of label
* @see Defaults.color
Expand Down

0 comments on commit f5c9a65

Please sign in to comment.