changeset 204:cb5eb207b5cc

Restore multicharts Y1/Y2 axis functionality Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-September/024985.html
author Andrew Azores <aazores@redhat.com>
date Fri, 15 Sep 2017 12:17:08 -0400
parents 55b433cf6922
children 599c230e22e5
files src/app/components/multichart/chart/chart.controller.js src/app/components/multichart/chart/chart.controller.spec.js src/app/components/multichart/chart/chart.html src/app/components/multichart/multichart.html src/app/shared/services/multichart.service.js src/app/shared/services/multichart.service.spec.js
diffstat 6 files changed, 103 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- a/src/app/components/multichart/chart/chart.controller.js	Tue Sep 12 10:27:01 2017 -0400
+++ b/src/app/components/multichart/chart/chart.controller.js	Fri Sep 15 12:17:08 2017 -0400
@@ -30,23 +30,29 @@
 import filters from 'shared/filters/filters.module.js';
 
 class MultichartChartController {
-  constructor (multichartService, $scope, $interval, dateFilter, DATE_FORMAT, $translate) {
+  constructor (multichartService, $interval, dateFilter, DATE_FORMAT, $translate) {
     this.svc = multichartService;
     this.interval = $interval;
     this.dateFilter = dateFilter;
     this.dateFormat = DATE_FORMAT;
     this.translate = $translate;
-    this.chart = $scope.$parent.chart;
-
-    this.initializeChartData();
-
-    $scope.$on('$destroy', () => this.stop());
 
     this._refreshRate = 2000;
     this._dataAgeLimit = 60000;
+  }
 
-    this.refresh = $interval(() => this.update(), this._refreshRate);
+  $onInit () {
+    this.initializeChartData().then(() => this.start());
+  }
+
+  $onDestroy () {
+    this.stop();
+  }
+
+  start () {
+    this.stop();
     this.update();
+    this.refresh = this.interval(() => this.update(), this._refreshRate);
   }
 
   update () {
@@ -56,15 +62,11 @@
         return;
       }
 
-      this.chartData.xData.push(Date.now());
-      keys.forEach(prop => {
-        if (this.chartData.hasOwnProperty(prop)) {
-          this.chartData[prop].push(data[prop][1]);
-        } else {
-          this.chartData[prop] = data[prop];
-        }
+      let update = [Date.now()];
+      keys.forEach(key => {
+        update.push(data[key][1]);
       });
-      this.chartConfig.data.axes = this.svc.getAxesForChart(this.chart);
+      this.chartConfig.data.rows.push(update);
 
       this.trimData();
     }, angular.noop);
@@ -78,21 +80,13 @@
   }
 
   trimData () {
-    if (!angular.isDefined(this.chartData)) {
-      return;
-    }
     let now = Date.now();
     let oldestLimit = now - this._dataAgeLimit;
 
-    while (true) {
-      if (this.chartData.xData.length <= 2) {
-        break;
-      }
-      let oldest = this.chartData.xData[1];
-      if (oldest < oldestLimit) {
-        Object.keys(this.chartData).forEach(key => {
-          this.chartData[key].splice(1, 1);
-        });
+    while (this.chartConfig.data.rows.length > 2) {
+      let oldest = this.chartConfig.data.rows[1];
+      if (oldest[0] < oldestLimit) {
+        this.chartConfig.data.rows.splice(1, 1);
       } else {
         break;
       }
@@ -100,13 +94,18 @@
   }
 
   initializeChartData () {
-    this.translate([
+    return this.translate([
       'multicharts.chart.X_AXIS_LABEL',
       'multicharts.chart.X_AXIS_DATA_TYPE'
     ]).then(translations => {
       let self = this;
       this.chartConfig = {
         chartId: 'chart-' + this.chart,
+        grid: {
+          y: {
+            show: true
+          }
+        },
         axis: {
           x: {
             label: translations['multicharts.chart.X_AXIS_LABEL'],
@@ -128,6 +127,11 @@
             }
           }
         },
+        data: {
+          x: translations['multicharts.chart.X_AXIS_DATA_TYPE'],
+          axes: this.svc.getAxesForChart(this.chart),
+          rows: [[translations['multicharts.chart.X_AXIS_DATA_TYPE']].concat(this.svc.getServicesForChart(this.chart))]
+        },
         tooltip: {
           format: {
             title: x => x,
@@ -135,9 +139,6 @@
           }
         }
       };
-      this.chartData = {
-        xData: [translations['multicharts.chart.X_AXIS_DATA_TYPE']]
-      };
     });
   }
 
--- a/src/app/components/multichart/chart/chart.controller.spec.js	Tue Sep 12 10:27:01 2017 -0400
+++ b/src/app/components/multichart/chart/chart.controller.spec.js	Fri Sep 15 12:17:08 2017 -0400
@@ -29,7 +29,7 @@
 
 describe('multichart chartController', () => {
 
-  let ctrl, svc, scope, interval, dateFilter, translate;
+  let ctrl, svc, interval, dateFilter, translate;
   beforeEach(() => {
     angular.mock.module(controllerModule);
     angular.mock.inject($controller => {
@@ -44,16 +44,10 @@
         getDataPromise: getDataPromise,
         getAxesForChart: sinon.stub().returns(['y']),
         countServicesForChart: sinon.stub().returns(2),
+        getServicesForChart: sinon.stub().returns(['foo-svc', 'bar-svc']),
         removeChart: sinon.spy(),
         rename: sinon.spy()
       };
-      scope = {
-        $parent: {
-          chart: 'foo-chart'
-        },
-        $on: sinon.spy(),
-        $watch: sinon.spy()
-      };
       interval = sinon.stub().returns('interval-sentinel');
       interval.cancel = sinon.spy();
       dateFilter = sinon.stub().returns('dateFilter-sentinel');
@@ -61,18 +55,20 @@
         then: sinon.stub().yields({
           'multicharts.chart.X_AXIS_LABEL': 'timestamp',
           'multicharts.chart.X_AXIS_DATA_TYPE': 'timestamp'
+        }).returns({
+          then: sinon.stub().yields()
         })
       });
 
       ctrl = $controller('MultichartChartController', {
         multichartService: svc,
-        $scope: scope,
         $interval: interval,
         dateFilter: dateFilter,
         DATE_FORMAT: { time: { medium: 'medium-time' } },
         $translate: translate
       });
-      ctrl.chartConfig.data = {};
+      ctrl.chart = 'foo-chart';
+      ctrl.$onInit();
     });
   });
 
@@ -81,13 +77,8 @@
   });
 
   it('should stop on destroy', () => {
-    scope.$on.should.be.calledWith('$destroy');
-    scope.$on.callCount.should.equal(1);
-    let fn = scope.$on.args[0][1];
-    fn.should.be.a.Function();
-
     interval.cancel.should.not.be.called();
-    fn();
+    ctrl.$onDestroy();
     interval.cancel.should.be.calledOnce();
     interval.cancel.should.be.calledWith('interval-sentinel');
   });
@@ -126,40 +117,35 @@
 
     it('should pass chart ID', () => {
       ctrl.update();
-      svc.getData.should.be.calledWith(scope.$parent.chart);
+      svc.getData.should.be.calledWith(ctrl.chart);
     });
 
     it('should do nothing if data is empty', () => {
-      ctrl.chartData.xData.length.should.equal(1);
+      ctrl.chartConfig.data.rows.length.should.equal(1);
       fn({});
-      ctrl.chartData.xData.length.should.equal(1);
+      ctrl.chartConfig.data.rows.length.should.equal(1);
     });
 
     it('should append new data', () => {
-      ctrl.chartData.xData.length.should.equal(1);
+      ctrl.chartConfig.data.rows.length.should.equal(1);
       ctrl.should.not.have.ownProperty('yData');
       fn({
         yData: ['someMetric', 100]
       });
-      ctrl.chartData.xData.length.should.equal(2);
-      ctrl.chartData.should.have.ownProperty('yData');
-      ctrl.chartData.yData.length.should.equal(2);
+      ctrl.chartConfig.data.rows.length.should.equal(2);
+      ctrl.chartConfig.data.rows[1][1].should.equal(100);
     });
 
     it('should append data for existing metric', () => {
-      ctrl.chartData.xData.length.should.equal(1);
-      ctrl.should.not.have.ownProperty('yData');
+      ctrl.chartConfig.data.rows.length.should.equal(1);
       fn({
         yData: ['someMetric', 100]
       });
-      ctrl.chartData.xData.length.should.equal(2);
-      ctrl.chartData.should.have.ownProperty('yData');
-      ctrl.chartData.yData.length.should.equal(2);
+      ctrl.chartConfig.data.rows.length.should.equal(2);
       fn({
         yData: ['someMetric', 200]
       });
-      ctrl.chartData.xData.length.should.equal(3);
-      ctrl.chartData.yData.length.should.equal(3);
+      ctrl.chartConfig.data.rows.length.should.equal(3);
     });
   });
 
@@ -173,17 +159,9 @@
       Date.now.restore();
     });
 
-    it('should do nothing if chartData undefined', () => {
-      delete ctrl.chartData;
-      ctrl.trimData();
-      should(ctrl.chartData).be.undefined();
-    });
-
     it('should do nothing if no samples', () => {
       ctrl.trimData();
-      ctrl.chartData.should.eql({
-        xData: ['timestamp']
-      });
+      ctrl.chartConfig.data.rows.should.deepEqual([['timestamp', 'foo-svc', 'bar-svc']]);
     });
 
     it('should not trim data if only one sample', () => {
@@ -192,18 +170,17 @@
 
       dateNowStub.returns(100);
       updateFn({
-        yData: ['foo', 500],
-        yData1: ['bar', 5000]
+        yData: ['foo-svc', 500],
+        yData1: ['bar-svc', 5000]
       });
 
       dateNowStub.returns(200);
       ctrl.trimData();
 
-      ctrl.chartData.should.eql({
-        xData: ['timestamp', 100],
-        yData: ['foo', 500],
-        yData1: ['bar', 5000]
-      });
+      ctrl.chartConfig.data.rows.should.deepEqual([
+        ['timestamp', 'foo-svc', 'bar-svc'],
+        [100, 500, 5000]
+      ]);
     });
 
     it('should trim old data', () => {
@@ -230,19 +207,20 @@
 
       dateNowStub.returns(350);
 
-      ctrl.chartData.should.eql({
-        xData: ['timestamp', 100, 200, 300],
-        yData: ['foo', 500, 600, 700],
-        yData1: ['bar', 5000, 6000, 7000]
-      });
+      ctrl.chartConfig.data.rows.should.deepEqual([
+        ['timestamp', 'foo-svc', 'bar-svc'],
+        [100, 500, 5000],
+        [200, 600, 6000],
+        [300, 700, 7000]
+      ]);
 
       ctrl.trimData();
 
-      ctrl.chartData.should.eql({
-        xData: ['timestamp', 200, 300],
-        yData: ['foo', 600, 700],
-        yData1: ['bar', 6000, 7000]
-      });
+      ctrl.chartConfig.data.rows.should.deepEqual([
+        ['timestamp', 'foo-svc', 'bar-svc'],
+        [200, 600, 6000],
+        [300, 700, 7000]
+      ]);
     });
   });
 
--- a/src/app/components/multichart/chart/chart.html	Tue Sep 12 10:27:01 2017 -0400
+++ b/src/app/components/multichart/chart/chart.html	Fri Sep 15 12:17:08 2017 -0400
@@ -57,11 +57,7 @@
   </div>
 
   <div class="card-pf-body" ng-if="$ctrl.chartConfig">
-    <pf-line-chart id="chart-{{$ctrl.chart}}" config="$ctrl.chartConfig"
-                                        chart-data="$ctrl.chartData"
-                                        show-x-axis="true"
-                                        show-y-axis="true"
-                                        ></pf-line-chart>
+    <pf-c3-chart id="chart-{{$ctrl.chart}}" config="$ctrl.chartConfig"></pf-c3-chart>
 
 
   </div>
--- a/src/app/components/multichart/multichart.html	Tue Sep 12 10:27:01 2017 -0400
+++ b/src/app/components/multichart/multichart.html	Fri Sep 15 12:17:08 2017 -0400
@@ -22,7 +22,7 @@
 
         <div ng-repeat="chart in $ctrl.chartNames">
           <div class="col-xs-12 col-md-10">
-            <multichart-chart></multichart-chart>
+            <multichart-chart chart="chart"></multichart-chart>
           </div>
         </div>
 
--- a/src/app/shared/services/multichart.service.js	Tue Sep 12 10:27:01 2017 -0400
+++ b/src/app/shared/services/multichart.service.js	Fri Sep 15 12:17:08 2017 -0400
@@ -73,6 +73,16 @@
     return ret;
   }
 
+  getServicesForChart (chartName) {
+    if (!this.hasChart(chartName)) {
+      return [];
+    }
+    let charts = this.charts.get(chartName);
+    let res = [];
+    charts.forEach(chart => res.push(chart.svcName));
+    return res;
+  }
+
   addChart (chartName) {
     if (this.charts.has(chartName)) {
       return;
--- a/src/app/shared/services/multichart.service.spec.js	Tue Sep 12 10:27:01 2017 -0400
+++ b/src/app/shared/services/multichart.service.spec.js	Fri Sep 15 12:17:08 2017 -0400
@@ -339,4 +339,29 @@
     });
   });
 
+  describe('getServicesForChart', () => {
+    it('should be empty for non-existent chart', () => {
+      svc.getServicesForChart('foo').should.deepEqual([]);
+    });
+
+    it('should be empty initially', () => {
+      svc.addChart('foo');
+      svc.getServicesForChart('foo').should.deepEqual([]);
+    });
+
+    it('should reflect added service names', () => {
+      svc.addChart('foo');
+      svc.addService('foo', 'foo-svc', angular.noop);
+      svc.getServicesForChart('foo').should.deepEqual(['foo-svc']);
+    });
+
+    it('should reflect removed service names', () => {
+      svc.addChart('foo');
+      svc.addService('foo', 'foo-svc', angular.noop);
+      svc.addService('foo', 'foo-svc-2', angular.noop);
+      svc.removeService('foo', 'foo-svc');
+      svc.getServicesForChart('foo').should.deepEqual(['foo-svc-2']);
+    });
+  });
+
 });