diff --git a/src/app/controllers/dash.js b/src/app/controllers/dash.js
index 2abb8e77054..e40db93fd7e 100644
--- a/src/app/controllers/dash.js
+++ b/src/app/controllers/dash.js
@@ -11,7 +11,7 @@ function (angular, $, config, _) {
var module = angular.module('grafana.controllers');
module.controller('DashCtrl', function(
- $scope, $rootScope, dashboardKeybindings, filterSrv, dashboard, panelMoveSrv, timer) {
+ $scope, $rootScope, dashboardKeybindings, filterSrv, dashboardSrv, panelMoveSrv, timer) {
$scope.editor = { index: 0 };
$scope.panelNames = config.panels;
@@ -26,7 +26,7 @@ function (angular, $, config, _) {
$rootScope.fullscreen = false;
- $scope.dashboard = dashboard.create(dashboardData);
+ $scope.dashboard = dashboardSrv.create(dashboardData);
$scope.grafana.style = $scope.dashboard.style;
$scope.filter = filterSrv;
@@ -107,16 +107,6 @@ function (angular, $, config, _) {
return $scope.editorTabs;
};
- $scope.colors = [
- "#7EB26D","#EAB839","#6ED0E0","#EF843C","#E24D42","#1F78C1","#BA43A9","#705DA0", //1
- "#508642","#CCA300","#447EBC","#C15C17","#890F02","#0A437C","#6D1F62","#584477", //2
- "#B7DBAB","#F4D598","#70DBED","#F9BA8F","#F29191","#82B5D8","#E5A8E2","#AEA2E0", //3
- "#629E51","#E5AC0E","#64B0C8","#E0752D","#BF1B00","#0A50A1","#962D82","#614D93", //4
- "#9AC48A","#F2C96D","#65C5DB","#F9934E","#EA6460","#5195CE","#D683CE","#806EB7", //5
- "#3F6833","#967302","#2F575E","#99440A","#58140C","#052B51","#511749","#3F2B5B", //6
- "#E0F9D7","#FCEACA","#CFFAFF","#F9E2D2","#FCE2DE","#BADFF4","#F9D9F9","#DEDAF7" //7
- ];
-
$scope.init();
});
});
diff --git a/src/app/controllers/grafanaCtrl.js b/src/app/controllers/grafanaCtrl.js
index c5efceeccd7..8254c02e9d9 100644
--- a/src/app/controllers/grafanaCtrl.js
+++ b/src/app/controllers/grafanaCtrl.js
@@ -29,6 +29,16 @@ function (angular, config, _) {
$rootScope.$emit(name, payload);
};
+ $rootScope.colors = [
+ "#7EB26D","#EAB839","#6ED0E0","#EF843C","#E24D42","#1F78C1","#BA43A9","#705DA0", //1
+ "#508642","#CCA300","#447EBC","#C15C17","#890F02","#0A437C","#6D1F62","#584477", //2
+ "#B7DBAB","#F4D598","#70DBED","#F9BA8F","#F29191","#82B5D8","#E5A8E2","#AEA2E0", //3
+ "#629E51","#E5AC0E","#64B0C8","#E0752D","#BF1B00","#0A50A1","#962D82","#614D93", //4
+ "#9AC48A","#F2C96D","#65C5DB","#F9934E","#EA6460","#5195CE","#D683CE","#806EB7", //5
+ "#3F6833","#967302","#2F575E","#99440A","#58140C","#052B51","#511749","#3F2B5B", //6
+ "#E0F9D7","#FCEACA","#CFFAFF","#F9E2D2","#FCE2DE","#BADFF4","#F9D9F9","#DEDAF7" //7
+ ];
+
$scope.init();
});
diff --git a/src/app/panels/graph/module.html b/src/app/panels/graph/module.html
index a61a632dd8e..8e27adf5c31 100644
--- a/src/app/panels/graph/module.html
+++ b/src/app/panels/graph/module.html
@@ -1,4 +1,4 @@
-
diff --git a/src/app/panels/graph/module.js b/src/app/panels/graph/module.js
index 8f8ad44c3dc..8daa773c620 100644
--- a/src/app/panels/graph/module.js
+++ b/src/app/panels/graph/module.js
@@ -19,6 +19,7 @@ define([
'kbn',
'moment',
'./timeSeries',
+ 'services/panelSrv',
'services/annotationsSrv',
'services/datasourceSrv',
'jquery.flot',
@@ -35,7 +36,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
var module = angular.module('grafana.panels.graph', []);
app.useModule(module);
- module.controller('graph', function($scope, $rootScope, $timeout, panelSrv, annotationsSrv) {
+ module.controller('GraphCtrl', function($scope, $rootScope, $timeout, panelSrv, annotationsSrv) {
$scope.panelMeta = {
modals : [],
@@ -190,12 +191,14 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
$scope.init = function() {
panelSrv.init($scope);
$scope.hiddenSeries = {};
- $scope.get_data();
+ if (!$scope.skipDataOnInit) {
+ $scope.get_data();
+ }
};
$scope.updateTimeRange = function () {
- $scope.range = this.filter.timeRange();
- $scope.rangeUnparsed = this.filter.timeRange(false);
+ $scope.range = $scope.filter.timeRange();
+ $scope.rangeUnparsed = $scope.filter.timeRange(false);
$scope.resolution = Math.ceil($(window).width() * ($scope.panel.span / 12));
$scope.interval = '10m';
@@ -264,7 +267,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
$scope.seriesHandler = function(seriesData, index) {
var datapoints = seriesData.datapoints;
var alias = seriesData.target;
- var color = $scope.panel.aliasColors[alias] || $scope.colors[index];
+ var color = $scope.panel.aliasColors[alias] || $rootScope.colors[index];
var yaxis = $scope.panel.aliasYAxis[alias] || 1;
var seriesInfo = {
diff --git a/src/app/panels/overview/module.html b/src/app/panels/overview/module.html
new file mode 100644
index 00000000000..cc682893a87
--- /dev/null
+++ b/src/app/panels/overview/module.html
@@ -0,0 +1,25 @@
+
+
+
hello
+
+
+
{{series.info.alias}}
+ {{series.info.avg}} Avg
+
+
+
+
+
+
+
diff --git a/src/app/panels/overview/module.js b/src/app/panels/overview/module.js
new file mode 100644
index 00000000000..0a3521a0566
--- /dev/null
+++ b/src/app/panels/overview/module.js
@@ -0,0 +1,107 @@
+define([
+ 'angular',
+ 'app',
+ 'lodash',
+ '../graph/timeSeries',
+ 'services/panelSrv',
+],
+function (angular, app, _, timeSeries) {
+ 'use strict';
+
+ var module = angular.module('grafana.panels.overview', []);
+ app.useModule(module);
+
+ module.controller('OverviewCtrl', function($scope, panelSrv) {
+
+ $scope.panelMeta = {
+ description : "A panel to show an overview of different metrics through avg, total, current numbers and sparklines",
+ fullEditorTabs : [
+ {
+ title: 'General',
+ src:'app/partials/panelgeneral.html'
+ },
+ {
+ title: 'Metrics',
+ src:'app/partials/metrics.html'
+ }
+ ],
+ fullscreenEdit: true,
+ };
+
+ // Set and populate defaults
+ var _d = {
+ targets: [{}]
+ };
+
+ _.defaults($scope.panel, _d);
+
+ $scope.init = function() {
+ panelSrv.init(this);
+
+ if (!$scope.skipDataOnInit) {
+ $scope.get_data();
+ }
+ //$scope.$on('refresh', $scope.render);
+ //$scope.render();
+ };
+
+ $scope.get_data = function() {
+ delete $scope.panel.error;
+ $scope.panelMeta.loading = true;
+
+ $scope.rangeUnparsed = $scope.filter.timeRange(false);
+
+ var metricsQuery = {
+ range: $scope.rangeUnparsed,
+ interval: '1min',
+ targets: $scope.panel.targets,
+ maxDataPoints: 100,
+ };
+
+ return $scope.datasource.query($scope.filter, metricsQuery)
+ .then($scope.dataHandler)
+ .then(null, function(err) {
+ $scope.panelMeta.loading = false;
+ $scope.panel.error = err.message || "Timeseries data request error";
+ $scope.inspector.error = err;
+ $scope.render([]);
+ });
+ };
+
+ $scope.dataHandler = function(results) {
+ $scope.panelMeta.loading = false;
+ $scope.series = _.map(results.data, $scope.seriesHandler);
+
+ console.log($scope.series);
+ };
+
+ $scope.seriesHandler = function(seriesData) {
+ var datapoints = seriesData.datapoints;
+ var alias = seriesData.target;
+
+ var seriesInfo = {
+ alias: alias,
+ enable: true,
+ };
+
+ var series = new timeSeries.ZeroFilled({
+ datapoints: datapoints,
+ info: seriesInfo,
+ });
+
+ series.points = series.getFlotPairs('connected', 'short');
+
+ return series;
+ };
+
+ $scope.render = function() {
+
+ };
+
+ $scope.openEditor = function() {
+ };
+
+ $scope.init();
+
+ });
+});
diff --git a/src/app/partials/solo-panel.html b/src/app/partials/solo-panel.html
new file mode 100644
index 00000000000..f349d32a716
--- /dev/null
+++ b/src/app/partials/solo-panel.html
@@ -0,0 +1,8 @@
+
+
diff --git a/src/app/routes/all.js b/src/app/routes/all.js
index 5342515d545..c09d09dc46f 100644
--- a/src/app/routes/all.js
+++ b/src/app/routes/all.js
@@ -1,5 +1,6 @@
define([
'./dashboard-from-db',
+ './solo-panel-route',
'./dashboard-from-file',
'./dashboard-from-script',
'./dashboard-default',
diff --git a/src/app/routes/solo-panel-route.js b/src/app/routes/solo-panel-route.js
new file mode 100644
index 00000000000..653ebdb31d6
--- /dev/null
+++ b/src/app/routes/solo-panel-route.js
@@ -0,0 +1,45 @@
+define([
+ 'angular',
+],
+function (angular) {
+ "use strict";
+
+ var module = angular.module('grafana.routes');
+
+ module.config(function($routeProvider) {
+ $routeProvider
+ .when('/solo-panel/db/:id', {
+ templateUrl: 'app/partials/solo-panel.html',
+ controller : 'SoloPanelCtrl',
+ });
+ });
+
+ module.controller('SoloPanelCtrl', function($scope, $rootScope, datasourceSrv, $routeParams, alertSrv, dashboardSrv, filterSrv) {
+
+ var db = datasourceSrv.getGrafanaDB();
+
+ db.getDashboard($routeParams.id, false)
+ .then(function(dashboardData) {
+ $scope.initPanelScope(dashboardData);
+ }).then(null, function(error) {
+ alertSrv.set('Error', error, 'error');
+ });
+
+ $scope.initPanelScope = function(dashboardData) {
+ $scope.dashboard = dashboardSrv.create(dashboardData);
+ $scope.grafana.style = $scope.dashboard.style;
+ $scope.row = {
+ height: '300px',
+ };
+ $scope.test = "Hej";
+ $scope.$index = 0;
+ $scope.panel = $scope.dashboard.rows[0].panels[0];
+ $scope.panel.span = 12;
+
+ $scope.filter = filterSrv;
+ $scope.filter.init($scope.dashboard);
+ };
+
+ });
+
+});
diff --git a/src/app/services/all.js b/src/app/services/all.js
index a9462629f5d..a1479355def 100644
--- a/src/app/services/all.js
+++ b/src/app/services/all.js
@@ -10,6 +10,6 @@ define([
'./playlistSrv',
'./unsavedChangesSrv',
'./dashboard/dashboardKeyBindings',
- './dashboard/dashboardModel',
+ './dashboard/dashboardSrv',
],
function () {});
diff --git a/src/app/services/dashboard/dashboardModel.js b/src/app/services/dashboard/dashboardSrv.js
similarity index 97%
rename from src/app/services/dashboard/dashboardModel.js
rename to src/app/services/dashboard/dashboardSrv.js
index ba8d24d097c..002f19cca15 100644
--- a/src/app/services/dashboard/dashboardModel.js
+++ b/src/app/services/dashboard/dashboardSrv.js
@@ -10,7 +10,7 @@ function (angular, $, kbn, _) {
var module = angular.module('grafana.services');
- module.service('dashboard', function(timer, $rootScope, $timeout) {
+ module.service('dashboardSrv', function(timer, $rootScope, $timeout) {
function DashboardModel (data) {
diff --git a/src/test/specs/dashboardModel-specs.js b/src/test/specs/dashboardSrv-specs.js
similarity index 89%
rename from src/test/specs/dashboardModel-specs.js
rename to src/test/specs/dashboardSrv-specs.js
index 5b92caafe46..6a43845a7d7 100644
--- a/src/test/specs/dashboardModel-specs.js
+++ b/src/test/specs/dashboardSrv-specs.js
@@ -1,5 +1,5 @@
define([
- 'services/dashboard/dashboardModel'
+ 'services/dashboard/dashboardSrv'
], function() {
'use strict';
@@ -8,8 +8,8 @@ define([
beforeEach(module('grafana.services'));
- beforeEach(inject(function(dashboard) {
- model = dashboard.create({});
+ beforeEach(inject(function(dashboardSrv) {
+ model = dashboardSrv.create({});
}));
it('should have title', function() {
@@ -30,8 +30,8 @@ define([
beforeEach(module('grafana.services'));
- beforeEach(inject(function(dashboard) {
- model = dashboard.create({
+ beforeEach(inject(function(dashboardSrv) {
+ model = dashboardSrv.create({
services: { filter: { time: { from: 'now-1d', to: 'now'}, list: [1] }},
rows: [
{
diff --git a/src/test/specs/graph-ctrl-specs.js b/src/test/specs/graph-ctrl-specs.js
new file mode 100644
index 00000000000..c01353feb62
--- /dev/null
+++ b/src/test/specs/graph-ctrl-specs.js
@@ -0,0 +1,44 @@
+define([
+ './helpers',
+ 'panels/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.get_data();
+ ctx.scope.$digest();
+ });
+
+ it('should build legend model', function() {
+ expect(ctx.scope.legend[0].alias).to.be('test.cpu1');
+ expect(ctx.scope.legend[1].alias).to.be('test.cpu2');
+ });
+
+ it('should send time series to render', function() {
+ var data = ctx.scope.render.getCall(0).args[0];
+ expect(data.length).to.be(2);
+ });
+
+ });
+ });
+
+});
+
diff --git a/src/test/specs/graph-panel-controller-specs.js b/src/test/specs/graph-panel-controller-specs.js
deleted file mode 100644
index 72c2934c4e5..00000000000
--- a/src/test/specs/graph-panel-controller-specs.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*define([
- 'panels/graphite/module'
-], function() {
- 'use strict';
-
- describe('Graph panel controller', function() {
- var _graphPanelCtrl;
-
- beforeEach(module('grafana.panels.graphite'));
- beforeEach(module(function($provide){
- $provide.value('filterSrv',{});
- }));
-
- beforeEach(inject(function($controller, $rootScope) {
- _graphPanelCtrl = $controller('graphite', {
- $scope: $rootScope.$new()
- });
- }));
-
- describe('init', function() {
- beforeEach(function() {
- });
-
- it('asd', function() {
-
- });
- });
- });
-
-});
-*/
\ No newline at end of file
diff --git a/src/test/specs/helpers.js b/src/test/specs/helpers.js
index 5c5fc3edfc3..5ca005adcad 100644
--- a/src/test/specs/helpers.js
+++ b/src/test/specs/helpers.js
@@ -1,11 +1,14 @@
define([
-], function() {
+ 'kbn'
+], function(kbn) {
'use strict';
function ControllerTestContext() {
var self = this;
+ this.timeRange = { from:'now-1h', to: 'now'};
this.datasource = {};
+ this.annotationsSrv = {};
this.datasourceSrv = {
getMetricSources: function() {},
get: function() { return self.datasource; }
@@ -14,6 +17,7 @@ define([
this.providePhase = function() {
return module(function($provide) {
$provide.value('datasourceSrv', self.datasourceSrv);
+ $provide.value('annotationsSrv', self.annotationsSrv);
});
};
@@ -22,9 +26,20 @@ define([
self.scope = $rootScope.$new();
self.scope.panel = {};
self.scope.filter = {
- timeRange: function() {}
+ timeRange: function(parse) {
+ if (!parse) {
+ return self.timeRange;
+ }
+ return {
+ from : kbn.parseDate(self.timeRange.from),
+ to : kbn.parseDate(self.timeRange.to)
+ };
+ }
};
+ $rootScope.colors = [];
+ for (var i = 0; i < 50; i++) { $rootScope.colors.push('#' + i); }
+
self.$q = $q;
self.scope.skipDataOnInit = true;
self.controller = $controller(controllerName, {
diff --git a/src/test/specs/overview-ctrl-specs.js b/src/test/specs/overview-ctrl-specs.js
new file mode 100644
index 00000000000..777dc2bc033
--- /dev/null
+++ b/src/test/specs/overview-ctrl-specs.js
@@ -0,0 +1,30 @@
+define([
+ './helpers',
+ 'panels/overview/module'
+], function(helpers) {
+ 'use strict';
+
+ describe('OverviewCtrl', function() {
+ var ctx = new helpers.ControllerTestContext();
+
+ beforeEach(module('grafana.services'));
+ beforeEach(module('grafana.panels.overview'));
+
+ beforeEach(ctx.providePhase());
+ beforeEach(ctx.createControllerPhase('OverviewCtrl'));
+
+ describe('when query return error', function() {
+ beforeEach(function() {
+ ctx.datasource.query = function() {
+ return ctx.$q.reject({ message: 'Some error' });
+ };
+ ctx.scope.get_data();
+ ctx.scope.$digest();
+ });
+
+ it('panel.error should be set', function() {
+ expect(ctx.scope.panel.error).to.be("Some error");
+ });
+ });
+ });
+});
diff --git a/src/test/test-main.js b/src/test/test-main.js
index b0ea2988bcd..cd494dba1b5 100644
--- a/src/test/test-main.js
+++ b/src/test/test-main.js
@@ -118,10 +118,12 @@ require([
'specs/parser-specs',
'specs/gfunc-specs',
'specs/graphiteTargetCtrl-specs',
+ 'specs/graph-ctrl-specs',
'specs/filterSrv-specs',
'specs/kbn-format-specs',
- 'specs/dashboardModel-specs',
- 'specs/influxSeries-specs'
+ 'specs/dashboardSrv-specs',
+ 'specs/influxSeries-specs',
+ 'specs/overview-ctrl-specs',
], function () {
window.__karma__.start();
});