diff --git a/src/core/core.tooltip.js b/src/core/core.tooltip.js index c529812cc61..c3245d9cf1e 100644 --- a/src/core/core.tooltip.js +++ b/src/core/core.tooltip.js @@ -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(); } }, diff --git a/test/fixtures/core.tooltip/opacity.js b/test/fixtures/core.tooltip/opacity.js new file mode 100644 index 00000000000..2a825f5a630 --- /dev/null +++ b/test/fixtures/core.tooltip/opacity.js @@ -0,0 +1,105 @@ +var pattern; +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], + 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 (!pattern) { + 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); + pattern = patternContext.createPattern(patternCanvas, 'repeat'); + } + chart.config.data.datasets[1].pointBorderColor = pattern; + chart.config.data.datasets[1].pointBackgroundColor = pattern; + + 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 + } + } +}; diff --git a/test/fixtures/core.tooltip/opacity.png b/test/fixtures/core.tooltip/opacity.png new file mode 100644 index 00000000000..142dcc05f60 Binary files /dev/null and b/test/fixtures/core.tooltip/opacity.png differ diff --git a/test/specs/core.tooltip.tests.js b/test/specs/core.tooltip.tests.js index 9d858a49e10..c342fe64618 100755 --- a/test/specs/core.tooltip.tests.js +++ b/test/specs/core.tooltip.tests.js @@ -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 = {