mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(plugins): work on plugin directive loading
This commit is contained in:
@@ -4,4 +4,5 @@ define([
|
||||
'./panel_srv',
|
||||
'./panel_helper',
|
||||
'./solo_panel_ctrl',
|
||||
'./panel_loader',
|
||||
], function () {});
|
||||
|
||||
@@ -1,32 +1,12 @@
|
||||
define([
|
||||
'angular',
|
||||
'jquery',
|
||||
'app/core/config',
|
||||
],
|
||||
function (angular, $, config) {
|
||||
function (angular, $) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.directives');
|
||||
|
||||
module.directive('panelLoader', function($compile, $parse) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, elem, attr) {
|
||||
var getter = $parse(attr.type), panelType = getter(scope);
|
||||
var module = config.panels[panelType].module;
|
||||
|
||||
System.import(module).then(function() {
|
||||
var panelEl = angular.element(document.createElement('grafana-panel-' + panelType));
|
||||
elem.append(panelEl);
|
||||
$compile(panelEl)(scope);
|
||||
}).catch(function(err) {
|
||||
console.log('Failed to load panel:', err);
|
||||
scope.appEvent('alert-error', ['Panel Load Error', 'Failed to load panel ' + panelType + ', ' + err]);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.directive('grafanaPanel', function() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
||||
22
public/app/features/panel/panel_loader.ts
Normal file
22
public/app/features/panel/panel_loader.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
///<reference path="../../headers/common.d.ts" />
|
||||
|
||||
import angular from 'angular';
|
||||
import config from 'app/core/config';
|
||||
|
||||
/** @ngInject */
|
||||
function panelLoader($parse, dynamicDirectiveSrv) {
|
||||
return dynamicDirectiveSrv.create({
|
||||
directive: scope => {
|
||||
let modulePath = config.panels[scope.panel.type].module;
|
||||
|
||||
return System.import(modulePath).then(function(panelModule) {
|
||||
return {
|
||||
name: 'panel-directive-' + scope.panel.type,
|
||||
fn: panelModule.panel,
|
||||
};
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
angular.module('grafana.directives').directive('panelLoader', panelLoader);
|
||||
@@ -1,220 +0,0 @@
|
||||
<div class="editor-row" style="margin-bottom: 20px;">
|
||||
<span style="float: right; font-size: 12px;"><i>Last updated by Grafana October 4, 2015 12:15:04 by $username</i></span>
|
||||
<div class="section">
|
||||
<h5>General Alerting Options</h5>
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item">
|
||||
Alert Title
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-xlarge tight-form-input"></input>
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
Alerting Backend
|
||||
</li>
|
||||
<li>
|
||||
<select class="input-medium tight-form-input">
|
||||
<option>Grafana Alerting</option>
|
||||
</select>
|
||||
</li>
|
||||
<li class="tight-form-item last">
|
||||
<label class="checkbox-label" for="alerting-enabled">Enabled</label>
|
||||
<input class="cr1" id="alerting-enabled" type="checkbox">
|
||||
<label for="alerting-enabled" class="cr1"></label>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-row" style="margin-bottom: 20px;">
|
||||
<h5>Choose your query:</h5>
|
||||
<p>Select an exising query to alert on:</p>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
|
||||
<li class="tight-form-item">None</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
|
||||
<li class="tight-form-item" style="min-width: 15px; text-align: center">A</li>
|
||||
<li class="tight-form-item">apps</li>
|
||||
<li class="tight-form-item"><i class="fa fa-asterisk"><i></i></i></li>
|
||||
<li class="tight-form-item">fakesite</li>
|
||||
<li class="tight-form-item">counters</li>
|
||||
<li class="tight-form-item">requests</li>
|
||||
<li class="tight-form-item">count</li>
|
||||
<li class="tight-form-item">scaleToSeconds(1)</li>
|
||||
<li class="tight-form-item last">aliasByNode(2)</li>
|
||||
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
|
||||
<li class="tight-form-item" style="min-width: 15px; text-align: center">B</li>
|
||||
<li class="tight-form-item last"><span class="query-keyword">Metric:</span> us-west-2 AWS/EC2 CPUUtilization <span class="query-keyword">Stats:</span> Minimum Maximum <span class="query-keyword">Dimensions</span> InstanceIS <span class="query-segment-operator">=</span> i-b0e8a447 <span class="query-keyword">Alias</span> {{stat}} <span class="query-keyword">Period</span> 60</li>
|
||||
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
|
||||
<li class="tight-form-item" style="min-width: 15px; text-align: center">C</li>
|
||||
<li class="tight-form-item last"><span class="query-keyword">Query:</span> avg(counters_logins) by(server) <span class="query-keyword">Legend Format:</span> {{app}} - {{server}} <span class="query-keyword">Step:</span> 1s <span class="query-keyword">Resolution:</span> 1/2</li>
|
||||
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
|
||||
<li class="tight-form-item" style="min-width: 15px; text-align: center">D</li>
|
||||
<li class="tight-form-item last"><span class="query-keyword">SELECT</span> mean(value) <span class="query-keyword">FROM</span> logins.count <span class="query-keyword">WHERE</span> hostname <span class="query-segment-operator">=</span> /$Hostname$/ <span class="query-keyword">GROUP BY</span> time($internal) hostname</li>
|
||||
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" checked /></li>
|
||||
<li class="tight-form-item" style="min-width: 15px; text-align: center">E</li>
|
||||
<li class="tight-form-item last"><span class="query-keyword">Metric:</span> apps.backend.backend_01.counters.requests.count <span class="query-keyword">Alias:</span> Bristow <span class="query-keyword">Aggregator:</span> Sum <span class="query-keyword">Downsample:</span> 1m <span class="query-keyword">Aggregator</span> Sum <span class="query-keyword">Tags</span> host = test</li>
|
||||
<li><div class="copy-query" bs-tooltip="'Copy to custom query'" data-placement="top"></div></li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-row" style="margin-bottom: 20px;">
|
||||
<p>Or write a new custom alerting query:</p>
|
||||
<div class="section">
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item"><input type="radio" class="radio input-small" name="query" style="margin: 0 4px 4px;" /></li>
|
||||
<li class="tight-form-item">
|
||||
<a class="pointer">
|
||||
<i class="fa fa-pencil"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
select metric
|
||||
</li>
|
||||
<li>
|
||||
<a class="tight-form-item tight-form-func last dropdown-toggle"><i class="fa fa-plus"></i></a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-row" style="margin-bottom: 10px;">
|
||||
<div class="section">
|
||||
<h5>Define Your States</h5>
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item">
|
||||
by
|
||||
</li>
|
||||
<li>
|
||||
<select class="input-medium tight-form-input">
|
||||
<option>Averaging</option>
|
||||
</select>
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
the values in the query over the last
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-mini tight-form-input last"></input>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-row" style="margin-bottom: 20px;">
|
||||
<div class="section">
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px;">
|
||||
<span class="alert-state alert-state-warning">Warn</span>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-mini tight-form-input" value=">" style="text-align: center;"></input>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-mini tight-form-input" value="#B" style="text-align: center;"></input>
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
.notify
|
||||
</li>
|
||||
<li class="alert-notify-emails">
|
||||
<bootstrap-tagsinput tagclass="label label-tag label-tag-email"></bootstrap-tagsinput>
|
||||
</li>
|
||||
<li class="tight-form-item last">
|
||||
<label class="checkbox-label" for="state-enabled">Enabled</label>
|
||||
<input class="cr1" id="state-enabled" type="checkbox">
|
||||
<label for="state-enabled" class="cr1"></label>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px;">
|
||||
<span class="alert-state alert-state-critical">Critical</span>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-mini tight-form-input"></input>
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-mini tight-form-input"></input>
|
||||
</li>
|
||||
<li class="tight-form-item">
|
||||
.notify
|
||||
</li>
|
||||
<li class="alert-notify-emails">
|
||||
<bootstrap-tagsinput tagclass="label label-tag label-tag-email"></bootstrap-tagsinput>
|
||||
</li>
|
||||
<li class="tight-form-item last">
|
||||
<label class="checkbox-label" for="state-enabled2">Enabled</label>
|
||||
<input class="cr1" id="state-enabled2" type="checkbox">
|
||||
<label for="state-enabled2" class="cr1"></label>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editor-row">
|
||||
<div class="section">
|
||||
<h5>What to Say <span style="float: right; font-size: 12px; font-weight: normal;"><a href="#">Variables</a> | <a href="#">Preview</a></span></h5>
|
||||
<div class="tight-form">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px;">
|
||||
Summary
|
||||
</li>
|
||||
<li>
|
||||
<input type="text" class="input-xxlarge tight-form-input last"></input>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="tight-form last">
|
||||
<ul class="tight-form-list">
|
||||
<li class="tight-form-item" style="width: 100px;">
|
||||
Description
|
||||
</li>
|
||||
<li>
|
||||
<textarea class="tight-form-textarea input-xxlarge last"></textarea>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
<div ng-repeat="(name, panel) in row.panels track by panel.id" class="panel" ui-draggable="!dashboardViewState.fullscreen" drag="panel.id"
|
||||
ui-on-Drop="onDrop($data, row, panel)" drag-handle-class="drag-handle" panel-width>
|
||||
<panel-loader type="panel.type" class="panel-margin"></panel-loader>
|
||||
<panel-loader class="panel-margin"></panel-loader>
|
||||
</div>
|
||||
|
||||
<div panel-drop-zone class="panel panel-drop-zone" ui-on-drop="onDrop($data, row)" data-drop="true">
|
||||
|
||||
@@ -11,14 +11,8 @@ function (angular, app, _, config, PanelMeta) {
|
||||
var module = angular.module('grafana.panels.dashlist', []);
|
||||
app.useModule(module);
|
||||
|
||||
module.directive('grafanaPanelDashlist', function() {
|
||||
return {
|
||||
controller: 'DashListPanelCtrl',
|
||||
templateUrl: 'app/plugins/panel/dashlist/module.html',
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('DashListPanelCtrl', function($scope, panelSrv, backendSrv) {
|
||||
/** @ngInject */
|
||||
function DashListPanelCtrl($scope, panelSrv, backendSrv) {
|
||||
|
||||
$scope.panelMeta = new PanelMeta({
|
||||
panelName: 'Dashboard list',
|
||||
@@ -73,5 +67,16 @@ function (angular, app, _, config, PanelMeta) {
|
||||
};
|
||||
|
||||
$scope.init();
|
||||
});
|
||||
}
|
||||
|
||||
function dashListPanelDirective() {
|
||||
return {
|
||||
controller: DashListPanelCtrl,
|
||||
templateUrl: 'app/plugins/panel/dashlist/module.html',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
panel: dashListPanelDirective
|
||||
};
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ define([
|
||||
'moment',
|
||||
'lodash',
|
||||
'app/core/utils/kbn',
|
||||
'./graph.tooltip',
|
||||
'./graph_tooltip',
|
||||
'jquery.flot',
|
||||
'jquery.flot.events',
|
||||
'jquery.flot.selection',
|
||||
|
||||
2
public/app/plugins/panel/graph/graph_tooltip.d.ts
vendored
Normal file
2
public/app/plugins/panel/graph/graph_tooltip.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
declare var GraphTooltip: any;
|
||||
export default GraphTooltip;
|
||||
3
public/app/plugins/panel/graph/module.d.ts
vendored
Normal file
3
public/app/plugins/panel/graph/module.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
declare var panel: any;
|
||||
declare var GraphCtrl: any;
|
||||
export {panel, GraphCtrl};
|
||||
@@ -12,16 +12,8 @@ define([
|
||||
function (angular, _, moment, kbn, TimeSeries, PanelMeta) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.panels.graph');
|
||||
|
||||
module.directive('grafanaPanelGraph', function() {
|
||||
return {
|
||||
controller: 'GraphCtrl',
|
||||
templateUrl: 'app/plugins/panel/graph/module.html',
|
||||
};
|
||||
});
|
||||
|
||||
module.controller('GraphCtrl', function($scope, $rootScope, panelSrv, annotationsSrv, panelHelper) {
|
||||
/** @ngInject */
|
||||
function GraphCtrl($scope, $rootScope, panelSrv, annotationsSrv, panelHelper) {
|
||||
|
||||
$scope.panelMeta = new PanelMeta({
|
||||
panelName: 'Graph',
|
||||
@@ -294,7 +286,17 @@ function (angular, _, moment, kbn, TimeSeries, PanelMeta) {
|
||||
};
|
||||
|
||||
panelSrv.init($scope);
|
||||
}
|
||||
|
||||
});
|
||||
function graphPanelDirective() {
|
||||
return {
|
||||
controller: GraphCtrl,
|
||||
templateUrl: 'app/plugins/panel/graph/module.html',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
GraphCtrl: GraphCtrl,
|
||||
panel: graphPanelDirective,
|
||||
};
|
||||
});
|
||||
|
||||
53
public/app/plugins/panel/graph/specs/graph_ctrl_specs.ts
Normal file
53
public/app/plugins/panel/graph/specs/graph_ctrl_specs.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
///<reference path="../../../../headers/common.d.ts" />
|
||||
|
||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from '../../../../../test/lib/common';
|
||||
|
||||
import 'app/features/panel/panel_srv';
|
||||
import 'app/features/panel/panel_helper';
|
||||
|
||||
import angular from 'angular';
|
||||
import {GraphCtrl} from '../module';
|
||||
import helpers from '../../../../../test/specs/helpers';
|
||||
|
||||
angular.module('grafana.controllers').controller('GraphCtrl', GraphCtrl);
|
||||
|
||||
describe('GraphCtrl', function() {
|
||||
var ctx = new helpers.ControllerTestContext();
|
||||
|
||||
beforeEach(angularMocks.module('grafana.services'));
|
||||
beforeEach(angularMocks.module('grafana.controllers'));
|
||||
|
||||
beforeEach(ctx.providePhase());
|
||||
beforeEach(ctx.createControllerPhase('GraphCtrl'));
|
||||
|
||||
describe('get_data with 2 series', function() {
|
||||
beforeEach(function() {
|
||||
ctx.annotationsSrv.getAnnotations = sinon.stub().returns(ctx.$q.when([]));
|
||||
ctx.datasource.query = sinon.stub().returns(ctx.$q.when({
|
||||
data: [
|
||||
{ target: 'test.cpu1', datapoints: [[1, 10]]},
|
||||
{ target: 'test.cpu2', datapoints: [[1, 10]]}
|
||||
]
|
||||
}));
|
||||
ctx.scope.render = sinon.spy();
|
||||
ctx.scope.refreshData(ctx.datasource);
|
||||
ctx.scope.$digest();
|
||||
});
|
||||
|
||||
it('should send time series to render', function() {
|
||||
var data = ctx.scope.render.getCall(0).args[0];
|
||||
expect(data.length).to.be(2);
|
||||
});
|
||||
|
||||
describe('get_data failure following success', function() {
|
||||
beforeEach(function() {
|
||||
ctx.datasource.query = sinon.stub().returns(ctx.$q.reject('Datasource Error'));
|
||||
ctx.scope.refreshData(ctx.datasource);
|
||||
ctx.scope.$digest();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
230
public/app/plugins/panel/graph/specs/graph_specs.ts
Normal file
230
public/app/plugins/panel/graph/specs/graph_specs.ts
Normal file
@@ -0,0 +1,230 @@
|
||||
///<reference path="../../../../headers/common.d.ts" />
|
||||
|
||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from '../../../../../test/lib/common';
|
||||
|
||||
import '../module';
|
||||
import angular from 'angular';
|
||||
import $ from 'jquery';
|
||||
import helpers from '../../../../../test/specs/helpers';
|
||||
import TimeSeries from '../../../../core/time_series2';
|
||||
|
||||
describe('grafanaGraph', function() {
|
||||
|
||||
beforeEach(angularMocks.module('grafana.directives'));
|
||||
|
||||
function graphScenario(desc, func) {
|
||||
describe(desc, function() {
|
||||
var ctx: any = {};
|
||||
|
||||
ctx.setup = function(setupFunc) {
|
||||
|
||||
beforeEach(angularMocks.module(function($provide) {
|
||||
$provide.value("timeSrv", new helpers.TimeSrvStub());
|
||||
}));
|
||||
|
||||
beforeEach(angularMocks.inject(function($rootScope, $compile) {
|
||||
var scope = $rootScope.$new();
|
||||
var element = angular.element("<div style='width:500px' grafana-graph><div>");
|
||||
|
||||
scope.height = '200px';
|
||||
scope.panel = {
|
||||
legend: {},
|
||||
grid: { },
|
||||
y_formats: [],
|
||||
seriesOverrides: [],
|
||||
tooltip: {
|
||||
shared: true
|
||||
}
|
||||
};
|
||||
|
||||
scope.panelRenderingComplete = sinon.spy();
|
||||
scope.appEvent = sinon.spy();
|
||||
scope.onAppEvent = sinon.spy();
|
||||
scope.hiddenSeries = {};
|
||||
scope.dashboard = { timezone: 'browser' };
|
||||
scope.range = {
|
||||
from: new Date('2014-08-09 10:00:00'),
|
||||
to: new Date('2014-09-09 13:00:00')
|
||||
};
|
||||
ctx.data = [];
|
||||
ctx.data.push(new TimeSeries({
|
||||
datapoints: [[1,1],[2,2]],
|
||||
alias: 'series1'
|
||||
}));
|
||||
ctx.data.push(new TimeSeries({
|
||||
datapoints: [[1,1],[2,2]],
|
||||
alias: 'series2'
|
||||
}));
|
||||
|
||||
setupFunc(scope, ctx.data);
|
||||
|
||||
$compile(element)(scope);
|
||||
scope.$digest();
|
||||
$.plot = ctx.plotSpy = sinon.spy();
|
||||
|
||||
scope.$emit('render', ctx.data);
|
||||
ctx.plotData = ctx.plotSpy.getCall(0).args[1];
|
||||
ctx.plotOptions = ctx.plotSpy.getCall(0).args[2];
|
||||
}));
|
||||
};
|
||||
|
||||
func(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
graphScenario('simple lines options', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.lines = true;
|
||||
scope.panel.fill = 5;
|
||||
scope.panel.linewidth = 3;
|
||||
scope.panel.steppedLine = true;
|
||||
});
|
||||
|
||||
it('should configure plot with correct options', function() {
|
||||
expect(ctx.plotOptions.series.lines.show).to.be(true);
|
||||
expect(ctx.plotOptions.series.lines.fill).to.be(0.5);
|
||||
expect(ctx.plotOptions.series.lines.lineWidth).to.be(3);
|
||||
expect(ctx.plotOptions.series.lines.steps).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('grid thresholds 100, 200', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.grid = {
|
||||
threshold1: 100,
|
||||
threshold1Color: "#111",
|
||||
threshold2: 200,
|
||||
threshold2Color: "#222",
|
||||
};
|
||||
});
|
||||
|
||||
it('should add grid markings', function() {
|
||||
var markings = ctx.plotOptions.grid.markings;
|
||||
expect(markings[0].yaxis.from).to.be(100);
|
||||
expect(markings[0].yaxis.to).to.be(200);
|
||||
expect(markings[0].color).to.be('#111');
|
||||
expect(markings[1].yaxis.from).to.be(200);
|
||||
expect(markings[1].yaxis.to).to.be(Infinity);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('inverted grid thresholds 200, 100', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.grid = {
|
||||
threshold1: 200,
|
||||
threshold1Color: "#111",
|
||||
threshold2: 100,
|
||||
threshold2Color: "#222",
|
||||
};
|
||||
});
|
||||
|
||||
it('should add grid markings', function() {
|
||||
var markings = ctx.plotOptions.grid.markings;
|
||||
expect(markings[0].yaxis.from).to.be(200);
|
||||
expect(markings[0].yaxis.to).to.be(100);
|
||||
expect(markings[0].color).to.be('#111');
|
||||
expect(markings[1].yaxis.from).to.be(100);
|
||||
expect(markings[1].yaxis.to).to.be(-Infinity);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('grid thresholds from zero', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.grid = {
|
||||
threshold1: 0,
|
||||
threshold1Color: "#111",
|
||||
};
|
||||
});
|
||||
|
||||
it('should add grid markings', function() {
|
||||
var markings = ctx.plotOptions.grid.markings;
|
||||
expect(markings[0].yaxis.from).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('when logBase is log 10', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.grid = {
|
||||
leftMax: null,
|
||||
rightMax: null,
|
||||
leftMin: null,
|
||||
rightMin: null,
|
||||
leftLogBase: 10,
|
||||
};
|
||||
});
|
||||
|
||||
it('should apply axis transform and ticks', function() {
|
||||
var axis = ctx.plotOptions.yaxes[0];
|
||||
expect(axis.transform(100)).to.be(Math.log(100+0.1));
|
||||
expect(axis.ticks[0]).to.be(0);
|
||||
expect(axis.ticks[1]).to.be(1);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('should use timeStep for barWidth', function(ctx) {
|
||||
ctx.setup(function(scope, data) {
|
||||
scope.panel.bars = true;
|
||||
data[0] = new TimeSeries({
|
||||
datapoints: [[1,10],[2,20]],
|
||||
alias: 'series1',
|
||||
});
|
||||
});
|
||||
|
||||
it('should set barWidth', function() {
|
||||
expect(ctx.plotOptions.series.bars.barWidth).to.be(10/1.5);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('series option overrides, fill & points', function(ctx) {
|
||||
ctx.setup(function(scope, data) {
|
||||
scope.panel.lines = true;
|
||||
scope.panel.fill = 5;
|
||||
scope.panel.seriesOverrides = [
|
||||
{ alias: 'test', fill: 0, points: true }
|
||||
];
|
||||
|
||||
data[1].alias = 'test';
|
||||
});
|
||||
|
||||
it('should match second series and fill zero, and enable points', function() {
|
||||
expect(ctx.plotOptions.series.lines.fill).to.be(0.5);
|
||||
expect(ctx.plotData[1].lines.fill).to.be(0.001);
|
||||
expect(ctx.plotData[1].points.show).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('should order series order according to zindex', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.seriesOverrides = [{ alias: 'series1', zindex: 2 }];
|
||||
});
|
||||
|
||||
it('should move zindex 2 last', function() {
|
||||
expect(ctx.plotData[0].alias).to.be('series2');
|
||||
expect(ctx.plotData[1].alias).to.be('series1');
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('when series is hidden', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.hiddenSeries = {'series2': true};
|
||||
});
|
||||
|
||||
it('should remove datapoints and disable stack', function() {
|
||||
expect(ctx.plotData[0].alias).to.be('series1');
|
||||
expect(ctx.plotData[1].data.length).to.be(0);
|
||||
expect(ctx.plotData[1].stack).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('when stack and percent', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.percentage = true;
|
||||
scope.panel.stack = true;
|
||||
});
|
||||
|
||||
it('should show percentage', function() {
|
||||
var axis = ctx.plotOptions.yaxes[0];
|
||||
expect(axis.tickFormatter(100, axis)).to.be("100%");
|
||||
});
|
||||
});
|
||||
});
|
||||
171
public/app/plugins/panel/graph/specs/tooltip_specs.ts
Normal file
171
public/app/plugins/panel/graph/specs/tooltip_specs.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
///<reference path="../../../../headers/common.d.ts" />
|
||||
|
||||
import {describe, beforeEach, it, sinon, expect, angularMocks} from '../../../../../test/lib/common';
|
||||
|
||||
import $ from 'jquery';
|
||||
import GraphTooltip from '../graph_tooltip';
|
||||
|
||||
var scope = {
|
||||
appEvent: sinon.spy(),
|
||||
onAppEvent: sinon.spy(),
|
||||
};
|
||||
|
||||
var elem = $('<div></div>');
|
||||
var dashboard = { };
|
||||
|
||||
function describeSharedTooltip(desc, fn) {
|
||||
var ctx: any = {};
|
||||
ctx.scope = scope;
|
||||
ctx.scope.panel = {
|
||||
tooltip: {
|
||||
shared: true
|
||||
},
|
||||
legend: { },
|
||||
stack: false
|
||||
};
|
||||
|
||||
ctx.setup = function(setupFn) {
|
||||
ctx.setupFn = setupFn;
|
||||
};
|
||||
|
||||
describe(desc, function() {
|
||||
beforeEach(function() {
|
||||
ctx.setupFn();
|
||||
var tooltip = new GraphTooltip(elem, dashboard, scope);
|
||||
ctx.results = tooltip.getMultiSeriesPlotHoverInfo(ctx.data, ctx.pos);
|
||||
});
|
||||
|
||||
fn(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
describeSharedTooltip("steppedLine false, stack false", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{ data: [[10, 15], [12, 20]], lines: {} },
|
||||
{ data: [[10, 2], [12, 3]], lines: {} }
|
||||
];
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
|
||||
it('should return 2 series', function() {
|
||||
expect(ctx.results.length).to.be(2);
|
||||
});
|
||||
it('should add time to results array', function() {
|
||||
expect(ctx.results.time).to.be(10);
|
||||
});
|
||||
it('should set value and hoverIndex', function() {
|
||||
expect(ctx.results[0].value).to.be(15);
|
||||
expect(ctx.results[1].value).to.be(2);
|
||||
expect(ctx.results[0].hoverIndex).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
describeSharedTooltip("one series is hidden", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{ data: [[10, 15], [12, 20]], },
|
||||
{ data: [] }
|
||||
];
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
});
|
||||
|
||||
describeSharedTooltip("steppedLine false, stack true, individual false", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{
|
||||
data: [[10, 15], [12, 20]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10,15], [12,20]],
|
||||
},
|
||||
stack: true,
|
||||
},
|
||||
{
|
||||
data: [[10, 2], [12, 3]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 2], [12, 3]],
|
||||
},
|
||||
stack: true
|
||||
}
|
||||
];
|
||||
ctx.scope.panel.stack = true;
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
|
||||
it('should show stacked value', function() {
|
||||
expect(ctx.results[1].value).to.be(17);
|
||||
});
|
||||
});
|
||||
|
||||
describeSharedTooltip("steppedLine false, stack true, individual false, series stack false", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{
|
||||
data: [[10, 15], [12, 20]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 15], [12, 20]],
|
||||
},
|
||||
stack: true
|
||||
},
|
||||
{
|
||||
data: [[10, 2], [12, 3]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 2], [12, 3]],
|
||||
},
|
||||
stack: false
|
||||
}
|
||||
];
|
||||
ctx.scope.panel.stack = true;
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
|
||||
it('should not show stacked value', function() {
|
||||
expect(ctx.results[1].value).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describeSharedTooltip("steppedLine false, stack true, individual true", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{
|
||||
data: [[10, 15], [12, 20]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 15], [12, 20]],
|
||||
},
|
||||
stack: true
|
||||
},
|
||||
{
|
||||
data: [[10, 2], [12, 3]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 2], [12, 3]],
|
||||
},
|
||||
stack: false
|
||||
}
|
||||
];
|
||||
ctx.scope.panel.stack = true;
|
||||
ctx.scope.panel.tooltip.value_type = 'individual';
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
|
||||
it('should not show stacked value', function() {
|
||||
expect(ctx.results[1].value).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
define([
|
||||
'./helpers',
|
||||
'app/features/panel/panel_srv',
|
||||
'app/features/panel/panel_helper',
|
||||
'app/plugins/panel/graph/module'
|
||||
], function(helpers) {
|
||||
'use strict';
|
||||
|
||||
describe('GraphCtrl', function() {
|
||||
var ctx = new helpers.ControllerTestContext();
|
||||
|
||||
beforeEach(module('grafana.services'));
|
||||
beforeEach(module('grafana.panels.graph'));
|
||||
|
||||
beforeEach(ctx.providePhase());
|
||||
beforeEach(ctx.createControllerPhase('GraphCtrl'));
|
||||
|
||||
describe('get_data with 2 series', function() {
|
||||
beforeEach(function() {
|
||||
ctx.annotationsSrv.getAnnotations = sinon.stub().returns(ctx.$q.when([]));
|
||||
ctx.datasource.query = sinon.stub().returns(ctx.$q.when({
|
||||
data: [
|
||||
{ target: 'test.cpu1', datapoints: [[1, 10]]},
|
||||
{ target: 'test.cpu2', datapoints: [[1, 10]]}
|
||||
]
|
||||
}));
|
||||
ctx.scope.render = sinon.spy();
|
||||
ctx.scope.refreshData(ctx.datasource);
|
||||
ctx.scope.$digest();
|
||||
});
|
||||
|
||||
it('should send time series to render', function() {
|
||||
var data = ctx.scope.render.getCall(0).args[0];
|
||||
expect(data.length).to.be(2);
|
||||
});
|
||||
|
||||
describe('get_data failure following success', function() {
|
||||
beforeEach(function() {
|
||||
ctx.datasource.query = sinon.stub().returns(ctx.$q.reject('Datasource Error'));
|
||||
ctx.scope.refreshData(ctx.datasource);
|
||||
ctx.scope.$digest();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,231 +0,0 @@
|
||||
define([
|
||||
'./helpers',
|
||||
'angular',
|
||||
'jquery',
|
||||
'app/core/time_series',
|
||||
'app/plugins/panel/graph/graph'
|
||||
], function(helpers, angular, $, TimeSeries) {
|
||||
'use strict';
|
||||
|
||||
describe('grafanaGraph', function() {
|
||||
|
||||
beforeEach(module('grafana.directives'));
|
||||
|
||||
function graphScenario(desc, func) {
|
||||
describe(desc, function() {
|
||||
var ctx = {};
|
||||
|
||||
ctx.setup = function (setupFunc) {
|
||||
|
||||
beforeEach(module(function($provide) {
|
||||
$provide.value("timeSrv", new helpers.TimeSrvStub());
|
||||
}));
|
||||
|
||||
beforeEach(inject(function($rootScope, $compile) {
|
||||
var scope = $rootScope.$new();
|
||||
var element = angular.element("<div style='width:500px' grafana-graph><div>");
|
||||
|
||||
scope.height = '200px';
|
||||
scope.panel = {
|
||||
legend: {},
|
||||
grid: { },
|
||||
y_formats: [],
|
||||
seriesOverrides: [],
|
||||
tooltip: {
|
||||
shared: true
|
||||
}
|
||||
};
|
||||
|
||||
scope.panelRenderingComplete = sinon.spy();
|
||||
scope.appEvent = sinon.spy();
|
||||
scope.onAppEvent = sinon.spy();
|
||||
scope.hiddenSeries = {};
|
||||
scope.dashboard = { timezone: 'browser' };
|
||||
scope.range = {
|
||||
from: new Date('2014-08-09 10:00:00'),
|
||||
to: new Date('2014-09-09 13:00:00')
|
||||
};
|
||||
ctx.data = [];
|
||||
ctx.data.push(new TimeSeries({
|
||||
datapoints: [[1,1],[2,2]],
|
||||
alias: 'series1'
|
||||
}));
|
||||
ctx.data.push(new TimeSeries({
|
||||
datapoints: [[1,1],[2,2]],
|
||||
alias: 'series2'
|
||||
}));
|
||||
|
||||
setupFunc(scope, ctx.data);
|
||||
|
||||
$compile(element)(scope);
|
||||
scope.$digest();
|
||||
$.plot = ctx.plotSpy = sinon.spy();
|
||||
|
||||
scope.$emit('render', ctx.data);
|
||||
ctx.plotData = ctx.plotSpy.getCall(0).args[1];
|
||||
ctx.plotOptions = ctx.plotSpy.getCall(0).args[2];
|
||||
}));
|
||||
};
|
||||
|
||||
func(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
graphScenario('simple lines options', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.lines = true;
|
||||
scope.panel.fill = 5;
|
||||
scope.panel.linewidth = 3;
|
||||
scope.panel.steppedLine = true;
|
||||
});
|
||||
|
||||
it('should configure plot with correct options', function() {
|
||||
expect(ctx.plotOptions.series.lines.show).to.be(true);
|
||||
expect(ctx.plotOptions.series.lines.fill).to.be(0.5);
|
||||
expect(ctx.plotOptions.series.lines.lineWidth).to.be(3);
|
||||
expect(ctx.plotOptions.series.lines.steps).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('grid thresholds 100, 200', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.grid = {
|
||||
threshold1: 100,
|
||||
threshold1Color: "#111",
|
||||
threshold2: 200,
|
||||
threshold2Color: "#222",
|
||||
};
|
||||
});
|
||||
|
||||
it('should add grid markings', function() {
|
||||
var markings = ctx.plotOptions.grid.markings;
|
||||
expect(markings[0].yaxis.from).to.be(100);
|
||||
expect(markings[0].yaxis.to).to.be(200);
|
||||
expect(markings[0].color).to.be('#111');
|
||||
expect(markings[1].yaxis.from).to.be(200);
|
||||
expect(markings[1].yaxis.to).to.be(Infinity);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('inverted grid thresholds 200, 100', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.grid = {
|
||||
threshold1: 200,
|
||||
threshold1Color: "#111",
|
||||
threshold2: 100,
|
||||
threshold2Color: "#222",
|
||||
};
|
||||
});
|
||||
|
||||
it('should add grid markings', function() {
|
||||
var markings = ctx.plotOptions.grid.markings;
|
||||
expect(markings[0].yaxis.from).to.be(200);
|
||||
expect(markings[0].yaxis.to).to.be(100);
|
||||
expect(markings[0].color).to.be('#111');
|
||||
expect(markings[1].yaxis.from).to.be(100);
|
||||
expect(markings[1].yaxis.to).to.be(-Infinity);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('grid thresholds from zero', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.grid = {
|
||||
threshold1: 0,
|
||||
threshold1Color: "#111",
|
||||
};
|
||||
});
|
||||
|
||||
it('should add grid markings', function() {
|
||||
var markings = ctx.plotOptions.grid.markings;
|
||||
expect(markings[0].yaxis.from).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('when logBase is log 10', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.grid = {
|
||||
leftMax: null,
|
||||
rightMax: null,
|
||||
leftMin: null,
|
||||
rightMin: null,
|
||||
leftLogBase: 10,
|
||||
};
|
||||
});
|
||||
|
||||
it('should apply axis transform and ticks', function() {
|
||||
var axis = ctx.plotOptions.yaxes[0];
|
||||
expect(axis.transform(100)).to.be(Math.log(100+0.1));
|
||||
expect(axis.ticks[0]).to.be(0);
|
||||
expect(axis.ticks[1]).to.be(1);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('should use timeStep for barWidth', function(ctx) {
|
||||
ctx.setup(function(scope, data) {
|
||||
scope.panel.bars = true;
|
||||
data[0] = new TimeSeries({
|
||||
datapoints: [[1,10],[2,20]],
|
||||
alias: 'series1',
|
||||
});
|
||||
});
|
||||
|
||||
it('should set barWidth', function() {
|
||||
expect(ctx.plotOptions.series.bars.barWidth).to.be(10/1.5);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('series option overrides, fill & points', function(ctx) {
|
||||
ctx.setup(function(scope, data) {
|
||||
scope.panel.lines = true;
|
||||
scope.panel.fill = 5;
|
||||
scope.panel.seriesOverrides = [
|
||||
{ alias: 'test', fill: 0, points: true }
|
||||
];
|
||||
|
||||
data[1].alias = 'test';
|
||||
});
|
||||
|
||||
it('should match second series and fill zero, and enable points', function() {
|
||||
expect(ctx.plotOptions.series.lines.fill).to.be(0.5);
|
||||
expect(ctx.plotData[1].lines.fill).to.be(0.001);
|
||||
expect(ctx.plotData[1].points.show).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('should order series order according to zindex', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.seriesOverrides = [{ alias: 'series1', zindex: 2 }];
|
||||
});
|
||||
|
||||
it('should move zindex 2 last', function() {
|
||||
expect(ctx.plotData[0].alias).to.be('series2');
|
||||
expect(ctx.plotData[1].alias).to.be('series1');
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('when series is hidden', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.hiddenSeries = {'series2': true};
|
||||
});
|
||||
|
||||
it('should remove datapoints and disable stack', function() {
|
||||
expect(ctx.plotData[0].alias).to.be('series1');
|
||||
expect(ctx.plotData[1].data.length).to.be(0);
|
||||
expect(ctx.plotData[1].stack).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
graphScenario('when stack and percent', function(ctx) {
|
||||
ctx.setup(function(scope) {
|
||||
scope.panel.percentage = true;
|
||||
scope.panel.stack = true;
|
||||
});
|
||||
|
||||
it('should show percentage', function() {
|
||||
var axis = ctx.plotOptions.yaxes[0];
|
||||
expect(axis.tickFormatter(100, axis)).to.be("100%");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
define([
|
||||
'jquery',
|
||||
'app/plugins/panel/graph/graph.tooltip'
|
||||
], function($, GraphTooltip) {
|
||||
'use strict';
|
||||
|
||||
var scope = {
|
||||
appEvent: sinon.spy(),
|
||||
onAppEvent: sinon.spy(),
|
||||
};
|
||||
|
||||
var elem = $('<div></div>');
|
||||
var dashboard = { };
|
||||
|
||||
function describeSharedTooltip(desc, fn) {
|
||||
var ctx = {};
|
||||
ctx.scope = scope;
|
||||
ctx.scope.panel = {
|
||||
tooltip: {
|
||||
shared: true
|
||||
},
|
||||
legend: { },
|
||||
stack: false
|
||||
};
|
||||
|
||||
ctx.setup = function(setupFn) {
|
||||
ctx.setupFn = setupFn;
|
||||
};
|
||||
|
||||
describe(desc, function() {
|
||||
beforeEach(function() {
|
||||
ctx.setupFn();
|
||||
var tooltip = new GraphTooltip(elem, dashboard, scope);
|
||||
ctx.results = tooltip.getMultiSeriesPlotHoverInfo(ctx.data, ctx.pos);
|
||||
});
|
||||
|
||||
fn(ctx);
|
||||
});
|
||||
}
|
||||
|
||||
describeSharedTooltip("steppedLine false, stack false", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{ data: [[10, 15], [12, 20]], lines: {} },
|
||||
{ data: [[10, 2], [12, 3]], lines: {} }
|
||||
];
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
|
||||
it('should return 2 series', function() {
|
||||
expect(ctx.results.length).to.be(2);
|
||||
});
|
||||
it('should add time to results array', function() {
|
||||
expect(ctx.results.time).to.be(10);
|
||||
});
|
||||
it('should set value and hoverIndex', function() {
|
||||
expect(ctx.results[0].value).to.be(15);
|
||||
expect(ctx.results[1].value).to.be(2);
|
||||
expect(ctx.results[0].hoverIndex).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
describeSharedTooltip("one series is hidden", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{ data: [[10, 15], [12, 20]], },
|
||||
{ data: [] }
|
||||
];
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
});
|
||||
|
||||
describeSharedTooltip("steppedLine false, stack true, individual false", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{
|
||||
data: [[10, 15], [12, 20]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10,15], [12,20]],
|
||||
},
|
||||
stack: true,
|
||||
},
|
||||
{
|
||||
data: [[10, 2], [12, 3]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 2], [12, 3]],
|
||||
},
|
||||
stack: true
|
||||
}
|
||||
];
|
||||
ctx.scope.panel.stack = true;
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
|
||||
it('should show stacked value', function() {
|
||||
expect(ctx.results[1].value).to.be(17);
|
||||
});
|
||||
});
|
||||
|
||||
describeSharedTooltip("steppedLine false, stack true, individual false, series stack false", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{
|
||||
data: [[10, 15], [12, 20]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 15], [12, 20]],
|
||||
},
|
||||
stack: true
|
||||
},
|
||||
{
|
||||
data: [[10, 2], [12, 3]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 2], [12, 3]],
|
||||
},
|
||||
stack: false
|
||||
}
|
||||
];
|
||||
ctx.scope.panel.stack = true;
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
|
||||
it('should not show stacked value', function() {
|
||||
expect(ctx.results[1].value).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describeSharedTooltip("steppedLine false, stack true, individual true", function(ctx) {
|
||||
ctx.setup(function() {
|
||||
ctx.data = [
|
||||
{
|
||||
data: [[10, 15], [12, 20]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 15], [12, 20]],
|
||||
},
|
||||
stack: true
|
||||
},
|
||||
{
|
||||
data: [[10, 2], [12, 3]],
|
||||
lines: {},
|
||||
datapoints: {
|
||||
pointsize: 2,
|
||||
points: [[10, 2], [12, 3]],
|
||||
},
|
||||
stack: false
|
||||
}
|
||||
];
|
||||
ctx.scope.panel.stack = true;
|
||||
ctx.scope.panel.tooltip.value_type = 'individual';
|
||||
ctx.pos = { x: 11 };
|
||||
});
|
||||
|
||||
it('should not show stacked value', function() {
|
||||
expect(ctx.results[1].value).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
6
public/test/specs/helpers.d.ts
vendored
6
public/test/specs/helpers.d.ts
vendored
@@ -1,6 +1,4 @@
|
||||
declare module "test/specs/helpers" {
|
||||
let helpers: any;
|
||||
export default helpers;
|
||||
}
|
||||
declare let helpers: any;
|
||||
export default helpers;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user