mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Merge pull request #1829 from nnnick/fix/1716-1731
Better tooltip positioning
This commit is contained in:
commit
31721a353c
@ -400,6 +400,7 @@
|
||||
initToolTip: function initToolTip() {
|
||||
this.tooltip = new Chart.Tooltip({
|
||||
_chart: this.chart,
|
||||
_chartInstance: this,
|
||||
_data: this.data,
|
||||
_options: this.options,
|
||||
}, this);
|
||||
|
||||
@ -283,9 +283,15 @@
|
||||
helpers.extend(this._model, {
|
||||
x: Math.round(tooltipPosition.x),
|
||||
y: Math.round(tooltipPosition.y),
|
||||
caretPadding: tooltipPosition.padding,
|
||||
caretPadding: helpers.getValueOrDefault(tooltipPosition.padding, 2),
|
||||
labelColors: labelColors,
|
||||
});
|
||||
|
||||
// We need to determine alignment of
|
||||
var tooltipSize = this.getTooltipSize(this._model);
|
||||
this.determineAlignment(tooltipSize); // Smart Tooltip placement to stay on the canvas
|
||||
|
||||
helpers.extend(this._model, this.getBackgroundPoint(this._model, tooltipSize));
|
||||
}
|
||||
else{
|
||||
this._model.opacity = 0;
|
||||
@ -297,227 +303,282 @@
|
||||
|
||||
return this;
|
||||
},
|
||||
draw: function() {
|
||||
getTooltipSize: function getTooltipSize(vm) {
|
||||
var ctx = this._chart.ctx;
|
||||
|
||||
var size = {
|
||||
height: vm.yPadding * 2, // Tooltip Padding
|
||||
width: 0
|
||||
};
|
||||
var combinedBodyLength = vm.body.length + vm.beforeBody.length + vm.afterBody.length;
|
||||
|
||||
size.height += vm.title.length * vm.titleFontSize; // Title Lines
|
||||
size.height += (vm.title.length - 1) * vm.titleSpacing; // Title Line Spacing
|
||||
size.height += vm.title.length ? vm.titleMarginBottom : 0; // Title's bottom Margin
|
||||
size.height += combinedBodyLength * vm.bodyFontSize; // Body Lines
|
||||
size.height += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing
|
||||
size.height += vm.footer.length ? vm.footerMarginTop : 0; // Footer Margin
|
||||
size.height += vm.footer.length * (vm.footerFontSize); // Footer Lines
|
||||
size.height += vm.footer.length ? (vm.footer.length - 1) * vm.footerSpacing : 0; // Footer Line Spacing
|
||||
|
||||
// Width
|
||||
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
|
||||
helpers.each(vm.title, function(line) {
|
||||
size.width = Math.max(size.width, ctx.measureText(line).width);
|
||||
});
|
||||
|
||||
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
|
||||
helpers.each(vm.beforeBody.concat(vm.afterBody), function(line) {
|
||||
size.width = Math.max(size.width, ctx.measureText(line).width);
|
||||
}, this);
|
||||
helpers.each(vm.body, function(line) {
|
||||
size.width = Math.max(size.width, ctx.measureText(line).width + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0));
|
||||
}, this);
|
||||
|
||||
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
|
||||
helpers.each(vm.footer, function(line) {
|
||||
size.width = Math.max(size.width, ctx.measureText(line).width);
|
||||
});
|
||||
size.width += 2 * vm.xPadding;
|
||||
|
||||
return size;
|
||||
},
|
||||
determineAlignment: function determineAlignment(size) {
|
||||
this._model.xAlign = this._model.yAlign = "center";
|
||||
|
||||
if (this._model.y < size.height) {
|
||||
this._model.yAlign = 'top';
|
||||
} else if (this._model.y > (this._chart.height - size.height)) {
|
||||
this._model.yAlign = 'bottom';
|
||||
}
|
||||
|
||||
var lf, rf;
|
||||
var _this = this;
|
||||
var midX = (this._chartInstance.chartArea.left + this._chartInstance.chartArea.right) / 2;
|
||||
|
||||
if (this._model.yAlign === 'center') {
|
||||
lf = function(x) { return x <= midX; };
|
||||
rf = function(x) { return x > midX; };
|
||||
} else {
|
||||
lf = function(x) { return x <= (size.width / 2); };
|
||||
rf = function(x) { return x >= (_this._chart.width - (size.width / 2)); };
|
||||
}
|
||||
|
||||
if (lf(this._model.x)) {
|
||||
this._model.xAlign = 'left';
|
||||
} else if (rf(this._model.x)) {
|
||||
this._model.xAlign = 'right';
|
||||
}
|
||||
},
|
||||
getBackgroundPoint: function getBackgroundPoint(vm, size) {
|
||||
// Background Position
|
||||
var pt = {
|
||||
x: vm.x,
|
||||
y: vm.y
|
||||
};
|
||||
|
||||
if (vm.xAlign === 'right') {
|
||||
pt.x -= size.width;
|
||||
} else if (vm.xAlign === 'center') {
|
||||
pt.x -= (size.width / 2);
|
||||
}
|
||||
|
||||
if (vm.yAlign === 'top') {
|
||||
pt.y += vm.caretPadding + vm.caretSize;
|
||||
} else if (vm.yAlign === 'bottom') {
|
||||
pt.y -= size.height + vm.caretPadding + vm.caretSize;
|
||||
} else {
|
||||
pt.y -= (size.height / 2);
|
||||
}
|
||||
|
||||
if (vm.yAlign == 'center') {
|
||||
if (vm.xAlign === 'left') {
|
||||
pt.x += vm.caretPadding + vm.caretSize;
|
||||
} else if (vm.xAlign === 'right') {
|
||||
pt.x -= vm.caretPadding + vm.caretSize;
|
||||
}
|
||||
} else {
|
||||
if (vm.xAlign === 'left') {
|
||||
pt.x -= vm.cornerRadius + vm.caretPadding;
|
||||
} else if (vm.xAlign === 'right') {
|
||||
pt.x += vm.cornerRadius + vm.caretPadding;
|
||||
}
|
||||
}
|
||||
|
||||
return pt;
|
||||
},
|
||||
drawCaret: function drawCaret(tooltipPoint, size, opacity, caretPadding) {
|
||||
var vm = this._view;
|
||||
var ctx = this._chart.ctx;
|
||||
var x1, x2, x3;
|
||||
var y1, y2, y3;
|
||||
|
||||
if (vm.yAlign === 'center') {
|
||||
// Left or right side
|
||||
if (vm.xAlign === 'left') {
|
||||
x1 = tooltipPoint.x;
|
||||
x2 = x1 - vm.caretSize;
|
||||
x3 = x1;
|
||||
} else {
|
||||
x1 = tooltipPoint.x + size.width;
|
||||
x2 = x1 + vm.caretSize;
|
||||
x3 = x1;
|
||||
}
|
||||
|
||||
y2 = tooltipPoint.y + (size.height / 2);
|
||||
y1 = y2 - vm.caretSize;
|
||||
y3 = y2 + vm.caretSize;
|
||||
} else {
|
||||
if (vm.xAlign === 'left') {
|
||||
x1 = tooltipPoint.x + vm.cornerRadius;
|
||||
x2 = x1 + vm.caretSize;
|
||||
x3 = x2 + vm.caretSize;
|
||||
} else if (vm.xAlign === 'right') {
|
||||
x1 = tooltipPoint.x + size.width - vm.cornerRadius;
|
||||
x2 = x1 - vm.caretSize;
|
||||
x3 = x2 - vm.caretSize;
|
||||
} else {
|
||||
x2 = tooltipPoint.x + (size.width / 2);
|
||||
x1 = x2 - vm.caretSize;
|
||||
x3 = x2 + vm.caretSize;
|
||||
}
|
||||
|
||||
if (vm.yAlign === 'top') {
|
||||
y1 = tooltipPoint.y;
|
||||
y2 = y1 - vm.caretSize;
|
||||
y3 = y1;
|
||||
} else {
|
||||
y1 = tooltipPoint.y + size.height;
|
||||
y2 = y1 + vm.caretSize;
|
||||
y3 = y1;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.fillStyle = helpers.color(vm.backgroundColor).alpha(opacity).rgbString();
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x1, y1);
|
||||
ctx.lineTo(x2, y2);
|
||||
ctx.lineTo(x3, y3);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
},
|
||||
drawTitle: function drawTitle(pt, vm, ctx, opacity) {
|
||||
if (vm.title.length) {
|
||||
ctx.textAlign = vm._titleAlign;
|
||||
ctx.textBaseline = "top";
|
||||
ctx.fillStyle = helpers.color(vm.titleColor).alpha(opacity).rgbString();
|
||||
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
|
||||
|
||||
helpers.each(vm.title, function(title, i) {
|
||||
ctx.fillText(title, pt.x, pt.y);
|
||||
pt.y += vm.titleFontSize + vm.titleSpacing; // Line Height and spacing
|
||||
|
||||
if (i + 1 === vm.title.length) {
|
||||
pt.y += vm.titleMarginBottom - vm.titleSpacing; // If Last, add margin, remove spacing
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
drawBody: function drawBody(pt, vm, ctx, opacity) {
|
||||
ctx.textAlign = vm._bodyAlign;
|
||||
ctx.textBaseline = "top";
|
||||
ctx.fillStyle = helpers.color(vm.bodyColor).alpha(opacity).rgbString();
|
||||
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
|
||||
|
||||
// Before Body
|
||||
helpers.each(vm.beforeBody, function(beforeBody) {
|
||||
ctx.fillText(beforeBody, pt.x, pt.y);
|
||||
pt.y += vm.bodyFontSize + vm.bodySpacing;
|
||||
});
|
||||
|
||||
helpers.each(vm.body, function(body, i) {
|
||||
// Draw Legend-like boxes if needed
|
||||
if (this._options.tooltips.mode !== 'single') {
|
||||
// Fill a white rect so that colours merge nicely if the opacity is < 1
|
||||
ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();
|
||||
ctx.fillRect(pt.x, pt.y, vm.bodyFontSize, vm.bodyFontSize);
|
||||
|
||||
// Border
|
||||
ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();
|
||||
ctx.strokeRect(pt.x, pt.y, vm.bodyFontSize, vm.bodyFontSize);
|
||||
|
||||
// Inner square
|
||||
ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();
|
||||
ctx.fillRect(pt.x + 1, pt.y + 1, vm.bodyFontSize - 2, vm.bodyFontSize - 2);
|
||||
|
||||
ctx.fillStyle = helpers.color(vm.bodyColor).alpha(opacity).rgbaString(); // Return fill style for text
|
||||
}
|
||||
|
||||
// Body Line
|
||||
ctx.fillText(body, pt.x + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0), pt.y);
|
||||
|
||||
pt.y += vm.bodyFontSize + vm.bodySpacing;
|
||||
}, this);
|
||||
|
||||
// After Body
|
||||
helpers.each(vm.afterBody, function(afterBody) {
|
||||
ctx.fillText(afterBody, pt.x, pt.y);
|
||||
pt.y += vm.bodyFontSize;
|
||||
});
|
||||
|
||||
pt.y -= vm.bodySpacing; // Remove last body spacing
|
||||
},
|
||||
drawFooter: function drawFooter(pt, vm, ctx, opacity) {
|
||||
if (vm.footer.length) {
|
||||
pt.y += vm.footerMarginTop;
|
||||
|
||||
ctx.textAlign = vm._footerAlign;
|
||||
ctx.textBaseline = "top";
|
||||
ctx.fillStyle = helpers.color(vm.footerColor).alpha(opacity).rgbString();
|
||||
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
|
||||
|
||||
helpers.each(vm.footer, function(footer) {
|
||||
ctx.fillText(footer, pt.x, pt.y);
|
||||
pt.y += vm.footerFontSize + vm.footerSpacing;
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
draw: function draw() {
|
||||
var ctx = this._chart.ctx;
|
||||
var vm = this._view;
|
||||
|
||||
if (this._view.opacity === 0) {
|
||||
if (vm.opacity === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get Dimensions
|
||||
|
||||
vm.position = "top";
|
||||
|
||||
var caretPadding = vm.caretPadding || 2;
|
||||
|
||||
var combinedBodyLength = vm.body.length + vm.beforeBody.length + vm.afterBody.length;
|
||||
|
||||
// Height
|
||||
var tooltipHeight = vm.yPadding * 2; // Tooltip Padding
|
||||
|
||||
tooltipHeight += vm.title.length * vm.titleFontSize; // Title Lines
|
||||
tooltipHeight += (vm.title.length - 1) * vm.titleSpacing; // Title Line Spacing
|
||||
tooltipHeight += vm.title.length ? vm.titleMarginBottom : 0; // Title's bottom Margin
|
||||
|
||||
tooltipHeight += combinedBodyLength * vm.bodyFontSize; // Body Lines
|
||||
tooltipHeight += combinedBodyLength ? (combinedBodyLength - 1) * vm.bodySpacing : 0; // Body Line Spacing
|
||||
|
||||
tooltipHeight += vm.footer.length ? vm.footerMarginTop : 0; // Footer Margin
|
||||
tooltipHeight += vm.footer.length * (vm.footerFontSize); // Footer Lines
|
||||
tooltipHeight += vm.footer.length ? (vm.footer.length - 1) * vm.footerSpacing : 0; // Footer Line Spacing
|
||||
|
||||
// Width
|
||||
var tooltipWidth = 0;
|
||||
helpers.each(vm.title, function(line) {
|
||||
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
|
||||
tooltipWidth = Math.max(tooltipWidth, ctx.measureText(line).width);
|
||||
});
|
||||
helpers.each(vm.beforeBody, function(line) {
|
||||
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
|
||||
tooltipWidth = Math.max(tooltipWidth, ctx.measureText(line).width);
|
||||
}, this);
|
||||
helpers.each(vm.body, function(line) {
|
||||
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
|
||||
tooltipWidth = Math.max(tooltipWidth, ctx.measureText(line).width + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0));
|
||||
}, this);
|
||||
helpers.each(vm.afterBody, function(line) {
|
||||
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
|
||||
tooltipWidth = Math.max(tooltipWidth, ctx.measureText(line).width);
|
||||
}, this);
|
||||
helpers.each(vm.footer, function(line) {
|
||||
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
|
||||
tooltipWidth = Math.max(tooltipWidth, ctx.measureText(line).width);
|
||||
});
|
||||
tooltipWidth += 2 * vm.xPadding;
|
||||
var tooltipTotalWidth = tooltipWidth + vm.caretSize + caretPadding;
|
||||
|
||||
|
||||
|
||||
// Smart Tooltip placement to stay on the canvas
|
||||
// Top, center, or bottom
|
||||
vm.yAlign = "center";
|
||||
if (vm.y - (tooltipHeight / 2) < 0) {
|
||||
vm.yAlign = "top";
|
||||
} else if (vm.y + (tooltipHeight / 2) > this._chart.height) {
|
||||
vm.yAlign = "bottom";
|
||||
}
|
||||
|
||||
|
||||
// Left or Right
|
||||
vm.xAlign = "right";
|
||||
if (vm.x + tooltipTotalWidth > this._chart.width) {
|
||||
vm.xAlign = "left";
|
||||
}
|
||||
|
||||
|
||||
// Background Position
|
||||
var tooltipX = vm.x,
|
||||
tooltipY = vm.y;
|
||||
|
||||
if (vm.yAlign === 'top') {
|
||||
tooltipY = vm.y - vm.caretSize - vm.cornerRadius;
|
||||
} else if (vm.yAlign === 'bottom') {
|
||||
tooltipY = vm.y - tooltipHeight + vm.caretSize + vm.cornerRadius;
|
||||
} else {
|
||||
tooltipY = vm.y - (tooltipHeight / 2);
|
||||
}
|
||||
|
||||
if (vm.xAlign === 'left') {
|
||||
tooltipX = vm.x - tooltipTotalWidth;
|
||||
} else if (vm.xAlign === 'right') {
|
||||
tooltipX = vm.x + caretPadding + vm.caretSize;
|
||||
} else {
|
||||
tooltipX = vm.x + (tooltipTotalWidth / 2);
|
||||
}
|
||||
|
||||
// Draw Background
|
||||
var caretPadding = vm.caretPadding;
|
||||
var tooltipSize = this.getTooltipSize(vm);
|
||||
var pt = {
|
||||
x: vm.x,
|
||||
y: vm.y
|
||||
};
|
||||
|
||||
// IE11/Edge does not like very small opacities, so snap to 0
|
||||
var opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;
|
||||
|
||||
if (this._options.tooltips.enabled) {
|
||||
// Draw Background
|
||||
ctx.fillStyle = helpers.color(vm.backgroundColor).alpha(opacity).rgbString();
|
||||
helpers.drawRoundedRectangle(ctx, tooltipX, tooltipY, tooltipWidth, tooltipHeight, vm.cornerRadius);
|
||||
helpers.drawRoundedRectangle(ctx, pt.x, pt.y, tooltipSize.width, tooltipSize.height, vm.cornerRadius);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
|
||||
// Draw Caret
|
||||
if (this._options.tooltips.enabled) {
|
||||
ctx.fillStyle = helpers.color(vm.backgroundColor).alpha(opacity).rgbString();
|
||||
|
||||
if (vm.xAlign === 'left') {
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vm.x - caretPadding, vm.y);
|
||||
ctx.lineTo(vm.x - caretPadding - vm.caretSize, vm.y - vm.caretSize);
|
||||
ctx.lineTo(vm.x - caretPadding - vm.caretSize, vm.y + vm.caretSize);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
} else {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(vm.x + caretPadding, vm.y);
|
||||
ctx.lineTo(vm.x + caretPadding + vm.caretSize, vm.y - vm.caretSize);
|
||||
ctx.lineTo(vm.x + caretPadding + vm.caretSize, vm.y + vm.caretSize);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Title, Body, and Footer
|
||||
|
||||
if (this._options.tooltips.enabled) {
|
||||
|
||||
var yBase = tooltipY + vm.yPadding;
|
||||
var xBase = tooltipX + vm.xPadding;
|
||||
// Draw Caret
|
||||
this.drawCaret(pt, tooltipSize, opacity, caretPadding);
|
||||
|
||||
// Draw Title, Body, and Footer
|
||||
pt.x += vm.xPadding;
|
||||
pt.y += vm.yPadding;
|
||||
|
||||
// Titles
|
||||
|
||||
if (vm.title.length) {
|
||||
ctx.textAlign = vm._titleAlign;
|
||||
ctx.textBaseline = "top";
|
||||
ctx.fillStyle = helpers.color(vm.titleColor).alpha(opacity).rgbString();
|
||||
ctx.font = helpers.fontString(vm.titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
|
||||
|
||||
helpers.each(vm.title, function(title, i) {
|
||||
ctx.fillText(title, xBase, yBase);
|
||||
yBase += vm.titleFontSize + vm.titleSpacing; // Line Height and spacing
|
||||
if (i + 1 === vm.title.length) {
|
||||
yBase += vm.titleMarginBottom - vm.titleSpacing; // If Last, add margin, remove spacing
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
this.drawTitle(pt, vm, ctx, opacity);
|
||||
|
||||
// Body
|
||||
ctx.textAlign = vm._bodyAlign;
|
||||
ctx.textBaseline = "top";
|
||||
ctx.fillStyle = helpers.color(vm.bodyColor).alpha(opacity).rgbString();
|
||||
ctx.font = helpers.fontString(vm.bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);
|
||||
|
||||
// Before Body
|
||||
helpers.each(vm.beforeBody, function(beforeBody) {
|
||||
ctx.fillText(beforeBody, xBase, yBase);
|
||||
yBase += vm.bodyFontSize + vm.bodySpacing;
|
||||
});
|
||||
|
||||
helpers.each(vm.body, function(body, i) {
|
||||
|
||||
|
||||
// Draw Legend-like boxes if needed
|
||||
if (this._options.tooltips.mode !== 'single') {
|
||||
// Fill a white rect so that colours merge nicely if the opacity is < 1
|
||||
ctx.fillStyle = helpers.color(vm.legendColorBackground).alpha(opacity).rgbaString();
|
||||
ctx.fillRect(xBase, yBase, vm.bodyFontSize, vm.bodyFontSize);
|
||||
|
||||
// Border
|
||||
ctx.strokeStyle = helpers.color(vm.labelColors[i].borderColor).alpha(opacity).rgbaString();
|
||||
ctx.strokeRect(xBase, yBase, vm.bodyFontSize, vm.bodyFontSize);
|
||||
|
||||
// Inner square
|
||||
ctx.fillStyle = helpers.color(vm.labelColors[i].backgroundColor).alpha(opacity).rgbaString();
|
||||
ctx.fillRect(xBase + 1, yBase + 1, vm.bodyFontSize - 2, vm.bodyFontSize - 2);
|
||||
|
||||
ctx.fillStyle = helpers.color(vm.bodyColor).alpha(opacity).rgbaString(); // Return fill style for text
|
||||
}
|
||||
|
||||
// Body Line
|
||||
ctx.fillText(body, xBase + (this._options.tooltips.mode !== 'single' ? (vm.bodyFontSize + 2) : 0), yBase);
|
||||
|
||||
yBase += vm.bodyFontSize + vm.bodySpacing;
|
||||
|
||||
}, this);
|
||||
|
||||
// After Body
|
||||
helpers.each(vm.afterBody, function(afterBody) {
|
||||
ctx.fillText(afterBody, xBase, yBase);
|
||||
yBase += vm.bodyFontSize;
|
||||
});
|
||||
|
||||
yBase -= vm.bodySpacing; // Remove last body spacing
|
||||
|
||||
this.drawBody(pt, vm, ctx, opacity);
|
||||
|
||||
// Footer
|
||||
if (vm.footer.length) {
|
||||
|
||||
yBase += vm.footerMarginTop;
|
||||
|
||||
ctx.textAlign = vm._footerAlign;
|
||||
ctx.textBaseline = "top";
|
||||
ctx.fillStyle = helpers.color(vm.footerColor).alpha(opacity).rgbString();
|
||||
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
|
||||
|
||||
helpers.each(vm.footer, function(footer) {
|
||||
ctx.fillText(footer, xBase, yBase);
|
||||
yBase += vm.footerFontSize + vm.footerSpacing;
|
||||
}, this);
|
||||
}
|
||||
|
||||
this.drawFooter(pt, vm, ctx, opacity);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
|
||||
@ -78,17 +78,10 @@
|
||||
},
|
||||
tooltipPosition: function() {
|
||||
var vm = this._view;
|
||||
if (vm.y < vm.base) {
|
||||
return {
|
||||
x: vm.x,
|
||||
y: vm.y
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
x: vm.x,
|
||||
y: vm.base
|
||||
};
|
||||
}
|
||||
return {
|
||||
x: vm.x,
|
||||
y: vm.y
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ describe('Rectangle element tests', function() {
|
||||
|
||||
expect(rectangle.tooltipPosition()).toEqual({
|
||||
x: 10,
|
||||
y: 0,
|
||||
y: 15,
|
||||
});
|
||||
|
||||
// Test when the y is below the base (negative bar)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user