Repository: eagle
Updated Branches:
  refs/heads/master 5e4c937e3 -> ce53540f3


[EAGLE-884] JPM support queue trend view

* Add trend chart
* support queue drill down
* Capacity base line

Author: zombieJ <[email protected]>

Closes #794 from zombieJ/EAGLE-884.


Project: http://git-wip-us.apache.org/repos/asf/eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/eagle/commit/ce53540f
Tree: http://git-wip-us.apache.org/repos/asf/eagle/tree/ce53540f
Diff: http://git-wip-us.apache.org/repos/asf/eagle/diff/ce53540f

Branch: refs/heads/master
Commit: ce53540f3d3128ed9aeec2112d184fa214edca45
Parents: 5e4c937
Author: zombieJ <[email protected]>
Authored: Tue Feb 7 17:35:43 2017 +0800
Committer: zombieJ <[email protected]>
Committed: Tue Feb 7 17:35:43 2017 +0800

----------------------------------------------------------------------
 .../main/webapp/app/apps/jpm/ctrl/queueCtrl.js  | 230 +++++++++++++++++++
 .../src/main/webapp/app/apps/jpm/index.js       |  46 ++--
 .../app/apps/jpm/partials/queue/overview.html   |  57 +++++
 .../main/webapp/app/apps/jpm/style/index.css    |   8 +
 eagle-server/src/main/webapp/app/dev/index.html |   6 +-
 .../src/main/webapp/app/dev/public/css/main.css |   9 +
 .../app/dev/public/js/services/pageSrv.js       |  41 +++-
 eagle-server/src/main/webapp/app/package.json   |   2 +-
 8 files changed, 378 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/eagle/blob/ce53540f/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/queueCtrl.js
----------------------------------------------------------------------
diff --git 
a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/queueCtrl.js 
b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/queueCtrl.js
new file mode 100644
index 0000000..70988f4
--- /dev/null
+++ b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/ctrl/queueCtrl.js
@@ -0,0 +1,230 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+(function () {
+       /**
+        * `register` without params will load the module which using require
+        */
+       register(function (jpmApp) {
+               var QUEUE_ROOT = 'unassigned';
+
+               jpmApp.controller("queueCtrl", function ($q, $wrapState, 
$element, $scope, $timeout, PageConfig, Time, Entity, JPM) {
+                       var TEXT_MAX_CAPACITY = 'Max Capacity';
+                       var DISPLAY_MARK_NAME = ['Guaranteed Capacity', 
TEXT_MAX_CAPACITY];
+
+                       $scope.site = $wrapState.param.siteId;
+                       $scope.currentQueue = $wrapState.param.queue;
+                       $scope.selectedQueue = '';
+                       $scope.selectedSubQueue = '';
+                       $scope.trendLoading = true;
+
+                       PageConfig.title = "Queue";
+                       PageConfig.subTitle = $scope.currentQueue || "Overview";
+                       var navPath = PageConfig.navPath = [];
+
+                       $scope.chartOption = {
+                               tooltip: {
+                                       formatter: function (points) {
+                                               return points[0].name + "<br/>" 
+
+                                                       $.map(points, function 
(point) {
+                                                               return '<span 
style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:'
 + point.color + '"></span> ' +
+                                                                       
point.seriesName + ": " +
+                                                                       
Math.floor(point.value) + '%';
+                                                       
}).reverse().join("<br/>");
+                                       }
+                               },
+                               yAxis: [{
+                                       axisLabel: {formatter: function (value) 
{
+                                               return value + '%';
+                                       }}
+                               }]
+                       };
+
+                       // Load queue tree
+                       (function () {
+                               var startTime = new Time('startTime');
+                               var endTime = startTime.clone().add(1, 'h');
+                               JPM
+                                       .groups('RunningQueueService', { site: 
$scope.site, queue: $scope.currentQueue }, ['queue', 'parentQueue'], 'count', 
60, startTime, endTime)
+                                       ._promise
+                                       .then(function (list) {
+                                               $.each(list, function (i, 
entity) {
+                                                       var parent = 
entity.key[1];
+                                                       $scope.parentQueue = 
parent === QUEUE_ROOT ? null : parent;
+
+                                                       // Update navigation 
path
+                                                       navPath.push(
+                                                               {
+                                                                       title: 
$scope.parentQueue || 'queue list',
+                                                                       icon: 
'sitemap',
+                                                                       param: 
['siteId', 'startTime', 'endTime', $scope.parentQueue && 'queue=' + 
$scope.parentQueue],
+                                                                       path: 
"/jpm/queue"
+                                                               },
+                                                               {title: 
$scope.currentQueue}
+                                                       );
+
+                                                       return false;
+                                               });
+                                       });
+                       })();
+
+                       // Refresh Trend Chart
+                       $scope.refresh = function () {
+                               $scope.trendLoading = true;
+                               var startTime = new Time('startTime');
+                               var endTime = new Time('endTime');
+                               var intervalMin = Time.diffInterval(startTime, 
endTime) / 1000 / 60;
+                               var condition = {site: $scope.site};
+                               if ($scope.currentQueue) condition.parentQueue 
= $scope.currentQueue;
+
+                               var promiseList = [];
+                               // Load sub queue trend
+                               promiseList.push(JPM.aggMetricsToEntities(
+                                       JPM.groups('RunningQueueService', 
condition, ['queue', 'parentQueue'], 'max(absoluteUsedCapacity)', intervalMin, 
startTime, endTime)
+                               )._promise.then(function (list) {
+                                       $scope.subQueueList = [];
+
+                                       // Filter top queue
+                                       var queueTrendSeries = $.map(list, 
function (subList) {
+                                               var tags = subList[0].tags;
+                                               if (!$scope.currentQueue && 
tags.parentQueue !== QUEUE_ROOT) return;
+
+                                               var name = 
subList[0].tags.queue;
+                                               $scope.subQueueList.push(name);
+                                               return 
JPM.metricsToSeries(name, subList, {
+                                                       stack: "queue",
+                                                       areaStyle: {normal: {}}
+                                               });
+                                       });
+
+                                       $scope.selectedQueue = 
common.getValueByPath(queueTrendSeries, ['0', 'name']);
+                                       $scope.refreshQueueStatistic();
+
+                                       return queueTrendSeries;
+                               }));
+
+                               if ($scope.currentQueue) {
+                                       // Load current queue trend
+                                       
promiseList.push(JPM.aggMetricsToEntities(
+                                               
JPM.groups('RunningQueueService',
+                                                       { site: $scope.site, 
queue: $scope.currentQueue },
+                                                       ['queue'],
+                                                       
'max(absoluteUsedCapacity), max(memory), max(absoluteCapacity), 
max(absoluteMaxCapacity)',
+                                                       intervalMin, startTime, 
endTime)
+                                       )._promise.then(function (list) {
+                                               // Filter top queue
+                                               return $.map(list, function 
(valueSeries, seriesIndex) {
+                                                       var seriesName = 
valueSeries[0].tags.queue;
+                                                       var option = {};
+                                                       if (seriesIndex === 0) {
+                                                               
option.areaStyle = {normal: {}};
+                                                       } else if (seriesIndex 
=== 1) {
+                                                               return;
+                                                       } else {
+                                                               seriesName = 
DISPLAY_MARK_NAME[seriesIndex - 2];
+                                                               var 
markDisplayText = seriesName;
+
+                                                               if (seriesName 
=== TEXT_MAX_CAPACITY) {
+                                                                       var 
lastMemory = list[1][list[1].length - 1].value[0];
+                                                                       var 
lastCapacity = list[0][list[0].length - 1].value[0];
+                                                                       var 
lastMaxCapacity = list[seriesIndex][list[seriesIndex].length - 1].value[0];
+                                                                       var 
lastMaxMemory = lastMemory / lastCapacity * lastMaxCapacity;
+                                                                       
lastMaxMemory *= 1024 * 1024;
+
+                                                                       if 
(!isNaN(lastMaxMemory)) markDisplayText += '(Memory:' + 
common.number.abbr(lastMaxMemory, true, 0) + ')';
+                                                               }
+
+                                                               var pointValue 
= common.getValueByPath(valueSeries, [valueSeries.length - 1, 'value', 0], 0);
+                                                               option = {
+                                                                       
markPoint: {
+                                                                               
silent: true,
+                                                                               
label: {
+                                                                               
        normal: {
+                                                                               
                formatter: function () {
+                                                                               
                        return markDisplayText;
+                                                                               
                },
+                                                                               
                position: 'insideRight',
+                                                                               
                textStyle: {
+                                                                               
                        color: '#333',
+                                                                               
                        fontSize: 12,
+                                                                               
                }
+                                                                               
        }
+                                                                               
},
+                                                                               
data: [
+                                                                               
        {
+                                                                               
                name: '',
+                                                                               
                coord: [valueSeries.length - 1, pointValue],
+                                                                               
                symbolSize: 30,
+                                                                               
                itemStyle: {
+                                                                               
                        normal: {color: 'rgba(0,0,0,0)'}
+                                                                               
                }
+                                                                               
        }
+                                                                               
],
+                                                                       },
+                                                                       
lineStyle: {
+                                                                               
normal: { type: 'dotted' }
+                                                                       }
+                                                               };
+                                                       }
+
+                                                       return 
JPM.metricsToSeries(seriesName, valueSeries, option);
+                                               });
+                                       }));
+                               }
+
+                               $q.all(promiseList).then(function (seriesList) {
+
+                                       var subQueuesSeries = seriesList[0];
+                                       $scope.queueTrendSeries = 
subQueuesSeries;
+
+                                       if (seriesList[1]) {
+                                               var queueSeries = 
[seriesList[1][0]];
+                                               var capacitySeries = 
seriesList[1].slice(1);
+
+                                               if (!subQueuesSeries.length) {
+                                                       $scope.queueTrendSeries 
= queueSeries;
+                                               }
+                                               $scope.queueTrendSeries = 
$scope.queueTrendSeries.concat(capacitySeries);
+                                       }
+                                       $scope.trendLoading = false;
+                               });
+                       };
+
+                       // Refresh Queue static info
+                       $scope.refreshQueueStatistic = function () {
+                               var startTime = new Time('startTime');
+                               var endTime = new Time('endTime');
+                       };
+
+                       // Go to sub queue view
+                       $scope.switchToSubQueue = function () {
+                               $wrapState.go(".", {
+                                       queue: $scope.selectedSubQueue,
+                                       startTime: Time.format('startTime'),
+                                       endTime: Time.format('endTime'),
+                               });
+                       };
+
+                       Time.onReload(function () {
+                               $scope.refresh();
+                       }, $scope);
+                       $scope.refresh();
+
+               });
+       });
+})();

http://git-wip-us.apache.org/repos/asf/eagle/blob/ce53540f/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/index.js
----------------------------------------------------------------------
diff --git a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/index.js 
b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/index.js
index 7348853..234c539 100644
--- a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/index.js
+++ b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/index.js
@@ -55,18 +55,25 @@
                reloadOnSearch: false,
                templateUrl: "partials/job/compare.html",
                controller: "compareCtrl"
+
+       }).route("jpmQueue", {
+               url: "/jpm/queue?queue&startTime&endTime",
+               site: true,
+               templateUrl: "partials/queue/overview.html",
+               controller: "queueCtrl",
+               resolve: { time: true }
        });
 
        jpmApp.portal({name: "YARN Jobs", icon: "taxi", list: [
                {name: "Overview", path: "jpm/overview"},
                {name: "Job Statistics", path: "jpm/statistics"},
-               {name: "Job List", path: "jpm/list"}
+               {name: "Job List", path: "jpm/list"},
+               {name: "Queue", path: "jpm/queue"}
        ]}, true);
 
        jpmApp.service("JPM", function ($q, $http, Time, Site, Application) {
                var JPM = window._JPM = {};
 
-               // TODO: timestamp support
                JPM.QUERY_LIST = 
'${baseURL}/rest/entities?query=${query}[${condition}]{${fields}}&pageSize=${limit}&startTime=${startTime}&endTime=${endTime}';
                JPM.QUERY_GROUPS = 
'${baseURL}/rest/entities?query=${query}[${condition}]<${groups}>{${field}}${order}${top}&pageSize=${limit}&startTime=${startTime}&endTime=${endTime}';
                JPM.QUERY_GROUPS_INTERVAL = 
'${baseURL}/rest/entities?query=${query}[${condition}]<${groups}>{${field}}${order}${top}&pageSize=${limit}&startTime=${startTime}&endTime=${endTime}&intervalmin=${intervalMin}&timeSeries=true';
@@ -142,6 +149,7 @@
                };
 
                JPM.condition = function (condition) {
+                       if (typeof condition === 'string') return condition;
                        return $.map(condition, function (value, key) {
                                return "@" + key + '="' + value + '"';
                        }).join(" AND ");
@@ -189,7 +197,8 @@
                        _list._aggInfo = {
                                groups: groups,
                                startTime: Time(startTime).valueOf(),
-                               interval: intervalMin * 60 * 1000
+                               interval: intervalMin * 60 * 1000,
+                               order: fields[orderId]
                        };
                        _list._promise.then(function () {
                                if(top) _list.reverse();
@@ -310,7 +319,7 @@
                        _list._aggInfo = {
                                groups: groups,
                                startTime: Time(startTime).valueOf(),
-                               interval: intervalMin * 60 * 1000
+                               interval: intervalMin * 60 * 1000,
                        };
                        _list._promise.then(function () {
                                _list.reverse();
@@ -331,19 +340,23 @@
                                                tags[group] = obj.key[j];
                                        });
 
-                                       var _subList = $.map(obj.value[0], 
function (value, index) {
-                                               return {
-                                                       timestamp: _startTime + 
index * _interval,
-                                                       value: [value],
-                                                       tags: tags
-                                               };
-                                       });
+                                       $.each(obj.value, function (j, values) {
+                                               if (list._aggInfo.order && j 
=== list.length - 1) return;
 
-                                       if(flatten) {
-                                               _list.push.apply(_list, 
_subList);
-                                       } else {
-                                               _list.push(_subList);
-                                       }
+                                               var _subList = $.map(values, 
function (value, index) {
+                                                       return {
+                                                               timestamp: 
_startTime + index * _interval,
+                                                               value: [value],
+                                                               tags: tags
+                                                       };
+                                               });
+
+                                               if(flatten) {
+                                                       _list.push.apply(_list, 
_subList);
+                                               } else {
+                                                       _list.push(_subList);
+                                               }
+                                       });
                                });
                                _list.done = true;
                                return _list;
@@ -484,4 +497,5 @@
        jpmApp.require("ctrl/detailCtrl.js");
        jpmApp.require("ctrl/jobTaskCtrl.js");
        jpmApp.require("ctrl/compareCtrl.js");
+       jpmApp.require("ctrl/queueCtrl.js");
 })();

http://git-wip-us.apache.org/repos/asf/eagle/blob/ce53540f/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html
----------------------------------------------------------------------
diff --git 
a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html
 
b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html
new file mode 100644
index 0000000..732fbb2
--- /dev/null
+++ 
b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/partials/queue/overview.html
@@ -0,0 +1,57 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<div class="box box-primary">
+       <div class="box-header with-border">
+               <h3 class="box-title">
+                       Queue Capacity Trend
+               </h3>
+               <div class="box-tools" ng-show="subQueueList.length">
+                       <select class="form-control input-sm" 
ng-model="selectedSubQueue" ng-change="switchToSubQueue()">
+                               <option value="">[View Sub Queue]</option>
+                               <option ng-repeat="queue in subQueueList track 
by $index" value="{{queue}}">{{queue}}</option>
+                       </select>
+               </div>
+       </div>
+       <div class="box-body">
+               <div class="jpm-chart">
+                       <div chart class="jpm-chart-container" 
series="queueTrendSeries" option="chartOption"></div>
+                       <h1 class="jpm-chart-tip" ng-if="queueTrendSeries && 
queueTrendSeries.length === 0">No Data</h1>
+               </div>
+       </div>
+
+       <div ng-if="trendLoading" class="overlay">
+               <i class="fa fa-refresh fa-spin"></i>
+       </div>
+</div>
+
+<!-- div class="nav-tabs-custom">
+       <ul class="nav nav-tabs">
+               <li class="active"><a data-toggle="tab" 
href="#queueUser">User</a></li>
+               <li><a data-toggle="tab" href="#queueJob">Job</a></li>
+
+               <li class="pull-right">
+                       <select class="form-control" ng-model="selectedQueue" 
ng-change="refreshQueueStatistic()">
+                               <option ng-repeat="queue in subQueueList track 
by $index" value="{{queue}}">{{queue}}</option>
+                       </select>
+               </li>
+       </ul>
+       <div class="tab-content">
+               <div class="tab-pane active"></div>
+       </div>
+</div -->
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/eagle/blob/ce53540f/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/style/index.css
----------------------------------------------------------------------
diff --git 
a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/style/index.css 
b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/style/index.css
index fbe238f..f63d67c 100644
--- a/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/style/index.css
+++ b/eagle-jpm/eagle-jpm-web/src/main/webapp/app/apps/jpm/style/index.css
@@ -39,6 +39,14 @@
        height: 350px;
 }
 
+.jpm-chart .jpm-chart-tip {
+       position: absolute;
+       top: 50%;
+       margin: -20px 0 0 0;
+       width: 100%;
+       text-align: center;
+}
+
 .with-border .jpm-chart {
        padding-bottom: 15px;
        margin-bottom: 15px;

http://git-wip-us.apache.org/repos/asf/eagle/blob/ce53540f/eagle-server/src/main/webapp/app/dev/index.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/index.html 
b/eagle-server/src/main/webapp/app/dev/index.html
index 74d5c57..26b12ee 100644
--- a/eagle-server/src/main/webapp/app/dev/index.html
+++ b/eagle-server/src/main/webapp/app/dev/index.html
@@ -162,13 +162,13 @@
 
 
                                        <ol class="breadcrumb">
-                                               <li ng-repeat="navPath in 
PageConfig.navPath">
+                                               <li ng-repeat="navPath in 
PageConfig.getNavPath() track by $index">
                                                        <span 
ng-if="!navPath.path">
-                                                               <span class="fa 
fa-home" ng-if="$first"></span>
+                                                               <span class="fa 
fa-{{navPath.icon || 'home'}}" ng-if="$first"></span>
                                                                {{navPath.title 
|| navPath.path}}
                                                        </span>
                                                        <a ng-if="navPath.path" 
ng-href="#{{navPath.path}}">
-                                                               <span class="fa 
fa-home" ng-if="$first"></span>
+                                                               <span class="fa 
fa-{{navPath.icon || 'home'}}" ng-if="$first"></span>
                                                                {{navPath.title 
|| navPath.path}}
                                                        </a>
                                                </li>

http://git-wip-us.apache.org/repos/asf/eagle/blob/ce53540f/eagle-server/src/main/webapp/app/dev/public/css/main.css
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/css/main.css 
b/eagle-server/src/main/webapp/app/dev/public/css/main.css
index 895d514..8583513 100644
--- a/eagle-server/src/main/webapp/app/dev/public/css/main.css
+++ b/eagle-server/src/main/webapp/app/dev/public/css/main.css
@@ -277,6 +277,15 @@ ul.stepGuide li > .title {
        overflow-x: auto;
 }
 
+.box-header > .box-tools {
+       white-space: nowrap;
+}
+
+.box-header > .box-tools > .form-control {
+       display: inline-block;
+       width: initial;
+}
+
 /* ========================================================================
  * =                                 Tab                                  =
  * ======================================================================== */

http://git-wip-us.apache.org/repos/asf/eagle/blob/ce53540f/eagle-server/src/main/webapp/app/dev/public/js/services/pageSrv.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/services/pageSrv.js 
b/eagle-server/src/main/webapp/app/dev/public/js/services/pageSrv.js
index 2c61087..f4ea2f4 100644
--- a/eagle-server/src/main/webapp/app/dev/public/js/services/pageSrv.js
+++ b/eagle-server/src/main/webapp/app/dev/public/js/services/pageSrv.js
@@ -24,7 +24,7 @@
        // ============================================================
        // =                           Page                           =
        // ============================================================
-       serviceModule.service('PageConfig', function() {
+       serviceModule.service('PageConfig', function($wrapState) {
                function PageConfig() {
                }
 
@@ -35,6 +35,45 @@
                        PageConfig.hideTitle = false;
                };
 
+               var cachedNavPath = [];
+               var cachedGenNavPath = [];
+               PageConfig.getNavPath = function () {
+                       if (cachedNavPath !== PageConfig.navPath || 
cachedGenNavPath.length !== cachedNavPath.length) {
+                               cachedNavPath = PageConfig.navPath;
+                               cachedGenNavPath = $.map(cachedNavPath, 
function (navPath) {
+                                       var pathEntity = $.extend({}, navPath);
+
+                                       if (!pathEntity.path || 
!pathEntity.param) return pathEntity;
+
+                                       // Parse param as `key=value` format
+                                       var params = {};
+                                       $.each(pathEntity.param, function (i, 
param) {
+                                               if (!param) return;
+
+                                               var match = 
param.match(/^([^=]+)(=(.*))?$/);
+                                               var key = match[1];
+                                               var value = match[3];
+                                               params[key] = value !== 
undefined ? value : $wrapState.param[key];
+                                       });
+
+                                       // Generate path with param
+                                       var path = "/" + 
pathEntity.path.replace(/^[\\\/]/, "");
+                                       if (params.siteId) {
+                                               pathEntity.path = "/site/" + 
$wrapState.param.siteId + path;
+                                               delete params.siteId;
+                                       } else {
+                                               pathEntity.path = path;
+                                       }
+                                       pathEntity.path += '?' + $.map(params, 
function (value, key) {
+                                               return key + '=' + value;
+                                       }).join('&');
+
+                                       return pathEntity;
+                               });
+                       }
+                       return cachedGenNavPath;
+               };
+
                return PageConfig;
        });
 

http://git-wip-us.apache.org/repos/asf/eagle/blob/ce53540f/eagle-server/src/main/webapp/app/package.json
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/package.json 
b/eagle-server/src/main/webapp/app/package.json
index 4ee3eda..2c5d272 100644
--- a/eagle-server/src/main/webapp/app/package.json
+++ b/eagle-server/src/main/webapp/app/package.json
@@ -23,7 +23,7 @@
     "angular-ui-router": "0.3.1",
     "bootstrap": "3.3.6",
     "d3": "3.5.16",
-    "echarts": "^3.3.2",
+    "echarts": "^3.4.0",
     "font-awesome": "4.7.0",
     "jquery": "2.2.4",
     "jquery-slimscroll": "1.3.6",

Reply via email to