diff --git a/docs/configuration/tooltip.md b/docs/configuration/tooltip.md index 936f9202c57..2c68ed9d773 100644 --- a/docs/configuration/tooltip.md +++ b/docs/configuration/tooltip.md @@ -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. diff --git a/src/plugins/plugin.tooltip.js b/src/plugins/plugin.tooltip.js index 231506b7363..f932cb15fbf 100644 --- a/src/plugins/plugin.tooltip.js +++ b/src/plugins/plugin.tooltip.js @@ -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); @@ -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); @@ -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)) { @@ -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; @@ -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 @@ -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: { diff --git a/test/fixtures/plugin.tooltip/box-padding.js b/test/fixtures/plugin.tooltip/box-padding.js new file mode 100644 index 00000000000..434620eddda --- /dev/null +++ b/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 + } + } +}; diff --git a/test/fixtures/plugin.tooltip/box-padding.png b/test/fixtures/plugin.tooltip/box-padding.png new file mode 100644 index 00000000000..d3cd19e202e Binary files /dev/null and b/test/fixtures/plugin.tooltip/box-padding.png differ diff --git a/types/index.esm.d.ts b/types/index.esm.d.ts index 1e3485e5364..5ea417ea318 100644 --- a/types/index.esm.d.ts +++ b/types/index.esm.d.ts @@ -2216,6 +2216,11 @@ export interface LegendOptions { * @default fontSize */ boxHeight: number; + /** + * Padding between the color box and the text + * @default 1 + */ + boxPadding: number; /** * Color of label * @see Defaults.color