mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Add support for CanvasPattern and CanvasGradient in tooltip (#5869)
This commit is contained in:
parent
aa652df240
commit
ecfa7b24c6
@ -168,14 +168,6 @@ var positioners = {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper method to merge the opacity into a color
|
||||
*/
|
||||
function mergeOpacity(colorString, opacity) {
|
||||
var color = helpers.color(colorString);
|
||||
return color.alpha(opacity * color.alpha()).rgbaString();
|
||||
}
|
||||
|
||||
// Helper to push or concat based on if the 2nd parameter is an array or not
|
||||
function pushOrConcat(base, toPush) {
|
||||
if (toPush) {
|
||||
@ -734,7 +726,7 @@ var exports = module.exports = Element.extend({
|
||||
return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};
|
||||
},
|
||||
|
||||
drawTitle: function(pt, vm, ctx, opacity) {
|
||||
drawTitle: function(pt, vm, ctx) {
|
||||
var title = vm.title;
|
||||
|
||||
if (title.length) {
|
||||
@ -744,7 +736,7 @@ var exports = module.exports = Element.extend({
|
||||
var titleFontSize = vm.titleFontSize;
|
||||
var titleSpacing = vm.titleSpacing;
|
||||
|
||||
ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
|
||||
ctx.fillStyle = vm.titleFontColor;
|
||||
ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
|
||||
|
||||
var i, len;
|
||||
@ -759,7 +751,7 @@ var exports = module.exports = Element.extend({
|
||||
}
|
||||
},
|
||||
|
||||
drawBody: function(pt, vm, ctx, opacity) {
|
||||
drawBody: function(pt, vm, ctx) {
|
||||
var bodyFontSize = vm.bodyFontSize;
|
||||
var bodySpacing = vm.bodySpacing;
|
||||
var body = vm.body;
|
||||
@ -776,7 +768,7 @@ var exports = module.exports = Element.extend({
|
||||
};
|
||||
|
||||
// Before body lines
|
||||
ctx.fillStyle = mergeOpacity(vm.bodyFontColor, opacity);
|
||||
ctx.fillStyle = vm.bodyFontColor;
|
||||
helpers.each(vm.beforeBody, fillLineOfText);
|
||||
|
||||
var drawColorBoxes = vm.displayColors;
|
||||
@ -784,7 +776,7 @@ var exports = module.exports = Element.extend({
|
||||
|
||||
// Draw body lines now
|
||||
helpers.each(body, function(bodyItem, i) {
|
||||
var textColor = mergeOpacity(vm.labelTextColors[i], opacity);
|
||||
var textColor = vm.labelTextColors[i];
|
||||
ctx.fillStyle = textColor;
|
||||
helpers.each(bodyItem.before, fillLineOfText);
|
||||
|
||||
@ -792,16 +784,16 @@ var exports = module.exports = Element.extend({
|
||||
// Draw Legend-like boxes if needed
|
||||
if (drawColorBoxes) {
|
||||
// Fill a white rect so that colours merge nicely if the opacity is < 1
|
||||
ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);
|
||||
ctx.fillStyle = vm.legendColorBackground;
|
||||
ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
|
||||
|
||||
// Border
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
|
||||
ctx.strokeStyle = vm.labelColors[i].borderColor;
|
||||
ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
|
||||
|
||||
// Inner square
|
||||
ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
|
||||
ctx.fillStyle = vm.labelColors[i].backgroundColor;
|
||||
ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
|
||||
ctx.fillStyle = textColor;
|
||||
}
|
||||
@ -820,7 +812,7 @@ var exports = module.exports = Element.extend({
|
||||
pt.y -= bodySpacing; // Remove last body spacing
|
||||
},
|
||||
|
||||
drawFooter: function(pt, vm, ctx, opacity) {
|
||||
drawFooter: function(pt, vm, ctx) {
|
||||
var footer = vm.footer;
|
||||
|
||||
if (footer.length) {
|
||||
@ -829,7 +821,7 @@ var exports = module.exports = Element.extend({
|
||||
ctx.textAlign = vm._footerAlign;
|
||||
ctx.textBaseline = 'top';
|
||||
|
||||
ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
|
||||
ctx.fillStyle = vm.footerFontColor;
|
||||
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
|
||||
|
||||
helpers.each(footer, function(line) {
|
||||
@ -839,9 +831,9 @@ var exports = module.exports = Element.extend({
|
||||
}
|
||||
},
|
||||
|
||||
drawBackground: function(pt, vm, ctx, tooltipSize, opacity) {
|
||||
ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
|
||||
ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);
|
||||
drawBackground: function(pt, vm, ctx, tooltipSize) {
|
||||
ctx.fillStyle = vm.backgroundColor;
|
||||
ctx.strokeStyle = vm.borderColor;
|
||||
ctx.lineWidth = vm.borderWidth;
|
||||
var xAlign = vm.xAlign;
|
||||
var yAlign = vm.yAlign;
|
||||
@ -906,21 +898,26 @@ var exports = module.exports = Element.extend({
|
||||
var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;
|
||||
|
||||
if (this._options.enabled && hasTooltipContent) {
|
||||
ctx.save();
|
||||
ctx.globalAlpha = opacity;
|
||||
|
||||
// Draw Background
|
||||
this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
|
||||
this.drawBackground(pt, vm, ctx, tooltipSize);
|
||||
|
||||
// Draw Title, Body, and Footer
|
||||
pt.x += vm.xPadding;
|
||||
pt.y += vm.yPadding;
|
||||
|
||||
// Titles
|
||||
this.drawTitle(pt, vm, ctx, opacity);
|
||||
this.drawTitle(pt, vm, ctx);
|
||||
|
||||
// Body
|
||||
this.drawBody(pt, vm, ctx, opacity);
|
||||
this.drawBody(pt, vm, ctx);
|
||||
|
||||
// Footer
|
||||
this.drawFooter(pt, vm, ctx, opacity);
|
||||
this.drawFooter(pt, vm, ctx);
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
104
test/fixtures/core.tooltip/opacity.js
vendored
Normal file
104
test/fixtures/core.tooltip/opacity.js
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
var patternCanvas = document.createElement('canvas');
|
||||
var patternContext = patternCanvas.getContext('2d');
|
||||
|
||||
patternCanvas.width = 6;
|
||||
patternCanvas.height = 6;
|
||||
patternContext.fillStyle = '#ff0000';
|
||||
patternContext.fillRect(0, 0, 6, 6);
|
||||
patternContext.fillStyle = '#ffff00';
|
||||
patternContext.fillRect(0, 0, 4, 4);
|
||||
|
||||
var pattern = patternContext.createPattern(patternCanvas, 'repeat');
|
||||
|
||||
var gradient;
|
||||
|
||||
module.exports = {
|
||||
config: {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
|
||||
pointBorderColor: '#ff0000',
|
||||
pointBackgroundColor: '#00ff00',
|
||||
showLine: false
|
||||
}, {
|
||||
label: '',
|
||||
data: [4, 4, 4, 4, 4, 5, 3, 4, 4, 4, 4],
|
||||
pointBorderColor: pattern,
|
||||
pointBackgroundColor: pattern,
|
||||
showLine: false
|
||||
}, {
|
||||
label: '',
|
||||
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
showLine: false
|
||||
}],
|
||||
labels: ['', '', '', '', '', '', '', '', '', '', '']
|
||||
},
|
||||
options: {
|
||||
legend: false,
|
||||
title: false,
|
||||
scales: {
|
||||
xAxes: [{display: false}],
|
||||
yAxes: [{display: false}]
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
fill: false
|
||||
}
|
||||
},
|
||||
tooltips: {
|
||||
mode: 'nearest',
|
||||
intersect: false,
|
||||
callbacks: {
|
||||
label: function() {
|
||||
return '\u200b';
|
||||
}
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
padding: 15
|
||||
}
|
||||
},
|
||||
plugins: [{
|
||||
beforeDatasetsUpdate: function(chart) {
|
||||
if (!gradient) {
|
||||
gradient = chart.ctx.createLinearGradient(0, 0, 512, 256);
|
||||
gradient.addColorStop(0, '#ff0000');
|
||||
gradient.addColorStop(1, '#0000ff');
|
||||
}
|
||||
chart.config.data.datasets[2].pointBorderColor = gradient;
|
||||
chart.config.data.datasets[2].pointBackgroundColor = gradient;
|
||||
|
||||
return true;
|
||||
},
|
||||
afterDraw: function(chart) {
|
||||
var canvas = chart.canvas;
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
var point, event;
|
||||
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
for (var j = 0; j < 11; ++j) {
|
||||
point = chart.getDatasetMeta(i).data[j];
|
||||
event = {
|
||||
type: 'mousemove',
|
||||
target: canvas,
|
||||
clientX: rect.left + point._model.x,
|
||||
clientY: rect.top + point._model.y
|
||||
};
|
||||
chart.handleEvent(event);
|
||||
chart.tooltip.handleEvent(event);
|
||||
chart.tooltip.transition(1);
|
||||
chart.tooltip._view.opacity = j / 10;
|
||||
chart.tooltip.draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 256,
|
||||
width: 512
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/core.tooltip/opacity.png
vendored
Normal file
BIN
test/fixtures/core.tooltip/opacity.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -1,5 +1,7 @@
|
||||
// Test the rectangle element
|
||||
describe('Core.Tooltip', function() {
|
||||
describe('auto', jasmine.fixture.specs('core.tooltip'));
|
||||
|
||||
describe('config', function() {
|
||||
it('should not include the dataset label in the body string if not defined', function() {
|
||||
var data = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user