dcos-dygraphs
Version:
dygraphs is a fast, flexible open source JavaScript charting library.
645 lines (581 loc) • 17 kB
JavaScript
// Copyright 2011 Google Inc. All Rights Reserved.
/**
* @fileoverview Regression tests for range selector.
* @author paul.eric.felix@gmail.com (Paul Felix)
*/
import Dygraph from '../../src/dygraph';
import * as utils from '../../src/dygraph-utils';
import RangeSelectorPlugin from '../../src/plugins/range-selector';
import Util from './Util';
import DygraphOps from './DygraphOps';
import CanvasAssertions from './CanvasAssertions';
import Proxy from './Proxy';
describe("range-selector", function() {
cleanupAfterEach();
var restoreConsole;
var logs = {};
beforeEach(function() {
restoreConsole = Util.captureConsole(logs);
});
afterEach(function() {
restoreConsole();
});
it('testRangeSelector', function() {
var opts = {
width: 480,
height: 320,
showRangeSelector: true,
labels: ['X', 'Y']
};
var data = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
assertGraphExistence(g, graph);
});
it('testRangeSelectorWithErrorBars', function() {
var opts = {
width: 480,
height: 320,
errorBars: true,
showRangeSelector: true,
labels: ['X', 'Y']
};
var data = [
[]],
[]],
[]],
[]],
[]],
[]],
[]],
[]],
[]]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
assertGraphExistence(g, graph);
});
it('testRangeSelectorWithCustomBars', function() {
var opts = {
width: 480,
height: 320,
customBars: true,
showRangeSelector: true,
labels: ['X', 'Y']
};
var data = [
[]],
[]],
[]],
[]],
[]],
[]],
[]],
[]],
[]]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
assertGraphExistence(g, graph);
});
it('testRangeSelectorWithLogScale', function() {
var opts = {
width: 480,
height: 320,
logscale: true,
showRangeSelector: true,
labels: ['X', 'Y']
};
var data = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
assertGraphExistence(g, graph);
});
it('testRangeSelectorOptions', function() {
var opts = {
width: 480,
height: 320,
showRangeSelector: true,
rangeSelectorHeight: 30,
rangeSelectorPlotFillColor: 'lightyellow',
rangeSelectorPlotFillGradientColor: 'rgba(200, 200, 42, 10)',
labels: ['X', 'Y']
};
var data = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
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 = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
];
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 = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
var initialChartHeight = g.getArea().h;
g.updateOptions({showRangeSelector: true});
assertGraphExistence(g, graph);
assert(g.getArea().h < initialChartHeight); // range selector shown
g.updateOptions({showRangeSelector: false});
assert.equal(g.getArea().h, initialChartHeight); // range selector hidden
});
// 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 = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
assertGraphExistence(g, graph);
assert.isFalse(g.getOption('animatedZooms'));
assert.deepEqual(logs, {
log: [], error: [],
warn: ["Animated zooms and range selector are not compatible; disabling animatedZooms."]
});
});
it('testRangeSelectorWithAnimatedZoomsOption2', function() {
var opts = {
width: 480,
height: 320,
animatedZooms: true,
labels: ['X', 'Y']
};
var data = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
g.updateOptions({showRangeSelector: true});
assertGraphExistence(g, graph);
assert.isFalse(g.getOption('animatedZooms'));
assert.deepEqual(logs, {
log: [], error: [],
warn: ["Animated zooms and range selector are not compatible; disabling animatedZooms."]
});
});
it('testRangeSelectorInteraction', function() {
var opts = {
width: 480,
height: 320,
showRangeSelector: true,
labels: ['X', 'Y']
};
var data = [
[],
[],
[],
[],
[],
[],
[],
[],
[]
];
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(newXRange[0] > xRange[0], 'left zoomhandle should have moved: '+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 = [
[],
[]
];
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 = utils.getContext;
var miniHtx;
utils.getContext = function(canvas) {
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 = [
[],
[],
[]
];
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'));
utils.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 = [
[],
[],
[]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
var rangeSelector = g.getPluginInstance_(RangeSelectorPlugin);
assert.isNotNull(rangeSelector);
var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
assert.deepEqual({
yMin: 1 - 7 * 0.25, // 25% padding
yMax: 8 + 7 * 0.25,
data: [
[],
[],
[]
]
}, combinedSeries);
});
// Tests that multiple series are averaged for the miniplot.
it('testCombinedSeries', function() {
var opts = {
showRangeSelector: true,
labels: ['X', 'Y1', 'Y2']
};
var data = [
[], // average = 2
[], // average = 5
[] // average = 8
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
var rangeSelector = g.getPluginInstance_(RangeSelectorPlugin);
assert.isNotNull(rangeSelector);
var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
assert.deepEqual({
yMin: 2 - 6 * 0.25, // 25% padding on combined series range.
yMax: 8 + 6 * 0.25,
data: [
[],
[],
[]
]
}, combinedSeries);
});
// Tests selection of a specific series to average for the mini plot.
it('testSelectedCombinedSeries', function() {
var opts = {
showRangeSelector: true,
labels: ['X', 'Y1', 'Y2', 'Y3', 'Y4'],
series: {
'Y1': { showInRangeSelector: true },
'Y3': { showInRangeSelector: true }
}
};
var data = [
[], // average (first and third) = 9
[], // average (first and third) = 4
[] // average (first and third) = 5
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
var rangeSelector = g.getPluginInstance_(RangeSelectorPlugin);
assert.isNotNull(rangeSelector);
var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
assert.deepEqual({
yMin: 4 - 5 * 0.25, // 25% padding on combined series range.
yMax: 9 + 5 * 0.25,
data: [
[],
[],
[]
]
}, combinedSeries);
});
// Tests data computation for the mini plot with a single error bar series.
it('testSingleCombinedSeriesCustomBars', function() {
var opts = {
customBars: true,
showRangeSelector: true,
labels: ['X', 'Y1']
};
var data = [
[]], // [low, value, high]
[]],
[]]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
var rangeSelector = g.getPluginInstance_(RangeSelectorPlugin);
assert.isNotNull(rangeSelector);
var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
assert.deepEqual({
yMin: 1 - 7 * 0.25, // 25% padding
yMax: 8 + 7 * 0.25,
data: [
[],
[],
[]
]
}, combinedSeries);
});
it('testSingleCombinedSeriesErrorBars', function() {
var opts = {
errorBars: true,
showRangeSelector: true,
labels: ['X', 'Y1']
};
var data = [
[]], // [value, standard deviation]
[]],
[]]
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
var rangeSelector = g.getPluginInstance_(RangeSelectorPlugin);
assert.isNotNull(rangeSelector);
var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
assert.deepEqual({
yMin: 1 - 7 * 0.25, // 25% padding
yMax: 8 + 7 * 0.25,
data: [
[],
[],
[]
]
}, combinedSeries);
});
// Tests data computation for the mini plot with two custom bar series.
it('testTwoCombinedSeriesCustomBars', function() {
var opts = {
customBars: true,
showRangeSelector: true,
labels: ['X', 'Y1', 'Y2']
};
var data = [
[], [4, 5, 6]], // [low, value, high], avg_val = 3
[], [5, 8, 9]], // avg_val = 6
[], [11, 12, 13]] // avg_val = 10
];
var graph = document.getElementById("graph");
var g = new Dygraph(graph, data, opts);
var rangeSelector = g.getPluginInstance_(RangeSelectorPlugin);
assert.isNotNull(rangeSelector);
var combinedSeries = rangeSelector.computeCombinedSeriesAndLimits_();
assert.deepEqual({
yMin: 3 - 7 * 0.25, // 25% padding
yMax: 10 + 7 * 0.25,
data: [
[],
[],
[]
]
}, combinedSeries);
});
var assertGraphExistence = function(g, graph) {
assert.isNotNull(g);
var zoomhandles = graph.getElementsByClassName('dygraph-rangesel-zoomhandle');
assert.equal(2, zoomhandles.length);
var bgcanvas = graph.getElementsByClassName('dygraph-rangesel-bgcanvas');
assert.equal(1, bgcanvas.length);
var fgcanvas = graph.getElementsByClassName('dygraph-rangesel-fgcanvas');
assert.equal(1, fgcanvas.length);
};
});