diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 80% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md index ee72da0ef..80d7cf27a 100644 --- a/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -7,13 +7,13 @@ It also helps if you include the non-compacted version of the JS on your page. For instance, instead of doing this: ```html - + ``` do this: ```html - + ``` This makes error messages and debugging simpler. The jsfiddle does this automatically. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..3bbac0493 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,20 @@ +Filing a bug report? Please include the following: + +1. Link to a page which demonstrates the problem, preferably a jsfiddle (use http://dygraphs.com/fiddle as a template) +2. Browser and Operating System that exhibit the problem +3. Version of dygraphs that you're using + +It also helps if you include the non-compacted version of the JS on your +page. For instance, instead of doing this: + +```html + +``` + +do this: + +```html + +``` + +This makes error messages and debugging simpler. The jsfiddle does this automatically. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..474eeed5b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,14 @@ +Please read the guide to making dygraphs changes: +http://dygraphs.com/changes.html + +Pull Requests will only be accepted if: + +- You clearly explain what you're adding and why you believe it's an + improvement. For example: "Fixes issue #123". +- You adhere to the style of the rest of the dygraphs code base. +- You write an `auto_test` for the code that you're adding. + +Be sure to document any new options you add. Also be aware that PRs which add +options are likely to be rejected. dygraphs already has many options. If you +can fit your feature into one of those or implement it as a plugin, it will be +more likely to get merged. diff --git a/.gitignore b/.gitignore index 121cd6678..1a6f93b9c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ env dist coverage *.log +*.pyc +src-es5 diff --git a/.travis.yml b/.travis.yml index 198ce97c2..130ac697a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - "0.10" + - "6" sudo: false # Use container-based architecture script: > diff --git a/DEVELOP.md b/DEVELOP.md index 9a13888c9..6eb43fb19 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -6,6 +6,10 @@ This is a step-by-step guide explaining how to do it. ### How-to +To install dependencies, run + + npm install + To build dygraphs, run npm run build diff --git a/README.md b/README.md index 9abb9a1a9..e539994d9 100644 --- a/README.md +++ b/README.md @@ -7,24 +7,23 @@ The dygraphs JavaScript library produces interactive, zoomable charts of time se Learn more about it at [dygraphs.com](http://www.dygraphs.com). -Get help with dygraphs on -[Stack Overflow](http://stackoverflow.com/questions/tagged/dygraphs) (preferred) and -[Google Groups](http://groups.google.com/group/dygraphs-users) +Get help with dygraphs by browsing the on [Stack Overflow][] (preferred) and [Google Groups][]. ## Features * Plots time series without using an external server or Flash -* Supports [error bands](http://dygraphs.com/tests/legend-values.html) around data series -* Interactive [pan and zoom](http://dygraphs.com/tests/link-interaction.html) -* Displays values [on mouseover](http://dygraphs.com/tests/legend-values.html) -* Adjustable [averaging period](http://dygraphs.com/tests/temperature-sf-ny.html) -* Extensive set of [options](http://www.dygraphs.com/options.html) for customization. -* Compatible with the [Google Visualization API](http://dygraphs.com/data.html#datatable) +* Supports [error bands][] around data series +* Interactive [pan and zoom][] +* Displays values [on mouseover][] +* Adjustable [averaging period][] +* Extensive set of [options][] for customization. +* Compatible with the [Google Visualization API][gviz] ## Minimal Example ```html - + +
@@ -42,9 +41,27 @@ Get help with dygraphs on ``` -Learn more by reading [the tutorial](http://www.dygraphs.com/tutorial.html) and -seeing demonstrations of what dygraphs can do in the -[gallery](http://www.dygraphs.com/gallery). +Learn more by reading [the tutorial][] and seeing demonstrations of what +dygraphs can do in the [gallery][]. You can get `dygraph.js` and `dygraph.css` +from [cdnjs][] or [from NPM][npm] (see below). + +## Usage with a module loader + +Get dygraphs from NPM: + + npm install dygraphs + +You'll find pre-built JS & CSS files in `node_modules/dygraphs/dist`. If you're +using a module bundler like browserify or webpack, you can import dygraphs: + +```js +import Dygraph from 'dygraphs'; +// or: const Dygraph = require('dygraphs'); + +const g = new Dygraph('graphdiv', data, { /* options */ }); +``` + +Check out the [dygraphs-es6 repo][] for a fully-worked example. ## Development @@ -59,3 +76,17 @@ Read more about the dygraphs development process in the [developer guide](/DEVEL ## License(s) dygraphs is available under the MIT license, included in LICENSE.txt. + +[cdnjs]: https://cdnjs.com/libraries/dygraph +[the tutorial]: http://www.dygraphs.com/tutorial.html +[gallery]: http://www.dygraphs.com/gallery +[error bands]: http://dygraphs.com/tests/legend-values.html +[pan and zoom]: http://dygraphs.com/tests/link-interaction.html +[on mouseover]: http://dygraphs.com/tests/legend-values.html +[averaging period]: http://dygraphs.com/tests/temperature-sf-ny.html +[options]: http://www.dygraphs.com/options.html +[Stack Overflow]: http://stackoverflow.com/questions/tagged/dygraphs?sort=votes&pageSize=50 +[Google Groups]: http://groups.google.com/group/dygraphs-users +[gviz]: http://dygraphs.com/data.html#datatable +[npm]: https://www.npmjs.com/package/dygraphs +[dygraphs-es6 repo]: https://github.com/danvk/dygraphs-es6 diff --git a/auto_tests/coverage.html b/auto_tests/coverage.html index 04573478f..adf263998 100644 --- a/auto_tests/coverage.html +++ b/auto_tests/coverage.html @@ -3,14 +3,12 @@ dygraphs tests +
- - - diff --git a/auto_tests/data/out-of-order-dates.csv b/auto_tests/data/out-of-order-dates.csv new file mode 100644 index 000000000..a05ef062e --- /dev/null +++ b/auto_tests/data/out-of-order-dates.csv @@ -0,0 +1,9 @@ +Date,r17,r82,r83,r9 +2013-10-17T21:00:00Z,,,,9 +2014-05-29T18:00:00Z,,,,9 +2013-10-17T21:00:00Z,17,,, +2014-05-29T17:00:00Z,17,,, +2014-05-29T18:00:00Z,,82,, +2014-05-29T18:00:00Z,,,83, +2014-10-11T04:00:00Z,,,83, +2015-05-22T04:00:00Z,,82,, diff --git a/auto_tests/data/out-of-order.csv b/auto_tests/data/out-of-order.csv new file mode 100644 index 000000000..51f40a688 --- /dev/null +++ b/auto_tests/data/out-of-order.csv @@ -0,0 +1,5 @@ +X,Y1,Y2 +0,0,0 +1,1,1 +3,3,9 +2,2,4 diff --git a/auto_tests/data/sample.csv b/auto_tests/data/sample.csv new file mode 100644 index 000000000..5bae60ee9 --- /dev/null +++ b/auto_tests/data/sample.csv @@ -0,0 +1,5 @@ +X,Y1,Y2 +0,0,0 +1,1,1 +2,2,4 +3,3,9 diff --git a/auto_tests/runner.html b/auto_tests/runner.html index c3a3d8797..7ceb0d08c 100644 --- a/auto_tests/runner.html +++ b/auto_tests/runner.html @@ -3,14 +3,12 @@ dygraphs tests +
- - - diff --git a/auto_tests/tests/axis_labels.js b/auto_tests/tests/axis_labels.js index 0af808522..5a631fa13 100644 --- a/auto_tests/tests/axis_labels.js +++ b/auto_tests/tests/axis_labels.js @@ -687,6 +687,33 @@ it('testLogScale', function() { assert.deepEqual(['0','200','400','600','800','1000'], Util.getYLabels()); }); +/** + * Verify that log scale axis range works with yRangePad. + * + * This is a regression test for https://github.com/danvk/dygraphs/issues/661 . + */ +it('testLogScalePad', function() { + var g = new Dygraph("graph", + [[0, 1e-5], [1, 0.25], [2, 1], [3, 3], [4, 10]], { + width: 250, + height: 130, + logscale: true, + yRangePad: 30, + axes: {y: {valueRange: [1, 10]}}, + labels: ['X', 'Y'] + }); + var nonEmptyLabels = Util.getYLabels().filter(function(x) { return x.length > 0; }); + assert.deepEqual(['1', '7', '30'], nonEmptyLabels); + + g.updateOptions({ yRangePad: 10, axes: {y: {valueRange: [0.25005, 3]}} }); + nonEmptyLabels = Util.getYLabels().filter(function(x) { return x.length > 0; }); + assert.deepEqual(['0.4', '1', '3'], nonEmptyLabels); + + g.updateOptions({ axes: {y: {valueRange: [0.01, 3]}} }); + nonEmptyLabels = Util.getYLabels().filter(function(x) { return x.length > 0; }); + assert.deepEqual(['0.01','0.1','0.7','5'], nonEmptyLabels); +}); + /** * Verify that include zero range is properly specified. */ @@ -771,75 +798,6 @@ it('testAxisLabelFontSizeNull', function() { assertFontSize(document.querySelectorAll(".dygraph-axis-label-y"), "14px"); }); -it('testAxisLabelColor', function() { - var graph = document.getElementById("graph"); - var g = new Dygraph(graph, simpleData, {}); - - // Be sure we're dealing with a black default. - assert.equal("black", DEFAULT_ATTRS.axisLabelColor); - - var assertColor = function(selector, expected) { - Util.assertStyleOfChildren(selector, "color", expected); - } - - assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 0)"); - assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(0, 0, 0)"); - - g.updateOptions({ axisLabelColor : "red"}); - assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(255, 0, 0)"); - assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(255, 0, 0)"); - - g.updateOptions({ - axisLabelColor : null, - axes : { - x : { axisLabelColor : "blue" }, - } - }); - - assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 255)"); - assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(0, 0, 0)"); - - g.updateOptions({ - axes : { - y : { axisLabelColor : "green" }, - } - }); - - assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 255)"); - assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(0, 128, 0)"); - - g.updateOptions({ - series : { - Y2 : { axis : "y2" } // copy y2 series to y2 axis. - }, - axes : { - y2 : { axisLabelColor : "yellow" }, - } - }); - - assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 255)"); - assertColor(document.querySelectorAll(".dygraph-axis-label-y1"), "rgb(0, 128, 0)"); - assertColor(document.querySelectorAll(".dygraph-axis-label-y2"), "rgb(255, 255, 0)"); -}); - -it('testAxisLabelColorNull', function() { - var graph = document.getElementById("graph"); - var g = new Dygraph(graph, simpleData, - { - axisLabelColor: null - }); - - var assertColor = function(selector, expected) { - Util.assertStyleOfChildren(selector, "color", expected); - } - - // Be sure we're dealing with a 14-point default. - assert.equal(14, DEFAULT_ATTRS.axisLabelFontSize); - - assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 0)"); - assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(0, 0, 0)"); -}); - /* * This test shows that the label formatter overrides labelsKMB for all values. */ diff --git a/auto_tests/tests/data_api.js b/auto_tests/tests/data_api.js index e692fc61e..631990980 100644 --- a/auto_tests/tests/data_api.js +++ b/auto_tests/tests/data_api.js @@ -4,6 +4,7 @@ * @author danvdk@gmail.com (Dan Vanderkam) */ import Dygraph from '../../src/dygraph'; +import * as utils from '../../src/dygraph-utils'; describe("data-api", function() { cleanupAfterEach(); @@ -99,4 +100,21 @@ it('testGetRowForXDuplicates', function() { assert.equal(5, g.getRowForX(9)); }); +// indexFromSeriesName should return a value even if the series is invisible +// In 1.1.1, if you request the last set and it's invisible, the method returns undefined. +it('testIndexFromSetNameOnInvisibleSet', function() { + + var localOpts = utils.clone(opts); + localOpts.visibility = [true, false]; + + var g = new Dygraph(graphDiv, [ + "x,y1,y2", + "1,1,1", + "2,2,2", + "3,3,3" + ].join('\n'), localOpts); + + assert.equal(2, g.indexFromSetName("y2")); +}); + }); diff --git a/auto_tests/tests/data_types.js b/auto_tests/tests/data_types.js new file mode 100644 index 000000000..023d60864 --- /dev/null +++ b/auto_tests/tests/data_types.js @@ -0,0 +1,34 @@ +/** + * @fileoverview Test cases for DygraphOptions. + */ + +import Dygraph from '../../src/dygraph'; + +describe("dygraph-data-types", function() { + + cleanupAfterEach(); + + var graph; + + beforeEach(function() { + graph = document.getElementById("graph"); + }); + + /* + * Test to ensure ints are correctly interpreted as ints and not as dates + */ + it('testNumberOfData', function() { + var opts = { + width: 480, + height: 320 + }; + var data = "x y\n" + + "20033000 1\n" + + "20034000 2\n" + + "20035000 3\n" + + "20036000 4"; + + var g = new Dygraph(graph, data, opts); + assert.deepEqual(4, g.rawData_.length); + }); +}); diff --git a/auto_tests/tests/date_formats.js b/auto_tests/tests/date_formats.js index f157b8dd4..5148fe7fb 100644 --- a/auto_tests/tests/date_formats.js +++ b/auto_tests/tests/date_formats.js @@ -36,4 +36,12 @@ it('testHyphenatedDate', function() { assert.equal(Date.UTC(2000, 1, 2), utils.dateParser(str)); }); +it('testMillisecondsDate', function() { + // Format: YYYY-MM-DD HH:MM:SS.MS + + // Midnight February 2, 2000 14:25:42.123 UTC + var ts = Date.UTC(2000, 1, 2, 14, 25, 42, 123); + assert.equal("2000/02/02 14:25:42.123", utils.dateString_(ts, true)); +}); + }); diff --git a/auto_tests/tests/date_ticker.js b/auto_tests/tests/date_ticker.js index c02331dc7..fc18733ed 100644 --- a/auto_tests/tests/date_ticker.js +++ b/auto_tests/tests/date_ticker.js @@ -263,6 +263,19 @@ it('testAllDateTickers', function() { assert.deepEqual([{"v":1307908020000,"label":"19:47"},{"v":1307908050000,"label":"19:47:30"},{"v":1307908080000,"label":"19:48"},{"v":1307908110000,"label":"19:48:30"},{"v":1307908140000,"label":"19:49"},{"v":1307908170000,"label":"19:49:30"}], ticker(1307908000112, 1307908172259, 800, options)); assert.deepEqual([{"v":1307908020000,"label":"19:47"},{"v":1307908050000,"label":"19:47:30"},{"v":1307908080000,"label":"19:48"},{"v":1307908110000,"label":"19:48:30"},{"v":1307908140000,"label":"19:49"},{"v":1307908170000,"label":"19:49:30"}], ticker(1307908000112, 1307908173260, 800, options)); assert.deepEqual([{"v":978307200000,"label":"Jan 2001"},{"v":986083200000,"label":"Apr 2001"},{"v":993945600000,"label":"Jul 2001"},{"v":1001894400000,"label":"Oct 2001"}], ticker(978307200000, 1001894400000, 400, options)); + + assert.deepEqual([{"v":1307908000110,"label":"40.110"},{"v":1307908000111,"label":"40.111"},{"v":1307908000112,"label":"40.112"},{"v":1307908000113,"label":"40.113"}], ticker(1307908000110, 1307908000113, 200, options)); + assert.deepEqual([{"v":1307908000110,"label":"40.110"},{"v":1307908000112,"label":"40.112"},{"v":1307908000114,"label":"40.114"},{"v":1307908000116,"label":"40.116"}], ticker(1307908000110, 1307908000116, 200, options)); + assert.deepEqual([{"v":1307908000110,"label":"40.110"},{"v":1307908000115,"label":"40.115"},{"v":1307908000120,"label":"40.120"},{"v":1307908000125,"label":"40.125"}], ticker(1307908000110, 1307908000125, 200, options)); + assert.deepEqual([{"v":1307908000110,"label":"40.110"},{"v":1307908000120,"label":"40.120"},{"v":1307908000130,"label":"40.130"},{"v":1307908000140,"label":"40.140"}], ticker(1307908000110, 1307908000140, 200, options)); + + assert.deepEqual([{"v":1307908000100,"label":"40.100"},{"v":1307908000150,"label":"40.150"},{"v":1307908000200,"label":"40.200"},{"v":1307908000250,"label":"40.250"}], ticker(1307908000100, 1307908000250, 200, options)); + assert.deepEqual([{"v":1307908000100,"label":"40.100"},{"v":1307908000150,"label":"40.150"},{"v":1307908000200,"label":"40.200"},{"v":1307908000250,"label":"40.250"}], ticker(1307908000090, 1307908000260, 200, options)); + + assert.deepEqual([{"v":1307908000100,"label":"40.100"},{"v":1307908000200,"label":"40.200"},{"v":1307908000300,"label":"40.300"},{"v":1307908000400,"label":"40.400"}], ticker(1307908000100, 1307908000400, 200, options)); + assert.deepEqual([{"v":1307908000100,"label":"40.100"},{"v":1307908000200,"label":"40.200"},{"v":1307908000300,"label":"40.300"},{"v":1307908000400,"label":"40.400"}], ticker(1307908000100, 1307908000410, 200, options)); + + assert.deepEqual([{"v":1307908000000,"label":"40.000"},{"v":1307908000500,"label":"40.500"},{"v":1307908001000,"label":"41.000"},{"v":1307908001500,"label":"41.500"}], ticker(1307908000000, 1307908001500, 200, options)); }); }); diff --git a/auto_tests/tests/draw_gap_edge_points.js b/auto_tests/tests/draw_gap_edge_points.js new file mode 100644 index 000000000..3d92b0f32 --- /dev/null +++ b/auto_tests/tests/draw_gap_edge_points.js @@ -0,0 +1,47 @@ +/** + * @fileoverview Test cases for the option "drawGapEdgePoints" + */ + +import Dygraph from '../../src/dygraph'; +import * as utils from '../../src/dygraph-utils'; + +describe("draw-gap-edge-points", function() { + + cleanupAfterEach(); + + it("shouldn't draw any points by default", function() { + var called = false; + var g = new Dygraph(document.getElementById("graph"), + [[0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [5, 5]], + {labels: ['a', 'b'], + drawGapEdgePoints: true, + drawPointCallback: function() { called = true; }}); + + assert.isFalse(called); + }); + + it("shouldn't draw any points by default (no axes)", function() { + var called = false; + var g = new Dygraph(document.getElementById("graph"), + [[0, 0], + [1, 1], + [2, 2], + [3, 3], + [4, 4], + [5, 5]], + {labels: ['a', 'b'], + drawGapEdgePoints: true, + drawPointCallback: function() { called = true; }, + axes: { + x: { drawAxis: false }, + y: { drawAxis: false } + }}); + + assert.isFalse(called); + }); +}); diff --git a/auto_tests/tests/formats.js b/auto_tests/tests/formats.js index f16cc6d88..2548d99fd 100644 --- a/auto_tests/tests/formats.js +++ b/auto_tests/tests/formats.js @@ -77,6 +77,16 @@ it('testXValueParser', function() { assert.equal(6, g.getValue(3, 0)); }); +it('should throw on strings in native format', () => { + assert.throws(() => { + new Dygraph('graph', [['1', '10'], ['2', '20']]) + }, /expected number or date/i); + + assert.throws(() => { + new Dygraph('graph', [[new Date(), '10'], [new Date(), '20']]) + }, /expected number or array/i); +}); + var assertData = function(g) { var expected = dataArray; diff --git a/auto_tests/tests/hidpi.js b/auto_tests/tests/hidpi.js index 1dd131c7b..ceb3a49dc 100644 --- a/auto_tests/tests/hidpi.js +++ b/auto_tests/tests/hidpi.js @@ -45,5 +45,36 @@ it('testDoesntCreateScrollbars', function() { assert.equal(sw, document.body.scrollWidth); }); +it('should be influenced by options.pixelRatio', function () { + var graph = document.getElementById("graph"); + + // make sure devicePixelRatio is still setup to not 1. + assert(devicePixelRatio > 1.5, 'devicePixelRatio is not much greater than 1.'); + + var data = "X,Y\n" + + "0,-1\n" + + "1,0\n" + + "2,1\n" + + "3,0\n"; + + // first try a default one + var g1 = new Dygraph(graph, data, {}); + var area1 = g1.getArea(); + + var g2 = new Dygraph(graph, data, { pixelRatio: 1 }); + var area2 = g2.getArea(); + + var g3 = new Dygraph(graph, data, { pixelRatio: 3 }); + var area3 = g3.getArea(); + + assert.deepEqual(area1, area2, 'areas 1 and 2 are not the same'); + assert.deepEqual(area2, area3, 'areas 2 and 3 are not the same'); + + assert.notEqual(g1.canvas_.width, g2.canvas_.width, + 'Expected, for devicePixelRatio != 1, ' + + 'that setting options.pixelRatio would change the canvas width'); + assert.equal(g2.canvas_.width * 3, g3.canvas_.width, + 'Expected that pixelRatio of 3 vs 1 would triple the canvas width.'); +}); }); diff --git a/auto_tests/tests/interaction_model.js b/auto_tests/tests/interaction_model.js index a846df5cf..2015e111f 100644 --- a/auto_tests/tests/interaction_model.js +++ b/auto_tests/tests/interaction_model.js @@ -1,4 +1,4 @@ -/** +/** * @fileoverview Test cases for the interaction model. * * @author konigsberg@google.com (Robert Konigsbrg) @@ -344,7 +344,7 @@ it('testCorrectAxisValueRangeAfterUnzoom', function() { dateWindow: [1, 9], animatedZooms:false }); - + // Zoom x axis DygraphOps.dispatchMouseDown_Point(g, 100, 100); DygraphOps.dispatchMouseMove_Point(g, 130, 100); @@ -356,13 +356,13 @@ it('testCorrectAxisValueRangeAfterUnzoom', function() { DygraphOps.dispatchMouseUp_Point(g, 100, 130); var currentYAxisRange = g.yAxisRange(); var currentXAxisRange = g.xAxisRange(); - + //check that the range for the axis has changed assert.notEqual(1, currentXAxisRange[0]); assert.notEqual(10, currentXAxisRange[1]); assert.notEqual(1, currentYAxisRange[0]); assert.notEqual(50, currentYAxisRange[1]); - + // unzoom by doubleclick. This is really the order in which a browser // generates events, and we depend on it. DygraphOps.dispatchMouseDown_Point(g, 10, 10); @@ -370,13 +370,10 @@ it('testCorrectAxisValueRangeAfterUnzoom', function() { DygraphOps.dispatchMouseDown_Point(g, 10, 10); DygraphOps.dispatchMouseUp_Point(g, 10, 10); DygraphOps.dispatchDoubleClick(g, null); - - // check if range for y-axis was reset to original value - // TODO check if range for x-axis is correct. - // Currently not possible because dateRange is set to null and extremes are returned - var newYAxisRange = g.yAxisRange(); - assert.equal(1, newYAxisRange[0]); - assert.equal(50, newYAxisRange[1]); + + // check if the range for both axis was reset to show the full data. + assert.deepEqual(g.yAxisExtremes()[0], g.yAxisRange()); + assert.deepEqual(g.xAxisExtremes(), g.xAxisRange()); }); /** @@ -468,8 +465,9 @@ it('testCorrectAxisPaddingAfterUnzoom', function() { animatedZooms:false }); - var extremes = g.xAxisExtremes(); - + var xExtremes = g.xAxisExtremes(); + var [ yExtremes ] = g.yAxisExtremes(); + // Zoom x axis DygraphOps.dispatchMouseDown_Point(g, 100, 100); DygraphOps.dispatchMouseMove_Point(g, 130, 100); @@ -479,15 +477,11 @@ it('testCorrectAxisPaddingAfterUnzoom', function() { DygraphOps.dispatchMouseDown_Point(g, 100, 100); DygraphOps.dispatchMouseMove_Point(g, 100, 130); DygraphOps.dispatchMouseUp_Point(g, 100, 130); - var currentYAxisRange = g.yAxisRange(); - var currentXAxisRange = g.xAxisRange(); - + //check that the range for the axis has changed - assert.notEqual(1, currentXAxisRange[0]); - assert.notEqual(10, currentXAxisRange[1]); - assert.notEqual(1, currentYAxisRange[0]); - assert.notEqual(50, currentYAxisRange[1]); - + assert.notDeepEqual([1, 10], g.xAxisRange()); + assert.notDeepEqual([1, 50], g.yAxisRange()); + // unzoom by doubleclick. This is really the order in which a browser // generates events, and we depend on it. DygraphOps.dispatchMouseDown_Point(g, 10, 10); @@ -495,11 +489,10 @@ it('testCorrectAxisPaddingAfterUnzoom', function() { DygraphOps.dispatchMouseDown_Point(g, 10, 10); DygraphOps.dispatchMouseUp_Point(g, 10, 10); DygraphOps.dispatchDoubleClick(g, null); - - // check if range for x-axis was reset to original value - var newXAxisRange = g.xAxisRange(); - assert.equal(extremes[0], newXAxisRange[0]); - assert.equal(extremes[1], newXAxisRange[1]); + + // check if range for x-axis was reset to original value. + assert.deepEqual(xExtremes, g.xAxisRange()); + assert.deepEqual(yExtremes, g.yAxisRange()); }); }); diff --git a/auto_tests/tests/pathological_cases.js b/auto_tests/tests/pathological_cases.js index 0bcab0b79..326fefb71 100644 --- a/auto_tests/tests/pathological_cases.js +++ b/auto_tests/tests/pathological_cases.js @@ -70,10 +70,6 @@ it('testCombinations', function() { var variantOpts = { none: {}, - avoidMinZero: { - avoidMinZero: true, - includeZero: true - }, padded: { includeZero: true, drawAxesAtZero: true, @@ -90,7 +86,6 @@ it('testCombinations', function() { var opts = { width: 300, height: 150, - labelsDivWidth: 100, pointSize: 10 }; for (var key in base) { diff --git a/auto_tests/tests/plugins_legend.js b/auto_tests/tests/plugins_legend.js index 5f6759159..e2ee4f105 100644 --- a/auto_tests/tests/plugins_legend.js +++ b/auto_tests/tests/plugins_legend.js @@ -113,6 +113,18 @@ it('should use a legendFormatter', function() { assert.equal(calls[2].series[0].y, undefined); }); +it('should work with highlight series', () => { + var calls = []; + var g = new Dygraph(graph, 'X,y1,y2\n1,2,3\n', { + highlightSeriesOpts: { + strokeWidth: 3, + } + }); + + g.setSelection(false, 'y2'); + assert.equal(Util.getLegend(graph), ''); +}); + it('should include point drawn where canvas-y is 0', function () { var graph = document.getElementById("graph"); var calls = [] diff --git a/auto_tests/tests/range_selector.js b/auto_tests/tests/range_selector.js index 82884c835..1bba35361 100644 --- a/auto_tests/tests/range_selector.js +++ b/auto_tests/tests/range_selector.js @@ -630,6 +630,73 @@ it('testTwoCombinedSeriesCustomBars', function() { }, combinedSeries); }); +it('testHiddenSeriesExcludedFromMiniplot', function() { + var opts = { + showRangeSelector: true, + labels: ['X', 'Y1', 'Y2'], + visibility: [true, false] + }; + var data = [ + [0, 1, 3], // average = 2 + [5, 4, 6], // average = 5 + [10, 7, 9] // average = 8 + ]; + var graph = document.getElementById("graph"); + var g = new Dygraph(graph, data, opts); + + var rangeSelector = g.getPluginInstance_(RangeSelectorPlugin); + assert.isNotNull(rangeSelector); + + // Invisible series (e.g. Y2) are not included in the combined series. + var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_(); + assert.deepEqual({ + yMin: 1 - 6 * 0.25, // 25% padding on single series range. + yMax: 7 + 6 * 0.25, + data: [ + [0, 1], + [5, 4], + [10, 7] + ] + }, combinedSeries); + + // If Y2 is explicitly marked to be included in the range selector, + // then it will be (even if it's not visible). Since we've started being + // explicit about marking series for inclusion, this means that Y1 is no + // longer included. + g.updateOptions({ + series: { + Y2: { showInRangeSelector: true }, + } + }); + combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_(); + assert.deepEqual({ + yMin: 3 - 6 * 0.25, // 25% padding on combined series range. + yMax: 9 + 6 * 0.25, + data: [ + [0, 3], + [5, 6], + [10, 9] + ] + }, combinedSeries); + + // If we explicitly mark Y1, too, then it also gets included. + g.updateOptions({ + series: { + Y1: { showInRangeSelector: true }, + Y2: { showInRangeSelector: true }, + } + }); + combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_(); + assert.deepEqual({ + yMin: 2 - 6 * 0.25, // 25% padding on combined series range. + yMax: 8 + 6 * 0.25, + data: [ + [0, 2], + [5, 5], + [10, 8] + ] + }, combinedSeries); +}); var assertGraphExistence = function(g, graph) { assert.isNotNull(g); diff --git a/auto_tests/tests/range_tests.js b/auto_tests/tests/range_tests.js index 353edcce7..7a952d175 100644 --- a/auto_tests/tests/range_tests.js +++ b/auto_tests/tests/range_tests.js @@ -252,15 +252,6 @@ it('testHugeRange', function() { assert.closeTo(1, 1.1e230 / g.yAxisRange(0)[1], 0.001); }); -/** - * Verify old-style avoidMinZero option. - */ -it('testAvoidMinZero', function() { - var g = createGraph({ - avoidMinZero: true, - }, ZERO_TO_FIFTY_STEPS, [10, 20], [-5, 55]); -}); - /** * Verify ranges with user-specified padding, implicit avoidMinZero. */ @@ -342,24 +333,7 @@ it('testLogscalePad', function() { yRangePad: 30 }, [[-10, 10], [10, 10], [30, 1000]], - [-10, 30], [5.01691, 1993.25801]); -}); - -/** - * Verify scrolling all-zero region, traditional. - */ -it('testZeroScroll', function() { - var g = new Dygraph( - document.getElementById("graph"), - "X,Y\n" + - "1,0\n" + - "8,0\n" + - "9,0.1\n", - { - drawAxesAtZero: true, - animatedZooms: true, - avoidMinZero: true - }); + [-10, 30], [5.623, 1778.279]); }); /** diff --git a/auto_tests/tests/to_dom_coords.js b/auto_tests/tests/to_dom_coords.js index 454050115..e5bda3b19 100644 --- a/auto_tests/tests/to_dom_coords.js +++ b/auto_tests/tests/to_dom_coords.js @@ -225,6 +225,20 @@ it('testChartLogarithmic_YAxis', function() { assert.deepEqual([400, 0], g.toDomCoords(10, 4)); assert.deepEqual([400, 400], g.toDomCoords(10, 1)); assert.deepEqual([400, 200], g.toDomCoords(10, 2)); + + // Verify that the margins are adjusted appropriately for yRangePad. + g.updateOptions({yRangePad: 40}); + assertDeepCloseTo([0, 4], g.toDataCoords(0, 40), epsilon); + assertDeepCloseTo([0, 1], g.toDataCoords(0, 360), epsilon); + assertDeepCloseTo([10, 4], g.toDataCoords(400, 40), epsilon); + assertDeepCloseTo([10, 1], g.toDataCoords(400, 360), epsilon); + assertDeepCloseTo([10, 2], g.toDataCoords(400, 200), epsilon); + + assertDeepCloseTo([0, 40], g.toDomCoords(0, 4), epsilon); + assertDeepCloseTo([0, 360], g.toDomCoords(0, 1), epsilon); + assertDeepCloseTo([400, 40], g.toDomCoords(10, 4), epsilon); + assertDeepCloseTo([400, 360], g.toDomCoords(10, 1), epsilon); + assertDeepCloseTo([400, 200], g.toDomCoords(10, 2), epsilon); }); it('testChartLogarithmic_XAxis', function() { diff --git a/auto_tests/tests/xhr.js b/auto_tests/tests/xhr.js new file mode 100644 index 000000000..ba06e61a7 --- /dev/null +++ b/auto_tests/tests/xhr.js @@ -0,0 +1,68 @@ +/** + * @fileoverview Tests involving issuing XHRs for data. + * + * Note that these tests must be run with an HTTP server. + * XHRs can't be issued from file:/// URLs. + * This can be done with + * + * npm install http-server + * http-server + * open http://localhost:8080/auto_tests/runner.html + * + */ + +import Dygraph from '../../src/dygraph'; +import Util from './Util'; + +import 'core-js/es6/promise'; + +function dygraphPromise(div, data, opts) { + return new Promise((resolve, reject) => { + const g = new Dygraph(div, data, opts); + g.ready(() => resolve(g)); + }); +} + +describe("xhr", () => { + +it('should issue XHRs for CSV data', () => { + return dygraphPromise('graph', 'data/sample.csv').then(g => { + assert.isNotNull(g); + assert.equal(g.numRows(), 4); + assert.equal(g.numColumns(), 3); + }); +}); + +it('should warn on out-of-order CSV data', () => { + const calls = {}; + const restore = Util.captureConsole(calls); + return dygraphPromise('graph', 'data/out-of-order.csv').then(g => { + restore(); + assert.isNotNull(g); + assert.equal(g.numRows(), 4); + assert.equal(g.numColumns(), 3); + assert.equal(calls.warn.length, 1); + assert(/out of order/.exec(calls.warn[0])); + }, e => { + restore(); + return Promise.reject(e); + }); +}); + +it('should warn on out-of-order CSV data with dates', () => { + const calls = {}; + const restore = Util.captureConsole(calls); + return dygraphPromise('graph', 'data/out-of-order-dates.csv').then(g => { + restore(); + assert.isNotNull(g); + assert.equal(g.numRows(), 8); + assert.equal(g.numColumns(), 5); + assert.equal(calls.warn.length, 1); + assert(/out of order/.exec(calls.warn[0])); + }, e => { + restore(); + return Promise.reject(e); + }); +}); + +}); diff --git a/bower.json b/bower.json deleted file mode 100644 index 6ebcc5cda..000000000 --- a/bower.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "dygraphs", - "main": "dist/dygraph.js", - "ignore": [ - "Makefile", - "NOTES", - "auto_tests", - "common", - "data.js", - "docs", - "experimental", - "file-size-stats.sh", - "gadget.xml", - "gallery", - "generate-combined.sh", - "generate-documentation.py", - "generate-download.py", - "generate-jar.sh", - "generate-jsdoc.sh", - "gwt", - "jsTestDriver.conf", - "jsdoc-toolkit", - "lint.sh", - "node_modules", - "package.json", - "phantom-driver.js", - "phantom-perf.js", - "push-to-web.sh", - "release.sh", - "releases.json", - "screenshot.png", - "scripts", - "test.sh", - "tests", - "thumbnail.png" - ] -} diff --git a/css/dygraph.css b/css/dygraph.css new file mode 100644 index 000000000..75d58685f --- /dev/null +++ b/css/dygraph.css @@ -0,0 +1,117 @@ +/** + * Default styles for the dygraphs charting library. + */ + +.dygraph-legend { + position: absolute; + font-size: 14px; + z-index: 10; + width: 250px; /* labelsDivWidth */ + /* + dygraphs determines these based on the presence of chart labels. + It might make more sense to create a wrapper div around the chart proper. + top: 0px; + right: 2px; + */ + background: white; + line-height: normal; + text-align: left; + overflow: hidden; +} + +/* styles for a solid line in the legend */ +.dygraph-legend-line { + display: inline-block; + position: relative; + bottom: .5ex; + padding-left: 1em; + height: 1px; + border-bottom-width: 2px; + border-bottom-style: solid; + /* border-bottom-color is set based on the series color */ +} + +/* styles for a dashed line in the legend, e.g. when strokePattern is set */ +.dygraph-legend-dash { + display: inline-block; + position: relative; + bottom: .5ex; + height: 1px; + border-bottom-width: 2px; + border-bottom-style: solid; + /* border-bottom-color is set based on the series color */ + /* margin-right is set based on the stroke pattern */ + /* padding-left is set based on the stroke pattern */ +} + +.dygraph-roller { + position: absolute; + z-index: 10; +} + +/* This class is shared by all annotations, including those with icons */ +.dygraph-annotation { + position: absolute; + z-index: 10; + overflow: hidden; +} + +/* This class only applies to annotations without icons */ +/* Old class name: .dygraphDefaultAnnotation */ +.dygraph-default-annotation { + border: 1px solid black; + background-color: white; + text-align: center; +} + +.dygraph-axis-label { + /* position: absolute; */ + /* font-size: 14px; */ + z-index: 10; + line-height: normal; + overflow: hidden; + color: black; /* replaces old axisLabelColor option */ +} + +.dygraph-axis-label-x { +} + +.dygraph-axis-label-y { +} + +.dygraph-axis-label-y2 { +} + +.dygraph-title { + font-weight: bold; + z-index: 10; + text-align: center; + /* font-size: based on titleHeight option */ +} + +.dygraph-xlabel { + text-align: center; + /* font-size: based on xLabelHeight option */ +} + +/* For y-axis label */ +.dygraph-label-rotate-left { + text-align: center; + /* See http://caniuse.com/#feat=transforms2d */ + transform: rotate(90deg); + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -o-transform: rotate(90deg); + -ms-transform: rotate(90deg); +} + +/* For y2-axis label */ +.dygraph-label-rotate-right { + text-align: center; + /* See http://caniuse.com/#feat=transforms2d */ + transform: rotate(-90deg); + -webkit-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -o-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); +} diff --git a/docs/annotations.html b/docs/annotations.html index 0a3ba17c4..7a0c1e3ad 100644 --- a/docs/annotations.html +++ b/docs/annotations.html @@ -6,6 +6,9 @@ .annotation { font-size: 12px !important; } + .dygraph-legend { + width: 300px; + }

dygraphs Annotations

@@ -26,7 +29,6 @@

Demo: Dow Jones Industrial Average

showRoller: true, customBars: true, labelsKMB: true, - labelsDivWidth: 300 } ); @@ -192,6 +194,8 @@

Annotations property reference

heightHeight (in pixels) of the annotation flag or icon. cssClassCSS class to use for styling the annotation. tickHeightHeight of the tick mark (in pixels) connecting the point to its flag or icon. +tickWidthWidth of the tick mark connecting the point to its flag or icon. +tickColorColor of the tick mark connecting the point to its flag or icon. attachAtBottomIf true, attach annotations to the x-axis, rather than to actual points. clickHandler See Handlers, below mouseOverHandlerSee Handlers, below diff --git a/docs/header.html b/docs/header.html index 870c84c25..cc5881c49 100644 --- a/docs/header.html +++ b/docs/header.html @@ -6,9 +6,10 @@ + - + - + +

Here is another demonstration of +how to use dygraphs a GViz visualization. +

Charting Fractions

diff --git a/docs/users.html b/docs/users.html index 0f362c5a4..663036229 100644 --- a/docs/users.html +++ b/docs/users.html @@ -111,6 +111,17 @@

Known Users

+
  • + Ghanastocks.net
    + + Ghanastocks.net is a financial platform offering information on the stocks traded on the Ghana Stock Exchange. + Dygraphs is used to display the stock charts. On the front page a tiny preview graph with no interaction model and + labels is used, the quote pages uses a standard version of dygraphs and the detailed chart is displayed using two + dygraphs instances, one for the volume bars and one for the chart, which are synchronized through a custom highlight + callback. + +
  • +

    Are you using dygraphs? Please let Dan know and he'll add your link here!

    diff --git a/docs/versions.html b/docs/versions.html index e336eeabc..ef0491d63 100644 --- a/docs/versions.html +++ b/docs/versions.html @@ -27,22 +27,114 @@

    Version History

    For links to download each release, see the Downloads page.

    + + + + + + + + + + + + diff --git a/dygraph-externs.js b/dygraph-externs.js index 9cf956801..a9401e45e 100644 --- a/dygraph-externs.js +++ b/dygraph-externs.js @@ -40,7 +40,7 @@ Dygraph.prototype.isZoomed; /** @type {function(): string} */ Dygraph.prototype.toString; -/** @type {function(string, string)} */ +/** @type {function(string, string=)} */ Dygraph.prototype.getOption; /** @type {function(): number} */ @@ -59,7 +59,7 @@ Dygraph.prototype.yAxisRange; Dygraph.prototype.yAxisRanges; /** @type {function(?number, ?number, ?number): Array.} */ -Dygraph.prototype.toDomCoords +Dygraph.prototype.toDomCoords; /** @type {function(?number): ?number} */ Dygraph.prototype.toDomXCoord; @@ -127,7 +127,7 @@ Dygraph.prototype.isSeriesLocked; /** @type {function(): number} */ Dygraph.prototype.numAxes; -/** @type {function(Object, Boolean=)} */ +/** @type {function(Object, boolean=)} */ Dygraph.prototype.updateOptions; /** @type {function(number, number)} */ @@ -142,7 +142,7 @@ Dygraph.prototype.visibility; /** @type {function(number, boolean)} */ Dygraph.prototype.setVisibility; -/** @type {function(Array., boolean)} */ +/** @type {function(Array., boolean=)} */ Dygraph.prototype.setAnnotations; /** @type {function(): Array.} */ diff --git a/gallery/avoid-min-zero.js b/gallery/avoid-min-zero.js deleted file mode 100644 index e74345fd7..000000000 --- a/gallery/avoid-min-zero.js +++ /dev/null @@ -1,61 +0,0 @@ -/*global Gallery,Dygraph,data */ -Gallery.register( - 'avoid-min-zero', - { - name: "Avoid Min Zero", - setup: function(parent) { - parent.innerHTML = - "

    1: Line chart with axis at zero problem:

    " + - "

    2: Step chart with axis at zero problem:

    " + - "

    3: Line chart with avoidMinZero option:

    " + - "

    4: Step chart with avoidMinZero option:

    "; - }, - run: function() { - new Dygraph(document.getElementById("graph1"), - "Date,Temperature\n" + - "2008-05-07,0\n" + - "2008-05-08,1\n" + - "2008-05-09,0\n" + - "2008-05-10,0\n" + - "2008-05-11,3\n" + - "2008-05-12,4\n" - ); - new Dygraph(document.getElementById("graphd2"), - "Date,Temperature\n" + - "2008-05-07,0\n" + - "2008-05-08,1\n" + - "2008-05-09,0\n" + - "2008-05-10,0\n" + - "2008-05-11,3\n" + - "2008-05-12,4\n", - { - stepPlot: true - } - ); - new Dygraph(document.getElementById("graph3"), - "Date,Temperature\n" + - "2008-05-07,0\n" + - "2008-05-08,1\n" + - "2008-05-09,0\n" + - "2008-05-10,0\n" + - "2008-05-11,3\n" + - "2008-05-12,4\n", - { - avoidMinZero: true - } - ); - new Dygraph(document.getElementById("graphd4"), - "Date,Temperature\n" + - "2008-05-07,0\n" + - "2008-05-08,1\n" + - "2008-05-09,0\n" + - "2008-05-10,0\n" + - "2008-05-11,3\n" + - "2008-05-12,4\n", - { - stepPlot: true, - avoidMinZero: true - } - ); - } -}); diff --git a/gallery/border.js b/gallery/border.js index b5e4f6893..eacaf4681 100644 --- a/gallery/border.js +++ b/gallery/border.js @@ -6,12 +6,12 @@ Gallery.register( title: 'Graph stays within the border', setup: function(parent) { parent.innerHTML = + "" + "
    "; }, run: function() { new Dygraph(document.getElementById('bordered'), data, { - labelsDivStyles: { border: '1px solid black' }, title: 'Chart Title', xlabel: 'Date', ylabel: 'Temperature (F)' diff --git a/gallery/edge-padding.js b/gallery/edge-padding.js deleted file mode 100644 index be79054ba..000000000 --- a/gallery/edge-padding.js +++ /dev/null @@ -1,84 +0,0 @@ -/*global Gallery,Dygraph,data */ -Gallery.register( - 'edge-padding', - { - name: 'Edge Padding', - title: 'Graph edge padding and axis position', - setup: function(parent) { - parent.innerHTML = ( - "

    " + - " Mode:" + - " use {x,y}RangePad" + - " original" + - "
    Settings:" + - " valueRange=[-2,2]" + - "

    " + - "
    " - ); - }, - run: function() { - var parent = document.getElementById("demodiv"); - - var graphs = []; - var nrows = 50; - - for (var oy = -2; oy <= 2; ++oy) { - for (var ox = -1; ox <= 1; ++ox) { - var gdiv = document.createElement('div'); - gdiv.style.display = 'inline-block'; - gdiv.style.margin = '2px'; - parent.appendChild(gdiv); - - var data = []; - for (var row = 0; row < nrows; ++row) { - var x = row * 5 / (nrows - 1); - data.push([ox * 2.5 + x - 2.5, - oy + Math.sin(x), - oy + Math.round(Math.cos(x))]); - } - - var g = new Dygraph(gdiv, data, { - labels: ['x', 'A', 'B'], - labelsDivWidth: 100, - gridLineColor: '#ccc', - includeZero: true, - width: 250, - height: 130 - }); - graphs.push(g); - } - parent.appendChild(document.createElement('br')); - } - - var updateGraphOpts = function(opts) { - for (var i = 0; i < graphs.length; ++i) { - graphs[i].updateOptions(opts); - } - }; - - var mode = document.getElementsByName('mode'); - mode[0].onchange = function() { - updateGraphOpts({ - avoidMinZero: false, - xRangePad: 3, - yRangePad: 10, - drawAxesAtZero: true}); - }; - mode[1].onchange = function() { - updateGraphOpts({ - avoidMinZero: true, - xRangePad: 0, - yRangePad: null, - drawAxesAtZero: false}); - }; - mode[0].checked = true; - mode[0].onchange(); - - var yrange = document.getElementById('yrange'); - yrange.onchange = function(ev) { - updateGraphOpts({ - valueRange: ev.target.checked ? [-2, 2] : null}); - }; - - } - }); diff --git a/gallery/gallery.css b/gallery/gallery.css index df899dfb4..2febc685f 100644 --- a/gallery/gallery.css +++ b/gallery/gallery.css @@ -122,7 +122,7 @@ a { position: absolute; left: 200px; right: 10px; - top: 100px; + top: 150px; bottom: 10px; } diff --git a/gallery/gallery.js b/gallery/gallery.js index f8b4ceea1..9f7e79b40 100644 --- a/gallery/gallery.js +++ b/gallery/gallery.js @@ -89,7 +89,7 @@ Gallery.start = function() { jsfs.html("\n" + "\n" + - "\n" + + "\n" + "\n"); var javascript = demo.run.toString(); diff --git a/gallery/index.html b/gallery/index.html index c953deb37..6d546b0a0 100644 --- a/gallery/index.html +++ b/gallery/index.html @@ -2,6 +2,7 @@ Dygraphs Gallery + @@ -32,14 +33,12 @@ - diff --git a/tests/annotation-native.html b/tests/annotation-native.html index a00349706..53ce249e3 100644 --- a/tests/annotation-native.html +++ b/tests/annotation-native.html @@ -1,6 +1,7 @@ + Native format annotations diff --git a/tests/annotation.html b/tests/annotation.html index 6d477e235..c180070ff 100644 --- a/tests/annotation.html +++ b/tests/annotation.html @@ -1,14 +1,8 @@ + demo - - @@ -21,7 +21,6 @@ diff --git a/tests/century-scale.html b/tests/century-scale.html index 8423715fc..b74bee8bf 100644 --- a/tests/century-scale.html +++ b/tests/century-scale.html @@ -1,11 +1,8 @@ + demo - diff --git a/tests/charting-combinations.html b/tests/charting-combinations.html index 8f2ecaf64..2722b87ee 100644 --- a/tests/charting-combinations.html +++ b/tests/charting-combinations.html @@ -1,6 +1,7 @@ + Charting combinations diff --git a/tests/color-cycle.html b/tests/color-cycle.html index 53da50399..1d8182f5a 100644 --- a/tests/color-cycle.html +++ b/tests/color-cycle.html @@ -1,11 +1,8 @@ + color cycles - diff --git a/tests/color-visibility.html b/tests/color-visibility.html index c0e6941db..36a602b46 100644 --- a/tests/color-visibility.html +++ b/tests/color-visibility.html @@ -1,11 +1,8 @@ + color visibility - diff --git a/tests/connect-separated.html b/tests/connect-separated.html index ef6034d7f..32de8b19b 100644 --- a/tests/connect-separated.html +++ b/tests/connect-separated.html @@ -1,11 +1,8 @@ + connect separated - diff --git a/tests/crosshair.html b/tests/crosshair.html index 25eb8d8b8..3bac26434 100644 --- a/tests/crosshair.html +++ b/tests/crosshair.html @@ -1,11 +1,8 @@ + crosshairs - diff --git a/tests/css-positioning.html b/tests/css-positioning.html index 2db8d6966..add2393d0 100644 --- a/tests/css-positioning.html +++ b/tests/css-positioning.html @@ -1,6 +1,7 @@ + demo

    Labels are styled with css3:

    @@ -20,14 +27,6 @@ NoisyData, { rollPeriod: 14, errorBars: true, - labelsDivWidth: 100, - labelsDivStyles: { - 'backgroundColor': 'rgba(200, 200, 255, 0.75)', - 'padding': '4px', - 'border': '1px solid black', - 'borderRadius': '10px', - 'boxShadow': '4px 4px 4px #888' - }, labelsSeparateLines: true, axes: { y: { diff --git a/tests/dashed-canvas.html b/tests/dashed-canvas.html deleted file mode 100644 index c80b3fcd7..000000000 --- a/tests/dashed-canvas.html +++ /dev/null @@ -1,58 +0,0 @@ - - -

    You should see solid black and blue lines with a dashed red line in between -them:

    - - -

    You should see a solid black line:

    - - - - - diff --git a/tests/dateWindow.html b/tests/dateWindow.html index 96926e4f5..7deb861a6 100644 --- a/tests/dateWindow.html +++ b/tests/dateWindow.html @@ -1,11 +1,8 @@ + dateWindow - diff --git a/tests/daylight-savings.html b/tests/daylight-savings.html index b52a65491..0c3ab24eb 100644 --- a/tests/daylight-savings.html +++ b/tests/daylight-savings.html @@ -1,11 +1,8 @@ + Daylight Savings -
    diff --git a/tests/logscale.html b/tests/logscale.html index fda64ddc5..4a81a5070 100644 --- a/tests/logscale.html +++ b/tests/logscale.html @@ -1,11 +1,8 @@ + log scale - diff --git a/tests/missing-data.html b/tests/missing-data.html index f337de53e..d48237c69 100644 --- a/tests/missing-data.html +++ b/tests/missing-data.html @@ -1,11 +1,8 @@ + missing data - diff --git a/tests/multi-scale.html b/tests/multi-scale.html index 478111bdb..45eb9890d 100644 --- a/tests/multi-scale.html +++ b/tests/multi-scale.html @@ -1,6 +1,7 @@ + multi-scale @@ -61,7 +73,6 @@

    Range selector options

    title: 'Daily Temperatures in New York vs. San Francisco', ylabel: 'Temperature (F)', legend: 'always', - labelsDivStyles: { 'textAlign': 'right' }, showRangeSelector: true } ); @@ -75,7 +86,6 @@

    Range selector options

    title: 'Daily Temperatures in New York vs. San Francisco', ylabel: 'Temperature (F)', legend: 'always', - labelsDivStyles: { 'textAlign': 'right' }, xAxisHeight: 14, showRangeSelector: true, rangeSelectorHeight: 80, @@ -133,11 +143,9 @@

    Range selector options

    title: 'Nightly Temperatures in NY vs. SF', ylabel: 'Temperature (F)', legend: 'always', - labelsDivStyles: { 'textAlign': 'right', 'backgroundColor': '#101015' }, showRangeSelector: true, rangeSelectorPlotFillColor: 'MediumSlateBlue', rangeSelectorPlotFillGradientColor: 'rgba(123, 104, 238, 0)', - axisLabelColor: 'white', colorValue: 0.9, fillAlpha: 0.4 } @@ -152,10 +160,8 @@

    Range selector options

    title: 'Nightly Temperatures in NY vs. SF', ylabel: 'Temperature (F)', legend: 'always', - labelsDivStyles: { 'textAlign': 'right', 'backgroundColor': '#101015' }, showRangeSelector: true, rangeSelectorPlotFillColor: 'MediumSlateBlue', - axisLabelColor: 'white', colorValue: 0.9, fillAlpha: 0.4 } diff --git a/tests/resize.html b/tests/resize.html index bbc120dc9..8381bf7b7 100644 --- a/tests/resize.html +++ b/tests/resize.html @@ -1,11 +1,8 @@ + resize the window - diff --git a/tests/reverse-y-axis.html b/tests/reverse-y-axis.html index 253a9f707..c64c3d540 100644 --- a/tests/reverse-y-axis.html +++ b/tests/reverse-y-axis.html @@ -1,11 +1,8 @@ + reverse y-axis - diff --git a/tests/series-highlight.html b/tests/series-highlight.html index 6abb715bb..299e0e436 100644 --- a/tests/series-highlight.html +++ b/tests/series-highlight.html @@ -1,11 +1,8 @@ + Series highlighting - @@ -50,10 +51,6 @@ titleHeight: 32, ylabel: 'Temperature (F)', xlabel: 'Date (Ticks indicate the start of the indicated time period)', - labelsDivStyles: { - 'text-align': 'right', - 'background': 'none' - }, strokeWidth: 1.5 } ); @@ -66,10 +63,6 @@ title: 'High and Low Temperatures (30-day average)', ylabel: 'Temperature (F)', xlabel: 'Date (Ticks indicate the start of the indicated time period)', - labelsDivStyles: { - 'text-align': 'right', - 'background': 'none' - }, strokeWidth: 1.5 } ); diff --git a/tests/synchronize.html b/tests/synchronize.html index c14ef64b4..b3fe62828 100644 --- a/tests/synchronize.html +++ b/tests/synchronize.html @@ -1,11 +1,8 @@ + synchronize - diff --git a/tests/temperature-sf-ny.html b/tests/temperature-sf-ny.html index b5cfef1e0..45d1feb64 100644 --- a/tests/temperature-sf-ny.html +++ b/tests/temperature-sf-ny.html @@ -1,11 +1,8 @@ + Temperatures - @@ -13,6 +10,9 @@ #bordered { border: 1px solid red; } + .dygraph-legend { + text-align: right; + } @@ -34,7 +34,6 @@ title: 'Daily Temperatures in New York vs. San Francisco', ylabel: 'Temperature (F)', legend: 'always', - labelsDivStyles: { 'textAlign': 'right' } } ); g2 = new Dygraph( @@ -47,7 +46,6 @@ title: 'Daily Temperatures in New York vs. San Francisco', ylabel: 'Temperature (F)', legend: 'always', - labelsDivStyles: { 'textAlign': 'right' } } ); diff --git a/tests/two-axes-vr.html b/tests/two-axes-vr.html index b714b36e0..7a32ad330 100644 --- a/tests/two-axes-vr.html +++ b/tests/two-axes-vr.html @@ -1,11 +1,8 @@ + Multiple y-axes with valueRange - diff --git a/tests/two-axes.html b/tests/two-axes.html index f652389be..fd3f9d8b9 100644 --- a/tests/two-axes.html +++ b/tests/two-axes.html @@ -1,11 +1,8 @@ + Multiple y-axes - diff --git a/tests/unboxed-spark.html b/tests/unboxed-spark.html index 2713467f1..e6b142466 100644 --- a/tests/unboxed-spark.html +++ b/tests/unboxed-spark.html @@ -1,11 +1,8 @@ + dygraphs unboxed - diff --git a/tests/underlay-callback.html b/tests/underlay-callback.html index 11b276476..10122ed89 100644 --- a/tests/underlay-callback.html +++ b/tests/underlay-callback.html @@ -1,11 +1,8 @@ + Custom underlay callback - diff --git a/tests/value-axis-formatters.html b/tests/value-axis-formatters.html index 31d61ea2d..f69c99da5 100644 --- a/tests/value-axis-formatters.html +++ b/tests/value-axis-formatters.html @@ -1,11 +1,8 @@ + valueFormatter and axisLabelFormatter - diff --git a/tests/visibility.html b/tests/visibility.html index 43b73a55e..c6ef1e7af 100644 --- a/tests/visibility.html +++ b/tests/visibility.html @@ -1,11 +1,8 @@ + visibility - diff --git a/tests/x-axis-formatter.html b/tests/x-axis-formatter.html index ef884e374..3f8f01ce8 100644 --- a/tests/x-axis-formatter.html +++ b/tests/x-axis-formatter.html @@ -1,11 +1,8 @@ + X Axis Label Formatting - diff --git a/tests/zero-series.html b/tests/zero-series.html index 72c4baa0d..cc8e8cd09 100644 --- a/tests/zero-series.html +++ b/tests/zero-series.html @@ -1,11 +1,8 @@ + zero series - diff --git a/tests/zoom.html b/tests/zoom.html index afc39a3a0..f53eab08e 100644 --- a/tests/zoom.html +++ b/tests/zoom.html @@ -1,11 +1,8 @@ + zoom - @@ -50,13 +47,13 @@

    Window coordinates (in dates and values):

    document.getElementById("div_g"), NoisyData, { errorBars: true, - zoomCallback : function(minDate, maxDate, yRange) { + zoomCallback: function(minDate, maxDate, yRange) { showDimensions(minDate, maxDate, yRange); }, - drawCallback: function(me, initial) { - document.getElementById("zoomed").innerHTML = "" + me.isZoomed(); - document.getElementById("zoomedX").innerHTML = "" + me.isZoomed("x"); - document.getElementById("zoomedY").innerHTML = "" + me.isZoomed("y"); + drawCallback: function() { + document.getElementById("zoomed").innerHTML = "" + this.isZoomed(); + document.getElementById("zoomedX").innerHTML = "" + this.isZoomed("x"); + document.getElementById("zoomedY").innerHTML = "" + this.isZoomed("y"); } } );
    2.1.0

    2017-12-08

    + New features: +
      +
    • Double click event can be captured and cancelled by plugins
    • +
    • setAnnotations's second parameter is now an optional boolean
    • +
    • Add `pixelRatio` option, which may allow improved performance on smaller screens by controlling the canvas' pixel ratio
    • +
    • X-axis label and tick logic can now operate at millisecond-level granularity
    • +
    + + Bug fixes: +
      +
    • Repair a bug in "Custom interaction modals" demo
    • +
    + + Internal refactors/fixes: +
      +
    • Fix various spelling mistakes
    • +
    • Fix a couple of type signatures in dygraph-externs.js
    • +
    +
    2.0.0

    2017-01-11

    + Breaking changes: +
      +
    • JS files were renamed to dygraph.js and dygraph.min.js.
    • +
    • There's now a dygraph.css file that you must include.
    • +
    • Dropped support for OldIE and other non-standard browsers. dygraphs works in IE11. I'm not sure about IE9 and IE10.
    • +
    • Double-click to unzoom zooms all the way out (and ignores valueRange).
    • +
    • Dropped old-style per-axis/per-series options.
    • +
    + + New features: +
      +
    • Add a legendFormatter option
    • +
    • `this` is the Dygraph object in all callbacks
    • +
    • pass through (row, col) to valueFormatter
    • +
    • Option to not sync range in extras/synchronizer.js
    • +
    • Additional options for styling the range selector
    • +
    • getRowForX method
    • +
    • setVisibility can set the visibility of multiple series at once.
    • +
    • crosshair plugin extra
    • +
    • rebase/straw broom plugin
    • +
    • highlightSeriesBackgroundColor option
    • +
    • yAxisExtremes() method.
    • +
    • Passing strings in native format now throws. (Previously it kinda sorta worked.)
    • +
    + + Bug fixes: +
      +
    • Selections are always cleared with animations
    • +
    • synchronizer calls previously-set callbacks
    • +
    • synchronizer only syncs when graphs are ready
    • +
    • Reset on synchronized graphs failed
    • +
    • fix to improve synchronizer performance
    • +
    • binary search bug fix in synchronizer
    • +
    • Fix range selection when chart is located inside fullscreen element
    • +
    • fillAlpha can be set per-series when fillGraph is set.
    • +
    • xRangePad was ignored on unzoom
    • +
    • Allow selected points where canvas-y coordinate is 0
    • +
    • Using valueRange with Logscale and yRangePad has unexpected results
    • +
    • With "drawGapEdgePoints", unwanted point often drawn at beginning of chart
    • +
    + + Other user-visible changes: +
      +
    • “legend: follow” positioning changes
    • +
    + + Internal refactors: +
      +
    • Code moved into a “src/“ directory
    • +
    • Tests use Mocha instead of jstd
    • +
    • dygraphs is split into ES6 modules and uses some ES6 features (e.g. arrows and destructuring).
    • +
    • dygraphs is built using babel & browserify
    • +
    • Code coverage is tracked continuously
    • +
    • Bundle size is now tracked continuously
    • +
    +
    1.1.1

    2015-06-01

    +
      +
    • Set this to the dygraph in all callbacks.
    • +
    • Minor bug fixes.
    • +
    +
    1.1.0

    2014-12-03

    Highlights include:
      -
    • dygraphs is now "retina" compatible. -
    • Dramatically improved performance for filled charts (i.e. fillGraph) -
    • More sensible date ticks: "Jan 08"→"Jan 2008", "29Jan"→"29 Jan" -
    • Using a non-existent option now throws (w/ dygraph-combined-dev.js) -
    • x-axis log scales -
    • The labelsUTC option forces UTC formatting for all labels. -
    • The new DataHandler system allows for more flexibility in data loading. -
    • "this" is set to the dygraph in all callbacks. -
    • dygraphs has shrunk, because we moved some stuff into "extras" (133kb→122kb) -
    - +
  • dygraphs is now "retina" compatible.
  • +
  • Dramatically improved performance for filled charts (i.e. fillGraph)
  • +
  • More sensible date ticks: "Jan 08"→"Jan 2008", "29Jan"→"29 Jan"
  • +
  • Using a non-existent option now throws (w/ dygraph-combined-dev.js)
  • +
  • x-axis log scales
  • +
  • The labelsUTC option forces UTC formatting for all labels.
  • +
  • The new DataHandler system allows for more flexibility in data loading.
  • +
  • "this" is set to the dygraph in all callbacks.
  • +
  • dygraphs has shrunk, because we moved some stuff into "extras" (133kb→122kb)
  • + + This will be the last major release to support browsers without a native <canvas> implementation. See blog post for more details.