From: Dan Vanderkam Date: Tue, 21 Apr 2015 18:41:39 +0000 (-0400) Subject: Parse rgba colors (fixes #517) X-Git-Tag: v1.1.1~18 X-Git-Url: https://adrianiainlam.tk/git/?a=commitdiff_plain;h=e6b1eb3b54a7a92e0b7c1c17a0667b637ab01ea2;p=dygraphs.git Parse rgba colors (fixes #517) Conflicts: auto_tests/tests/utils_test.js --- diff --git a/auto_tests/tests/error_bars.js b/auto_tests/tests/error_bars.js index 1c3894c..6830496 100644 --- a/auto_tests/tests/error_bars.js +++ b/auto_tests/tests/error_bars.js @@ -131,6 +131,53 @@ errorBarsTestCase.prototype.testErrorBarsCorrectColors = function() { assertEquals([0, 255, 0, 38], Util.samplePixel(g.hidden_, 200, 225)); }; +// Regression test for https://github.com/danvk/dygraphs/issues/517 +// This verifies that the error bars have alpha=fillAlpha, even if the series +// color has its own alpha value. +it('testErrorBarsForAlphaSeriesCorrectColors', function() { + var data = [ + [0, [100, 50]], + [2, [100, 50]] + ]; + + var opts = { + errorBars: true, + sigma: 1.0, + fillAlpha: 0.15, + strokeWidth: 10, + colors: ['rgba(0, 255, 0, 0.5)'], + axes : { + x : { + drawGrid: false, + drawAxis: false, + }, + y : { + drawGrid: false, + drawAxis: false, + } + }, + width: 400, + height: 300, + valueRange: [0, 300], + labels: ['X', 'Y'] + }; + var graph = document.getElementById("graph"); + var g = new Dygraph(graph, data, opts); + + // y-pixels (0=top, 299=bottom) + // 0-148: empty (white) + // 149-198: Y error bar + // 199: Y center line + // 200-248: Y error bar + // 249-299: empty (white) + + // 38 = 255 * 0.15 (fillAlpha) + // 146 = 255 * (0.15 * 0.5 + 1 * 0.5) (fillAlpha from error bar + alpha from series line) + assert.deepEqual([0, 255, 0, 38], Util.samplePixel(g.hidden_, 1, 175)); + assert.deepEqual([0, 255, 0, 146], Util.samplePixel(g.hidden_, 200, 199)); + assert.deepEqual([0, 255, 0, 38], Util.samplePixel(g.hidden_, 1, 225)); +}); + // Regression test for http://code.google.com/p/dygraphs/issues/detail?id=392 errorBarsTestCase.prototype.testRollingAveragePreservesNaNs = function() { diff --git a/auto_tests/tests/utils_test.js b/auto_tests/tests/utils_test.js index 5bd7f8d..ef48b8c 100644 --- a/auto_tests/tests/utils_test.js +++ b/auto_tests/tests/utils_test.js @@ -175,6 +175,8 @@ UtilsTestCase.prototype.testToRGB = function() { assertEquals({r: 255, g: 200, b: 150}, Dygraph.toRGB_('rgb(255,200,150)')); assertEquals({r: 255, g: 200, b: 150}, Dygraph.toRGB_('#FFC896')); assertEquals({r: 255, g: 0, b: 0}, Dygraph.toRGB_('red')); + assertEquals({r: 255, g: 200, b: 150, a: 0.6}, + Dygraph.toRGB_('rgba(255, 200, 150, 0.6)')); }; UtilsTestCase.prototype.testIsPixelChangingOptionList = function() { diff --git a/dygraph-utils.js b/dygraph-utils.js index bf93665..bb96073 100644 --- a/dygraph-utils.js +++ b/dygraph-utils.js @@ -1135,15 +1135,41 @@ Dygraph.pow = function(base, exp) { return Math.pow(base, exp); }; +var RGBA_RE = /^rgba?\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})(?:,\s*([01](?:\.\d+)?))?\)$/; + +/** + * Helper for Dygraph.toRGB_ which parses strings of the form: + * rgb(123, 45, 67) + * rgba(123, 45, 67, 0.5) + * @return parsed {r,g,b,a?} tuple or null. + */ +function parseRGBA(rgbStr) { + var bits = RGBA_RE.exec(rgbStr); + if (!bits) return null; + var r = parseInt(bits[1], 10), + g = parseInt(bits[2], 10), + b = parseInt(bits[3], 10); + if (bits[4]) { + return {r: r, g: g, b: b, a: parseFloat(bits[4])}; + } else { + return {r: r, g: g, b: b}; + } +} + /** * Converts any valid CSS color (hex, rgb(), named color) to an RGB tuple. * * @param {!string} colorStr Any valid CSS color string. - * @return {{r:number,g:number,b:number}} Parsed RGB tuple. + * @return {{r:number,g:number,b:number,a:number?}} Parsed RGB tuple. * @private */ Dygraph.toRGB_ = function(colorStr) { - // TODO(danvk): cache color parses to avoid repeated DOM manipulation. + // Strategy: First try to parse colorStr directly. This is fast & avoids DOM + // manipulation. If that fails (e.g. for named colors like 'red'), then + // create a hidden DOM element and parse its computed color. + var rgb = parseRGBA(colorStr); + if (rgb) return rgb; + var div = document.createElement('div'); div.style.backgroundColor = colorStr; div.style.visibility = 'hidden'; @@ -1156,12 +1182,7 @@ Dygraph.toRGB_ = function(colorStr) { rgbStr = div.currentStyle.backgroundColor; } document.body.removeChild(div); - var bits = /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.exec(rgbStr); - return { - r: parseInt(bits[1], 10), - g: parseInt(bits[2], 10), - b: parseInt(bits[3], 10) - }; + return parseRGBA(rgbStr); }; /**