+ assertGraphExistence(g, graph);
+});
+
+it('testAdditionalRangeSelectorOptions', function() {
+ var opts = {
+ width: 480,
+ height: 320,
+ showRangeSelector: true,
+ rangeSelectorHeight: 30,
+ rangeSelectorBackgroundStrokeColor: 'blue',
+ rangeSelectorBackgroundLineWidth: 3,
+ rangeSelectorPlotLineWidth: 0.5,
+ rangeSelectorForegroundStrokeColor: 'red',
+ rangeSelectorForegroundLineWidth: 2,
+ rangeSelectorAlpha: 0.8,
+ labels: ['X', 'Y']
+ };
+ var data = [
+ [1, 10],
+ [2, 15],
+ [3, 10],
+ [4, 15],
+ [5, 10],
+ [6, 15],
+ [7, 10],
+ [8, 15],
+ [9, 10]
+ ];
+ var graph = document.getElementById("graph");
+ var g = new Dygraph(graph, data, opts);
+ assertGraphExistence(g, graph);
+});
+
+it('testRangeSelectorEnablingAfterCreation', function() {
+ var opts = {
+ width: 480,
+ height: 320,
+ labels: ['X', 'Y']
+ };
+ var data = [
+ [1, 10],
+ [2, 15],
+ [3, 10],
+ [4, 15],
+ [5, 10],
+ [6, 15],
+ [7, 10],
+ [8, 15],
+ [9, 10]
+ ];
+ var graph = document.getElementById("graph");
+ var g = new Dygraph(graph, data, opts);
+ g.updateOptions({showRangeSelector: true});
+ assertGraphExistence(g, graph);
+});
+
+// The animatedZooms option does not work with the range selector. Make sure it gets turned off.
+it('testRangeSelectorWithAnimatedZoomsOption', function() {
+ var opts = {
+ width: 480,
+ height: 320,
+ showRangeSelector: true,
+ animatedZooms: true,
+ labels: ['X', 'Y']
+ };
+ var data = [
+ [1, 10],
+ [2, 15],
+ [3, 10],
+ [4, 15],
+ [5, 10],
+ [6, 15],
+ [7, 10],
+ [8, 15],
+ [9, 10]
+ ];
+ var graph = document.getElementById("graph");
+ var g = new Dygraph(graph, data, opts);
+ assertGraphExistence(g, graph);
+ assert.isFalse(g.getOption('animatedZooms'));
+});
+
+it('testRangeSelectorWithAnimatedZoomsOption2', function() {
+ var opts = {
+ width: 480,
+ height: 320,
+ animatedZooms: true,
+ labels: ['X', 'Y']
+ };
+ var data = [
+ [1, 10],
+ [2, 15],
+ [3, 10],
+ [4, 15],
+ [5, 10],
+ [6, 15],
+ [7, 10],
+ [8, 15],
+ [9, 10]
+ ];
+ var graph = document.getElementById("graph");
+ var g = new Dygraph(graph, data, opts);
+ g.updateOptions({showRangeSelector: true});
+ assertGraphExistence(g, graph);
+ assert.isFalse(g.getOption('animatedZooms'));
+});
+
+it('testRangeSelectorInteraction', function() {
+ var opts = {
+ width: 480,
+ height: 320,
+ showRangeSelector: true,
+ labels: ['X', 'Y']
+ };
+ var data = [
+ [1, 10],
+ [2, 15],
+ [3, 10],
+ [4, 15],
+ [5, 10],
+ [6, 15],
+ [7, 10],
+ [8, 15],
+ [9, 10]
+ ];
+ var graph = document.getElementById("graph");
+ var g = new Dygraph(graph, data, opts);
+ assertGraphExistence(g, graph);
+ var zoomhandles = graph.getElementsByClassName('dygraph-rangesel-zoomhandle');
+
+ // Move left zoomhandle in
+ var xRange = g.xAxisRange().slice();
+
+ var mouseDownEvent = DygraphOps.createEvent({
+ type : 'dragstart',
+ detail: 1,
+ clientX : 0,
+ clientY : 0
+ });
+ zoomhandles[0].dispatchEvent(mouseDownEvent);
+
+ var mouseMoveEvent = DygraphOps.createEvent({
+ type : 'mousemove',
+ clientX : 20,
+ clientY : 20
+ });
+ zoomhandles[0].dispatchEvent(mouseMoveEvent);
+
+ var mouseUpEvent = DygraphOps.createEvent({
+ type : 'mouseup',
+ detail: 1,
+ clientX : 20,
+ clientY : 20
+ });
+ zoomhandles[0].dispatchEvent(mouseUpEvent);
+
+ var newXRange = g.xAxisRange().slice();
+ assert('left zoomhandle should have moved: '+newXRange[0]+'>'+xRange[0], newXRange[0] > xRange[0]);
+ assert.equal(xRange[1], newXRange[1], 'right zoomhandle should not have moved');
+
+ // Move right zoomhandle in
+ xRange = newXRange;
+
+ mouseDownEvent = DygraphOps.createEvent({
+ type : 'dragstart',
+ detail: 1,
+ clientX : 100,
+ clientY : 100
+ });
+ zoomhandles[1].dispatchEvent(mouseDownEvent);
+
+ mouseMoveEvent = DygraphOps.createEvent({
+ type : 'mousemove',
+ clientX : 80,
+ clientY : 80
+ });
+ zoomhandles[1].dispatchEvent(mouseMoveEvent);
+
+ mouseUpEvent = DygraphOps.createEvent({
+ type : 'mouseup',
+ detail: 1,
+ clientX : 80,
+ clientY : 80
+ });
+ zoomhandles[1].dispatchEvent(mouseUpEvent);
+
+ var newXRange = g.xAxisRange().slice();
+ assert(newXRange[1] < xRange[1], 'right zoomhandle should have moved: '+newXRange[1]+'<'+xRange[1]);
+ assert.equal(xRange[0], newXRange[0], 'left zoomhandle should not have moved');
+
+ // Pan left
+ xRange = newXRange;
+ var fgcanvas = graph.getElementsByClassName('dygraph-rangesel-fgcanvas')[0];
+ var x = parseInt(zoomhandles[0].style.left) + 20;
+ var y = parseInt(zoomhandles[0].style.top);
+
+ mouseDownEvent = DygraphOps.createEvent({
+ type : 'mousedown',
+ detail: 1,
+ clientX : x,
+ clientY : y
+ });
+ fgcanvas.dispatchEvent(mouseDownEvent);
+
+ x -= 10;
+
+ mouseMoveEvent = DygraphOps.createEvent({
+ type : 'mousemove',
+ clientX : x,
+ clientY : y
+ });
+ fgcanvas.dispatchEvent(mouseMoveEvent);
+
+ mouseUpEvent = DygraphOps.createEvent({
+ type : 'mouseup',
+ detail: 1,
+ clientX : x,
+ clientY : y
+ });
+ fgcanvas.dispatchEvent(mouseUpEvent);
+
+ var newXRange = g.xAxisRange().slice();
+ assert(newXRange[0]+'<'+xRange[0], newXRange[0] < xRange[0]);
+ assert(newXRange[1]+'<'+xRange[1], newXRange[1] < xRange[1]);
+});
+
+
+it('testRangeSelectorPositionIfXAxisNotDrawn', function() {
+ var opts = {
+ width: 480,
+ height: 100,
+ xAxisHeight: 30,
+ axes : { x : { drawAxis: false }},
+ showRangeSelector: true,
+ rangeSelectorHeight: 30,
+ labels: ['X', 'Y']
+ };
+ var data = [
+ [0, 1],
+ [10, 1]
+ ];
+ var graph = document.getElementById("graph");
+ var g = new Dygraph(graph, data, opts);
+
+ //assert, that the range selector is at top position 70 since the 30px of the
+ // xAxis shouldn't be reserved since it isn't drawn.
+ assertGraphExistence(g, graph);
+ var bgcanvas = graph.getElementsByClassName('dygraph-rangesel-bgcanvas')[0];
+ assert.equal("70px", bgcanvas.style.top, "Range selector is not at the expected position.");
+ var fgcanvas = graph.getElementsByClassName('dygraph-rangesel-fgcanvas')[0];
+ assert.equal("70px", fgcanvas.style.top, "Range selector is not at the expected position.");
+});
+
+it('testMiniPlotDrawn', function() {
+ // Install Proxy to track canvas calls.
+ var origFunc = Dygraph.getContext;
+ var miniHtx;
+ Dygraph.getContext = function(canvas) {
+ console.log(canvas.className);
+ if (canvas.className != 'dygraph-rangesel-bgcanvas') {
+ return origFunc(canvas);
+ }
+ miniHtx = new Proxy(origFunc(canvas));
+ return miniHtx;
+ };
+
+ var opts = {
+ width: 480,
+ height: 100,
+ xAxisHeight: 30,
+ axes : { x : { drawAxis: false }},
+ showRangeSelector: true,
+ rangeSelectorHeight: 30,
+ rangeSelectorPlotStrokeColor: '#ff0000',
+ labels: ['X', 'Y']
+ };
+ var data = [
+ [0, 1],
+ [5, 4],
+ [10, 8]
+ ];
+ var graph = document.getElementById("graph");
+ var g = new Dygraph(graph, data, opts);
+
+ // TODO(danvk): more precise tests.
+ assert.isNotNull(miniHtx);
+ assert.isTrue(0 < CanvasAssertions.numLinesDrawn(miniHtx, '#ff0000'));
+
+ Dygraph.getContext = origFunc;
+});
+
+// Tests data computation for the mini plot with a single series.
+it('testSingleCombinedSeries', function() {
+ var opts = {
+ showRangeSelector: true,
+ labels: ['X', 'Y1']
+ };
+ var data = [
+ [0, 1],
+ [5, 4],
+ [10, 8]
+ ];
+ var graph = document.getElementById("graph");
+ var g = new Dygraph(graph, data, opts);
+
+ var rangeSelector = g.getPluginInstance_(Dygraph.Plugins.RangeSelector);
+ assert.isNotNull(rangeSelector);
+
+ var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
+ assert.deepEqual({
+ yMin: 1 - 7 * 0.25, // 25% padding
+ yMax: 8 + 7 * 0.25,
+ data: [
+ [0, 1],
+ [5, 4],
+ [10, 8]
+ ]
+ }, combinedSeries);
+});