Skip to content

Commit 93152df

Browse files
committed
Refactor tooltip mergeOpacity calls and support CanvasPattern and CanvasGradient
1 parent d6ac7d8 commit 93152df

File tree

4 files changed

+129
-25
lines changed

4 files changed

+129
-25
lines changed

src/core/core.tooltip.js

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,6 @@ var positioners = {
168168
}
169169
};
170170

171-
/**
172-
* Helper method to merge the opacity into a color
173-
*/
174-
function mergeOpacity(colorString, opacity) {
175-
var color = helpers.color(colorString);
176-
return color.alpha(opacity * color.alpha()).rgbaString();
177-
}
178-
179171
// Helper to push or concat based on if the 2nd parameter is an array or not
180172
function pushOrConcat(base, toPush) {
181173
if (toPush) {
@@ -734,7 +726,7 @@ var exports = module.exports = Element.extend({
734726
return {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};
735727
},
736728

737-
drawTitle: function(pt, vm, ctx, opacity) {
729+
drawTitle: function(pt, vm, ctx) {
738730
var title = vm.title;
739731

740732
if (title.length) {
@@ -744,7 +736,7 @@ var exports = module.exports = Element.extend({
744736
var titleFontSize = vm.titleFontSize;
745737
var titleSpacing = vm.titleSpacing;
746738

747-
ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
739+
ctx.fillStyle = vm.titleFontColor;
748740
ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);
749741

750742
var i, len;
@@ -759,7 +751,7 @@ var exports = module.exports = Element.extend({
759751
}
760752
},
761753

762-
drawBody: function(pt, vm, ctx, opacity) {
754+
drawBody: function(pt, vm, ctx) {
763755
var bodyFontSize = vm.bodyFontSize;
764756
var bodySpacing = vm.bodySpacing;
765757
var body = vm.body;
@@ -776,32 +768,32 @@ var exports = module.exports = Element.extend({
776768
};
777769

778770
// Before body lines
779-
ctx.fillStyle = mergeOpacity(vm.bodyFontColor, opacity);
771+
ctx.fillStyle = vm.bodyFontColor;
780772
helpers.each(vm.beforeBody, fillLineOfText);
781773

782774
var drawColorBoxes = vm.displayColors;
783775
xLinePadding = drawColorBoxes ? (bodyFontSize + 2) : 0;
784776

785777
// Draw body lines now
786778
helpers.each(body, function(bodyItem, i) {
787-
var textColor = mergeOpacity(vm.labelTextColors[i], opacity);
779+
var textColor = vm.labelTextColors[i];
788780
ctx.fillStyle = textColor;
789781
helpers.each(bodyItem.before, fillLineOfText);
790782

791783
helpers.each(bodyItem.lines, function(line) {
792784
// Draw Legend-like boxes if needed
793785
if (drawColorBoxes) {
794786
// Fill a white rect so that colours merge nicely if the opacity is < 1
795-
ctx.fillStyle = mergeOpacity(vm.legendColorBackground, opacity);
787+
ctx.fillStyle = vm.legendColorBackground;
796788
ctx.fillRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
797789

798790
// Border
799791
ctx.lineWidth = 1;
800-
ctx.strokeStyle = mergeOpacity(vm.labelColors[i].borderColor, opacity);
792+
ctx.strokeStyle = vm.labelColors[i].borderColor;
801793
ctx.strokeRect(pt.x, pt.y, bodyFontSize, bodyFontSize);
802794

803795
// Inner square
804-
ctx.fillStyle = mergeOpacity(vm.labelColors[i].backgroundColor, opacity);
796+
ctx.fillStyle = vm.labelColors[i].backgroundColor;
805797
ctx.fillRect(pt.x + 1, pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);
806798
ctx.fillStyle = textColor;
807799
}
@@ -820,7 +812,7 @@ var exports = module.exports = Element.extend({
820812
pt.y -= bodySpacing; // Remove last body spacing
821813
},
822814

823-
drawFooter: function(pt, vm, ctx, opacity) {
815+
drawFooter: function(pt, vm, ctx) {
824816
var footer = vm.footer;
825817

826818
if (footer.length) {
@@ -829,7 +821,7 @@ var exports = module.exports = Element.extend({
829821
ctx.textAlign = vm._footerAlign;
830822
ctx.textBaseline = 'top';
831823

832-
ctx.fillStyle = mergeOpacity(vm.footerFontColor, opacity);
824+
ctx.fillStyle = vm.footerFontColor;
833825
ctx.font = helpers.fontString(vm.footerFontSize, vm._footerFontStyle, vm._footerFontFamily);
834826

835827
helpers.each(footer, function(line) {
@@ -839,9 +831,9 @@ var exports = module.exports = Element.extend({
839831
}
840832
},
841833

842-
drawBackground: function(pt, vm, ctx, tooltipSize, opacity) {
843-
ctx.fillStyle = mergeOpacity(vm.backgroundColor, opacity);
844-
ctx.strokeStyle = mergeOpacity(vm.borderColor, opacity);
834+
drawBackground: function(pt, vm, ctx, tooltipSize) {
835+
ctx.fillStyle = vm.backgroundColor;
836+
ctx.strokeStyle = vm.borderColor;
845837
ctx.lineWidth = vm.borderWidth;
846838
var xAlign = vm.xAlign;
847839
var yAlign = vm.yAlign;
@@ -906,21 +898,26 @@ var exports = module.exports = Element.extend({
906898
var hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;
907899

908900
if (this._options.enabled && hasTooltipContent) {
901+
ctx.save();
902+
ctx.globalAlpha = opacity;
903+
909904
// Draw Background
910-
this.drawBackground(pt, vm, ctx, tooltipSize, opacity);
905+
this.drawBackground(pt, vm, ctx, tooltipSize);
911906

912907
// Draw Title, Body, and Footer
913908
pt.x += vm.xPadding;
914909
pt.y += vm.yPadding;
915910

916911
// Titles
917-
this.drawTitle(pt, vm, ctx, opacity);
912+
this.drawTitle(pt, vm, ctx);
918913

919914
// Body
920-
this.drawBody(pt, vm, ctx, opacity);
915+
this.drawBody(pt, vm, ctx);
921916

922917
// Footer
923-
this.drawFooter(pt, vm, ctx, opacity);
918+
this.drawFooter(pt, vm, ctx);
919+
920+
ctx.restore();
924921
}
925922
},
926923

test/fixtures/core.tooltip/opacity.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
var pattern;
2+
var gradient;
3+
4+
module.exports = {
5+
config: {
6+
type: 'line',
7+
data: {
8+
datasets: [{
9+
data: [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
10+
pointBorderColor: '#ff0000',
11+
pointBackgroundColor: '#00ff00',
12+
showLine: false
13+
}, {
14+
label: '',
15+
data: [4, 4, 4, 4, 4, 5, 3, 4, 4, 4, 4],
16+
showLine: false
17+
}, {
18+
label: '',
19+
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
20+
showLine: false
21+
}],
22+
labels: ['', '', '', '', '', '', '', '', '', '', '']
23+
},
24+
options: {
25+
legend: false,
26+
title: false,
27+
scales: {
28+
xAxes: [{display: false}],
29+
yAxes: [{display: false}]
30+
},
31+
elements: {
32+
line: {
33+
fill: false
34+
}
35+
},
36+
tooltips: {
37+
mode: 'nearest',
38+
intersect: false,
39+
callbacks: {
40+
label: function() {
41+
return '\u200b';
42+
}
43+
}
44+
},
45+
layout: {
46+
padding: 15
47+
}
48+
},
49+
plugins: [{
50+
beforeDatasetsUpdate: function(chart) {
51+
if (!pattern) {
52+
var patternCanvas = document.createElement('canvas');
53+
var patternContext = patternCanvas.getContext('2d');
54+
patternCanvas.width = 6;
55+
patternCanvas.height = 6;
56+
patternContext.fillStyle = '#ff0000';
57+
patternContext.fillRect(0, 0, 6, 6);
58+
patternContext.fillStyle = '#ffff00';
59+
patternContext.fillRect(0, 0, 4, 4);
60+
pattern = patternContext.createPattern(patternCanvas, 'repeat');
61+
}
62+
chart.config.data.datasets[1].pointBorderColor = pattern;
63+
chart.config.data.datasets[1].pointBackgroundColor = pattern;
64+
65+
if (!gradient) {
66+
gradient = chart.ctx.createLinearGradient(0, 0, 512, 256);
67+
gradient.addColorStop(0, '#ff0000');
68+
gradient.addColorStop(1, '#0000ff');
69+
}
70+
chart.config.data.datasets[2].pointBorderColor = gradient;
71+
chart.config.data.datasets[2].pointBackgroundColor = gradient;
72+
73+
return true;
74+
},
75+
afterDraw: function(chart) {
76+
var canvas = chart.canvas;
77+
var rect = canvas.getBoundingClientRect();
78+
var point, event;
79+
80+
for (var i = 0; i < 3; ++i) {
81+
for (var j = 0; j < 11; ++j) {
82+
point = chart.getDatasetMeta(i).data[j];
83+
event = {
84+
type: 'mousemove',
85+
target: canvas,
86+
clientX: rect.left + point._model.x,
87+
clientY: rect.top + point._model.y
88+
};
89+
chart.handleEvent(event);
90+
chart.tooltip.handleEvent(event);
91+
chart.tooltip.transition(1);
92+
chart.tooltip._view.opacity = j / 10;
93+
chart.tooltip.draw();
94+
}
95+
}
96+
}
97+
}]
98+
},
99+
options: {
100+
canvas: {
101+
height: 256,
102+
width: 512
103+
}
104+
}
105+
};
11.5 KB
Loading

test/specs/core.tooltip.tests.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Test the rectangle element
22
describe('Core.Tooltip', function() {
3+
describe('auto', jasmine.fixture.specs('core.tooltip'));
4+
35
describe('config', function() {
46
it('should not include the dataset label in the body string if not defined', function() {
57
var data = {

0 commit comments

Comments
 (0)