assert.deepEqual([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
it('testRollingAveragePreservesNaNs', function() {
assert.deepEqual({r: 255, g: 200, b: 150}, Dygraph.toRGB_('rgb(255,200,150)'));
assert.deepEqual({r: 255, g: 200, b: 150}, Dygraph.toRGB_('#FFC896'));
assert.deepEqual({r: 255, g: 0, b: 0}, Dygraph.toRGB_('red'));
+ assert.deepEqual({r: 255, g: 200, b: 150, a: 0.6},
+ Dygraph.toRGB_('rgba(255, 200, 150, 0.6)'));
});
it('testIsPixelChangingOptionList', function() {
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';
document.body.appendChild(div);
var rgbStr = window.getComputedStyle(div, null).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);
};
/**