Skip to content

Commit e1796d3

Browse files
authored
expose boxWidth and boxHeight on tooltip (#6995)
1 parent 5320545 commit e1796d3

File tree

2 files changed

+27
-11
lines changed

2 files changed

+27
-11
lines changed

docs/configuration/tooltip.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ The tooltip configuration is passed into the `options.tooltips` namespace. The g
4242
| `cornerRadius` | `number` | `6` | Radius of tooltip corner curves.
4343
| `multiKeyBackground` | `Color` | `'#fff'` | Color to draw behind the colored boxes when multiple items are in the tooltip.
4444
| `displayColors` | `boolean` | `true` | If true, color boxes are shown in the tooltip.
45+
| `boxWidth` | `number` | `bodyFontSize` | Width of the color box if displayColors is true.
46+
| `boxHeight` | `number` | `bodyFontSize` | Height of the color box if displayColors is true.
4547
| `borderColor` | `Color` | `'rgba(0, 0, 0, 0)'` | Color of the border.
4648
| `borderWidth` | `number` | `0` | Size of the border.
4749
| `rtl` | `boolean` | | `true` for rendering the legends from right to left.

src/plugins/plugin.tooltip.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,9 @@ function resolveOptions(options) {
242242
options.bodyFontStyle = valueOrDefault(options.bodyFontStyle, defaults.fontStyle);
243243
options.bodyFontSize = valueOrDefault(options.bodyFontSize, defaults.fontSize);
244244

245+
options.boxHeight = valueOrDefault(options.boxHeight, options.bodyFontSize);
246+
options.boxWidth = valueOrDefault(options.boxWidth, options.bodyFontSize);
247+
245248
options.titleFontFamily = valueOrDefault(options.titleFontFamily, defaults.fontFamily);
246249
options.titleFontStyle = valueOrDefault(options.titleFontStyle, defaults.fontStyle);
247250
options.titleFontSize = valueOrDefault(options.titleFontSize, defaults.fontSize);
@@ -259,9 +262,10 @@ function resolveOptions(options) {
259262
function getTooltipSize(tooltip) {
260263
const ctx = tooltip._chart.ctx;
261264
const {body, footer, options, title} = tooltip;
262-
const {bodyFontSize, footerFontSize, titleFontSize} = options;
265+
const {bodyFontSize, footerFontSize, titleFontSize, boxWidth, boxHeight} = options;
263266
const titleLineCount = title.length;
264267
const footerLineCount = footer.length;
268+
const bodyLineItemCount = body.length;
265269

266270
let height = options.yPadding * 2; // Tooltip Padding
267271
let width = 0;
@@ -276,7 +280,10 @@ function getTooltipSize(tooltip) {
276280
+ options.titleMarginBottom;
277281
}
278282
if (combinedBodyLength) {
279-
height += combinedBodyLength * bodyFontSize
283+
// Body lines may include some extra height depending on boxHeight
284+
const bodyLineHeight = options.displayColors ? Math.max(boxHeight, bodyFontSize) : bodyFontSize;
285+
height += bodyLineItemCount * bodyLineHeight
286+
+ (combinedBodyLength - bodyLineItemCount) * bodyFontSize
280287
+ (combinedBodyLength - 1) * options.bodySpacing;
281288
}
282289
if (footerLineCount) {
@@ -301,7 +308,7 @@ function getTooltipSize(tooltip) {
301308
helpers.each(tooltip.beforeBody.concat(tooltip.afterBody), maxLineWidth);
302309

303310
// Body lines may include some extra width due to the color box
304-
widthPadding = options.displayColors ? (bodyFontSize + 2) : 0;
311+
widthPadding = options.displayColors ? (boxWidth + 2) : 0;
305312
helpers.each(body, (bodyItem) => {
306313
helpers.each(bodyItem.before, maxLineWidth);
307314
helpers.each(bodyItem.lines, maxLineWidth);
@@ -757,22 +764,24 @@ export class Tooltip extends Element {
757764
const me = this;
758765
const options = me.options;
759766
const labelColors = me.labelColors[i];
760-
const bodyFontSize = options.bodyFontSize;
767+
const {boxHeight, boxWidth, bodyFontSize} = options;
761768
const colorX = getAlignedX(me, 'left');
762769
const rtlColorX = rtlHelper.x(colorX);
770+
const yOffSet = boxHeight < bodyFontSize ? (bodyFontSize - boxHeight) / 2 : 0;
771+
const colorY = pt.y + yOffSet;
763772

764773
// Fill a white rect so that colours merge nicely if the opacity is < 1
765774
ctx.fillStyle = options.multiKeyBackground;
766-
ctx.fillRect(rtlHelper.leftForLtr(rtlColorX, bodyFontSize), pt.y, bodyFontSize, bodyFontSize);
775+
ctx.fillRect(rtlHelper.leftForLtr(rtlColorX, boxWidth), colorY, boxWidth, boxHeight);
767776

768777
// Border
769778
ctx.lineWidth = 1;
770779
ctx.strokeStyle = labelColors.borderColor;
771-
ctx.strokeRect(rtlHelper.leftForLtr(rtlColorX, bodyFontSize), pt.y, bodyFontSize, bodyFontSize);
780+
ctx.strokeRect(rtlHelper.leftForLtr(rtlColorX, boxWidth), colorY, boxWidth, boxHeight);
772781

773782
// Inner square
774783
ctx.fillStyle = labelColors.backgroundColor;
775-
ctx.fillRect(rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), bodyFontSize - 2), pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
784+
ctx.fillRect(rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), boxWidth - 2), colorY + 1, boxWidth - 2, boxHeight - 2);
776785

777786
// restore fillStyle
778787
ctx.fillStyle = me.labelTextColors[i];
@@ -781,14 +790,15 @@ export class Tooltip extends Element {
781790
drawBody(pt, ctx) {
782791
const me = this;
783792
const {body, options} = me;
784-
const {bodyFontSize, bodySpacing, bodyAlign, displayColors} = options;
793+
const {bodyFontSize, bodySpacing, bodyAlign, displayColors, boxHeight, boxWidth} = options;
794+
let bodyLineHeight = bodyFontSize;
785795
let xLinePadding = 0;
786796

787797
const rtlHelper = getRtlHelper(options.rtl, me.x, me.width);
788798

789799
const fillLineOfText = function(line) {
790-
ctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyFontSize / 2);
791-
pt.y += bodyFontSize + bodySpacing;
800+
ctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyLineHeight / 2);
801+
pt.y += bodyLineHeight + bodySpacing;
792802
};
793803

794804
const bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign);
@@ -805,7 +815,7 @@ export class Tooltip extends Element {
805815
helpers.each(me.beforeBody, fillLineOfText);
806816

807817
xLinePadding = displayColors && bodyAlignForCalculation !== 'right'
808-
? bodyAlign === 'center' ? (bodyFontSize / 2 + 1) : (bodyFontSize + 2)
818+
? bodyAlign === 'center' ? (boxWidth / 2 + 1) : (boxWidth + 2)
809819
: 0;
810820

811821
// Draw body lines now
@@ -820,17 +830,21 @@ export class Tooltip extends Element {
820830
// Draw Legend-like boxes if needed
821831
if (displayColors && lines.length) {
822832
me._drawColorBox(ctx, pt, i, rtlHelper);
833+
bodyLineHeight = Math.max(bodyFontSize, boxHeight);
823834
}
824835

825836
for (j = 0, jlen = lines.length; j < jlen; ++j) {
826837
fillLineOfText(lines[j]);
838+
// Reset for any lines that don't include colorbox
839+
bodyLineHeight = bodyFontSize;
827840
}
828841

829842
helpers.each(bodyItem.after, fillLineOfText);
830843
}
831844

832845
// Reset back to 0 for after body
833846
xLinePadding = 0;
847+
bodyLineHeight = bodyFontSize;
834848

835849
// After body lines
836850
helpers.each(me.afterBody, fillLineOfText);

0 commit comments

Comments
 (0)