소스 검색

feat(live): panel sdk/api refactorings

Torkel Ödegaard 9 년 전
부모
커밋
cb49e11eca

+ 0 - 5
public/app/features/dashboard/rowCtrl.js

@@ -30,11 +30,6 @@ function (angular, _, config) {
 
     $scope.toggleRow = function(row) {
       row.collapse = row.collapse ? false : true;
-      if (!row.collapse) {
-        $timeout(function() {
-          $scope.$broadcast('render');
-        });
-      }
     };
 
     $scope.addPanel = function(panel) {

+ 19 - 33
public/app/features/panel/metrics_panel_ctrl.ts

@@ -53,21 +53,14 @@ class MetricsPanelCtrl extends PanelCtrl {
     this.datasources = this.datasourceSrv.getMetricSources();
   }
 
-  loadSnapshot(data) {
-    // null op
-    return data;
-  }
-
   refresh() {
     // ignore fetching data if another panel is in fullscreen
     if (this.otherPanelInFullscreenMode()) { return; }
 
     // if we have snapshot data use that
     if (this.panel.snapshotData) {
-      if (this.loadSnapshot) {
-        this.updateTimeRange();
-        this.loadSnapshot(this.panel.snapshotData);
-      }
+      this.updateTimeRange();
+      this.events.emit('load-snapshot', this.panel.snapshotData);
       return;
     }
 
@@ -83,15 +76,13 @@ class MetricsPanelCtrl extends PanelCtrl {
     // load datasource service
     this.datasourceSrv.get(this.panel.datasource)
     .then(this.issueQueries.bind(this))
-    .then(() => {
-      this.loading = false;
-    }).catch(err => {
-      console.log('Panel data error:', err);
+    .then(this.handleQueryResult.bind(this))
+    .catch(err => {
       this.loading = false;
       this.error = err.message || "Timeseries data request error";
       this.inspector = {error: err};
-
       this.events.emit('data-error', err);
+      console.log('Panel data error:', err);
     });
   }
 
@@ -184,29 +175,24 @@ class MetricsPanelCtrl extends PanelCtrl {
     };
 
     this.setTimeQueryStart();
-    try {
-      return datasource.query(metricsQuery).then(results => {
-        this.setTimeQueryEnd();
-
-        // check for if data source returns subject
-        if (results && results.subscribe) {
-          this.handleDataStream(results);
-          return;
-        }
+    return datasource.query(metricsQuery);
+  }
 
-        if (this.dashboard.snapshot) {
-          this.panel.snapshotData = results;
-        }
+  handleQueryResult(result) {
+    this.setTimeQueryEnd();
+    this.loading = false;
 
-        return this.events.emit('data-received', results);
-      });
-    } catch (err) {
-      return this.$q.reject(err);
+    // check for if data source returns subject
+    if (result && result.subscribe) {
+      this.handleDataStream(result);
+      return;
+    }
+
+    if (this.dashboard.snapshot) {
+      this.panel.snapshotData = result;
     }
-  }
 
-  dataHandler(data) {
-    return data;
+    return this.events.emit('data-received', result.data);
   }
 
   handleDataStream(stream) {

+ 1 - 1
public/app/features/panel/panel_directive.ts

@@ -121,7 +121,7 @@ module.directive('panelResizer', function($rootScope) {
         }
 
         scope.$apply(function() {
-          ctrl.broadcastRender();
+          ctrl.render();
         });
       }
 

+ 24 - 28
public/app/plugins/datasource/graphite/datasource.ts

@@ -16,38 +16,34 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
   this.render_method = instanceSettings.render_method || 'POST';
 
   this.query = function(options) {
-    try {
-      var graphOptions = {
-        from: this.translateTime(options.rangeRaw.from, false),
-        until: this.translateTime(options.rangeRaw.to, true),
-        targets: options.targets,
-        format: options.format,
-        cacheTimeout: options.cacheTimeout || this.cacheTimeout,
-        maxDataPoints: options.maxDataPoints,
-      };
-
-      var params = this.buildGraphiteParams(graphOptions, options.scopedVars);
-      if (params.length === 0) {
-        return $q.when([]);
-      }
-
-      if (options.format === 'png') {
-        return $q.when(this.url + '/render' + '?' + params.join('&'));
-      }
+    var graphOptions = {
+      from: this.translateTime(options.rangeRaw.from, false),
+      until: this.translateTime(options.rangeRaw.to, true),
+      targets: options.targets,
+      format: options.format,
+      cacheTimeout: options.cacheTimeout || this.cacheTimeout,
+      maxDataPoints: options.maxDataPoints,
+    };
+
+    var params = this.buildGraphiteParams(graphOptions, options.scopedVars);
+    if (params.length === 0) {
+      return $q.when([]);
+    }
 
-      var httpOptions: any = {method: this.render_method, url: '/render'};
+    if (options.format === 'png') {
+      return $q.when(this.url + '/render' + '?' + params.join('&'));
+    }
 
-      if (httpOptions.method === 'GET') {
-        httpOptions.url = httpOptions.url + '?' + params.join('&');
-      } else {
-        httpOptions.data = params.join('&');
-        httpOptions.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
-      }
+    var httpOptions: any = {method: this.render_method, url: '/render'};
 
-      return this.doGraphiteRequest(httpOptions).then(this.convertDataPointsToMs);
-    } catch (err) {
-      return $q.reject(err);
+    if (httpOptions.method === 'GET') {
+      httpOptions.url = httpOptions.url + '?' + params.join('&');
+    } else {
+      httpOptions.data = params.join('&');
+      httpOptions.headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
     }
+
+    return this.doGraphiteRequest(httpOptions).then(this.convertDataPointsToMs);
   };
 
   this.convertDataPointsToMs = function(result) {

+ 4 - 4
public/app/plugins/panel/graph/module.ts

@@ -160,17 +160,17 @@ class GraphCtrl extends MetricsPanelCtrl {
     this.render([]);
   }
 
-  onDataReceived(results) {
+  onDataReceived(dataList) {
     // png renderer returns just a url
-    if (_.isString(results)) {
-      this.render(results);
+    if (_.isString(dataList)) {
+      this.render(dataList);
       return;
     }
 
     this.datapointsWarning = false;
     this.datapointsCount = 0;
     this.datapointsOutside = false;
-    this.seriesList = _.map(results.data, (series, i) => this.seriesHandler(series, i));
+    this.seriesList = dataList.map(this.seriesHandler.bind(this));
     this.datapointsWarning = this.datapointsCount === 0 || this.datapointsOutside;
 
     this.annotationsPromise.then(annotations => {

+ 24 - 61
public/app/plugins/panel/graph/specs/graph_ctrl_specs.ts

@@ -14,47 +14,19 @@ describe('GraphCtrl', function() {
 
   beforeEach(ctx.providePhase());
   beforeEach(ctx.createPanelController(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.ctrl.render = sinon.spy();
-      ctx.ctrl.refreshData(ctx.datasource);
-      ctx.scope.$digest();
-    });
-
-    it('should send time series to render', function() {
-      var data = ctx.ctrl.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.ctrl.refreshData(ctx.datasource);
-        ctx.scope.$digest();
-      });
-
-    });
+  beforeEach(() => {
+    ctx.ctrl.annotationsPromise = Promise.resolve({});
+    ctx.ctrl.updateTimeRange();
   });
 
   describe('msResolution with second resolution timestamps', function() {
     beforeEach(function() {
-      ctx.datasource.query = sinon.stub().returns(ctx.$q.when({
-        data: [
-          { target: 'test.cpu1', datapoints: [[1234567890, 45], [1234567899, 60]]},
-          { target: 'test.cpu2', datapoints: [[1236547890, 55], [1234456709, 90]]}
-        ]
-      }));
+      var data = [
+        { target: 'test.cpu1', datapoints: [[1234567890, 45], [1234567899, 60]]},
+        { target: 'test.cpu2', datapoints: [[1236547890, 55], [1234456709, 90]]}
+      ];
       ctx.ctrl.panel.tooltip.msResolution = false;
-      ctx.ctrl.refreshData(ctx.datasource);
-      ctx.scope.$digest();
+      ctx.ctrl.onDataReceived(data);
     });
 
     it('should not show millisecond resolution tooltip', function() {
@@ -64,15 +36,12 @@ describe('GraphCtrl', function() {
 
   describe('msResolution with millisecond resolution timestamps', function() {
     beforeEach(function() {
-      ctx.datasource.query = sinon.stub().returns(ctx.$q.when({
-        data: [
-          { target: 'test.cpu1', datapoints: [[1234567890000, 45], [1234567899000, 60]]},
-          { target: 'test.cpu2', datapoints: [[1236547890001, 55], [1234456709000, 90]]}
-        ]
-      }));
+      var data = [
+        { target: 'test.cpu1', datapoints: [[1234567890000, 45], [1234567899000, 60]]},
+        { target: 'test.cpu2', datapoints: [[1236547890001, 55], [1234456709000, 90]]}
+      ];
       ctx.ctrl.panel.tooltip.msResolution = false;
-      ctx.ctrl.refreshData(ctx.datasource);
-      ctx.scope.$digest();
+      ctx.ctrl.onDataReceived(data);
     });
 
     it('should show millisecond resolution tooltip', function() {
@@ -82,15 +51,12 @@ describe('GraphCtrl', function() {
 
   describe('msResolution with millisecond resolution timestamps but with trailing zeroes', function() {
     beforeEach(function() {
-      ctx.datasource.query = sinon.stub().returns(ctx.$q.when({
-        data: [
-          { target: 'test.cpu1', datapoints: [[1234567890000, 45], [1234567899000, 60]]},
-          { target: 'test.cpu2', datapoints: [[1236547890000, 55], [1234456709000, 90]]}
-        ]
-      }));
+      var data = [
+        { target: 'test.cpu1', datapoints: [[1234567890000, 45], [1234567899000, 60]]},
+        { target: 'test.cpu2', datapoints: [[1236547890000, 55], [1234456709000, 90]]}
+      ];
       ctx.ctrl.panel.tooltip.msResolution = false;
-      ctx.ctrl.refreshData(ctx.datasource);
-      ctx.scope.$digest();
+      ctx.ctrl.onDataReceived(data);
     });
 
     it('should not show millisecond resolution tooltip', function() {
@@ -100,16 +66,13 @@ describe('GraphCtrl', function() {
 
   describe('msResolution with millisecond resolution timestamps in one of the series', function() {
     beforeEach(function() {
-      ctx.datasource.query = sinon.stub().returns(ctx.$q.when({
-        data: [
-          { target: 'test.cpu1', datapoints: [[1234567890000, 45], [1234567899000, 60]]},
-          { target: 'test.cpu2', datapoints: [[1236547890010, 55], [1234456709000, 90]]},
-          { target: 'test.cpu3', datapoints: [[1236547890000, 65], [1234456709000, 120]]}
-        ]
-      }));
+      var data = [
+        { target: 'test.cpu1', datapoints: [[1234567890000, 45], [1234567899000, 60]]},
+        { target: 'test.cpu2', datapoints: [[1236547890010, 55], [1234456709000, 90]]},
+        { target: 'test.cpu3', datapoints: [[1236547890000, 65], [1234456709000, 120]]}
+      ];
       ctx.ctrl.panel.tooltip.msResolution = false;
-      ctx.ctrl.refreshData(ctx.datasource);
-      ctx.scope.$digest();
+      ctx.ctrl.onDataReceived(data);
     });
 
     it('should show millisecond resolution tooltip', function() {

+ 20 - 27
public/app/plugins/panel/singlestat/module.ts

@@ -45,7 +45,7 @@ class SingleStatCtrl extends MetricsPanelCtrl {
   static templateUrl = 'module.html';
 
   series: any[];
-  data: any[];
+  data: any;
   fontSizes: any[];
   unitFormats: any[];
 
@@ -53,6 +53,9 @@ class SingleStatCtrl extends MetricsPanelCtrl {
   constructor($scope, $injector, private $location, private linkSrv) {
     super($scope, $injector);
     _.defaults(this.panel, panelDefaults);
+
+    this.events.on('data-received', this.onDataReceived.bind(this));
+    this.events.on('data-error', this.onDataError.bind(this));
   }
 
   initEditMode() {
@@ -68,23 +71,27 @@ class SingleStatCtrl extends MetricsPanelCtrl {
     this.render();
   }
 
-  refreshData(datasource) {
-    return this.issueQueries(datasource)
-      .then(this.dataHandler.bind(this))
-      .catch(err => {
-        this.series = [];
-        this.render();
-        throw err;
-      });
-  }
-
   loadSnapshot(snapshotData) {
     // give element time to get attached and get dimensions
     this.$timeout(() => this.dataHandler(snapshotData), 50);
   }
 
-  dataHandler(results) {
-    this.series = _.map(results.data, this.seriesHandler.bind(this));
+  onDataError(err) {
+    this.onDataReceived({data: []});
+  }
+
+  onDataReceived(dataList) {
+    this.series = dataList.map(this.seriesHandler.bind(this));
+
+    var data: any = {};
+    this.setValues(data);
+
+    data.thresholds = this.panel.thresholds.split(',').map(function(strVale) {
+      return Number(strVale.trim());
+    });
+
+    data.colorMap = this.panel.colors;
+    this.data = data;
     this.render();
   }
 
@@ -155,20 +162,6 @@ class SingleStatCtrl extends MetricsPanelCtrl {
     return result;
   }
 
-  render() {
-    var data: any = {};
-    this.setValues(data);
-
-    data.thresholds = this.panel.thresholds.split(',').map(function(strVale) {
-      return Number(strVale.trim());
-    });
-
-    data.colorMap = this.panel.colors;
-
-    this.data = data;
-    this.broadcastRender();
-  }
-
   setValues(data) {
     data.flotpairs = [];
 

+ 4 - 5
public/app/plugins/panel/singlestat/specs/singlestat-specs.ts

@@ -23,12 +23,11 @@ describe('SingleStatCtrl', function() {
 
         beforeEach(function() {
           setupFunc();
-          ctx.datasource.query = sinon.stub().returns(ctx.$q.when({
-            data: [{target: 'test.cpu1', datapoints: ctx.datapoints}]
-          }));
+          var data = [
+            {target: 'test.cpu1', datapoints: ctx.datapoints}
+          ];
 
-          ctx.ctrl.refreshData(ctx.datasource);
-          ctx.scope.$digest();
+          ctx.ctrl.onDataReceived(data);
           ctx.data = ctx.ctrl.data;
         });
       };

+ 26 - 25
public/app/plugins/panel/table/module.ts

@@ -57,6 +57,9 @@ class TablePanelCtrl extends MetricsPanelCtrl {
     }
 
     _.defaults(this.panel, panelDefaults);
+
+    this.events.on('data-received', this.onDataReceived.bind(this));
+    this.events.on('data-error', this.onDataError.bind(this));
   }
 
   initEditMode() {
@@ -70,7 +73,7 @@ class TablePanelCtrl extends MetricsPanelCtrl {
     return menu;
   }
 
-  refreshData(datasource) {
+  issueQueries(datasource) {
     this.pageIndex = 0;
 
     if (this.panel.transform === 'annotations') {
@@ -80,36 +83,19 @@ class TablePanelCtrl extends MetricsPanelCtrl {
       });
     }
 
-    return this.issueQueries(datasource).catch(err => {
-      this.render();
-      throw err;
-    });
+    return super.issueQueries(datasource);
   }
 
-  toggleColumnSort(col, colIndex) {
-    if (this.panel.sort.col === colIndex) {
-      if (this.panel.sort.desc) {
-        this.panel.sort.desc = false;
-      } else {
-        this.panel.sort.col = null;
-      }
-    } else {
-      this.panel.sort.col = colIndex;
-      this.panel.sort.desc = true;
-    }
-
+  onDataError(err) {
+    this.dataRaw = [];
     this.render();
   }
 
-  dataHandler(results) {
-    this.dataRaw = results.data;
+  onDataReceived(dataList) {
+    this.dataRaw = dataList;
     this.pageIndex = 0;
-    this.render();
-  }
 
-  render() {
-    // automatically correct transform mode
-    // based on data
+    // automatically correct transform mode based on data
     if (this.dataRaw && this.dataRaw.length) {
       if (this.dataRaw[0].type === 'table') {
         this.panel.transform = 'table';
@@ -126,7 +112,22 @@ class TablePanelCtrl extends MetricsPanelCtrl {
 
     this.table = transformDataToTable(this.dataRaw, this.panel);
     this.table.sort(this.panel.sort);
-    this.broadcastRender(this.table);
+    this.render(this.table);
+  }
+
+  toggleColumnSort(col, colIndex) {
+    if (this.panel.sort.col === colIndex) {
+      if (this.panel.sort.desc) {
+        this.panel.sort.desc = false;
+      } else {
+        this.panel.sort.col = null;
+      }
+    } else {
+      this.panel.sort.col = colIndex;
+      this.panel.sort.desc = true;
+    }
+
+    this.render();
   }
 
   exportCsv() {