To iterate on the code, open `tests/demo.html` (or one of the other demos) in your browser.
-To iterate on a unit test, change `it` to `it.only` in the Mocha test, change the browser from `PhantomJS` to `Chrome` (or whatever you like) and set `singleRun` to `false` in `auto_tests/karma.conf.js`. Then run
+To iterate on a unit test, change `it` to `it.only` in the Mocha test. Then run
- ./node_modules/karma/bin/karma start auto_tests/karma.conf.js
+ ./node_modules/karma/bin/karma start auto_tests/chrome.karma.conf.js
and hit "DEBUG" in the Karma UI.
--- /dev/null
+module.exports = function (config) {
+ config.set({
+ basePath: '../',
+ frameworks: [
+ 'mocha',
+ 'chai'
+ ],
+ files: [
+ 'dist/dygraph-combined-dev.js',
+ 'src/extras/smooth-plotter.js',
+ 'auto_tests/data/*.js',
+ 'auto_tests/tests/*.js',
+ ],
+ autoWatch: true,
+ singleRun: false,
+ reporters: ['mocha'], // or 'dots', 'mocha', 'spec'
+ browsers: ['Chrome'], // or 'Firefox', 'Safari', etc.
+ plugins: [
+ 'karma-mocha',
+ 'karma-chai-plugins',
+ 'karma-chrome-launcher',
+ 'karma-firefox-launcher',
+ 'karma-spec-reporter',
+ 'karma-mocha-reporter'
+ ]
+ });
+};
files: [
'dist/dygraph-combined-dev.js',
'src/extras/smooth-plotter.js',
- 'auto_tests/**/*.js',
+ 'auto_tests/data/*.js',
+ 'auto_tests/tests/*.js',
],
autoWatch: false,
singleRun: true,
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() {
"karma-chai-plugins": "^0.2.4",
"karma-chrome-launcher": "^0.1.7",
"karma-coverage": "^0.2.7",
+ "karma-firefox-launcher": "^0.1.4",
"karma-mocha": "^0.1.10",
"karma-mocha-reporter": "^1.0.2",
"karma-phantomjs-launcher": "^0.1.4",
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);
};
/**