fix #1892: added instruction text to operate network graph (2) minor tweaks of context menu
Project: http://git-wip-us.apache.org/repos/asf/incubator-gearpump/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-gearpump/commit/3bf290e4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-gearpump/tree/3bf290e4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-gearpump/diff/3bf290e4 Branch: refs/heads/master Commit: 3bf290e4f3cd117923381d88d134f44835a1f504 Parents: 9feb159 Author: Qian Xu <[email protected]> Authored: Sun Feb 14 16:29:06 2016 +0800 Committer: Qian Xu <[email protected]> Committed: Mon Feb 15 10:23:10 2016 +0800 ---------------------------------------------------------------------- services/dashboard/index.html | 4 +- services/dashboard/views/apps/apps.js | 4 +- .../dashboard/views/apps/compose/compose.js | 6 +- .../dashboard/views/apps/streamingapp/dag.html | 8 ++- .../dashboard/views/apps/streamingapp/dag.js | 48 +++++++++++--- .../views/apps/streamingapp/popups/dag_edit.js | 2 +- .../streamingapp/popups/processor_menu.html | 15 ----- .../views/apps/streamingapp/vis/network.js | 69 +++++++++++--------- .../views/widgets/metrics_period_switcher.html | 3 - .../views/widgets/metrics_period_switcher.js | 32 --------- .../dashboard/views/widgets/radio_group.html | 12 ---- services/dashboard/views/widgets/radio_group.js | 29 -------- .../widgets/metrics_period_switcher.html | 3 + .../widgets/metrics_period_switcher.js | 32 +++++++++ services/dashboard/widgets/radio_group.html | 12 ++++ services/dashboard/widgets/radio_group.js | 29 ++++++++ 16 files changed, 164 insertions(+), 144 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/index.html ---------------------------------------------------------------------- diff --git a/services/dashboard/index.html b/services/dashboard/index.html index 47007cc..a3bbaa9 100644 --- a/services/dashboard/index.html +++ b/services/dashboard/index.html @@ -77,8 +77,8 @@ <script src="services/restapi.js"></script> <script src="services/health_check_service.js"></script> <script src="services/login_check.js"></script> -<script src="views/widgets/radio_group.js"></script> -<script src="views/widgets/metrics_period_switcher.js"></script> +<script src="widgets/radio_group.js"></script> +<script src="widgets/metrics_period_switcher.js"></script> <script src="views/landing/breadcrumbs.js"></script> <script src="views/landing/header.js"></script> <script src="views/cluster/master/master.js"></script> http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/apps/apps.js ---------------------------------------------------------------------- diff --git a/services/dashboard/views/apps/apps.js b/services/dashboard/views/apps/apps.js index 4a4f7d6..669d018 100644 --- a/services/dashboard/views/apps/apps.js +++ b/services/dashboard/views/apps/apps.js @@ -45,10 +45,10 @@ angular.module('dashboard') }; $scope.composeMenuOptions = [{ - text: '<i class="glyphicon glyphicon-none"></i> <b>Submit Gearpump Application</b>', + text: '<i class="glyphicon glyphicon-none"></i> <b>Submit Gearpump Application...</b>', click: $scope.openSubmitGearAppDialog }, { - text: '<i class="glyphicon glyphicon-none"></i> Submit Storm Application', + text: '<i class="glyphicon glyphicon-none"></i> Submit Storm Application...', click: $scope.openSubmitStormAppDialog }, { text: '<i class="glyphicon glyphicon-pencil"></i> Compose DAG', http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/apps/compose/compose.js ---------------------------------------------------------------------- diff --git a/services/dashboard/views/apps/compose/compose.js b/services/dashboard/views/apps/compose/compose.js index d1ff1c6..33e9263 100644 --- a/services/dashboard/views/apps/compose/compose.js +++ b/services/dashboard/views/apps/compose/compose.js @@ -79,7 +79,7 @@ angular.module('dashboard') options: $vis.newOptions(/*height=*/'400px'), data: $vis.newData(), events: { - doubleClick: function(data) { + onDoubleClick: function(data) { if (data.nodes.length === 1) { var processor = $scope.visGraph.data.nodes.get(data.nodes[0]); $scope.chooseProcessor(processor); @@ -90,7 +90,7 @@ angular.module('dashboard') $scope.chooseProcessor(); } }, - oncontext: function(data) { + onContext: function(data) { if (data.hasOwnProperty('node')) { $scope.selectItemModify = function() { $scope.chooseProcessor($scope.visGraph.data.nodes.get(data.node)); @@ -111,7 +111,7 @@ angular.module('dashboard') var elem = document.getElementById('contextmenu'); $contextmenu.popup(elem, data.pointer.DOM); }, - ondeletepressed: function(selection) { + onDeletePressed: function(selection) { if (selection.nodes.length === 1) { deleteProcessor(selection.nodes[0]); } else if (selection.edges.length === 1) { http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/apps/streamingapp/dag.html ---------------------------------------------------------------------- diff --git a/services/dashboard/views/apps/streamingapp/dag.html b/services/dashboard/views/apps/streamingapp/dag.html index 5b2928d..93655cb 100644 --- a/services/dashboard/views/apps/streamingapp/dag.html +++ b/services/dashboard/views/apps/streamingapp/dag.html @@ -1,10 +1,12 @@ <div class="col-md-8"> <div class="panel panel-sm panel-default"> - <div class="panel-heading">DAG</div> + <div class="panel-heading">DAG + <remark class="pull-right" type="info" + tooltip="<b>Right click (or long press on touch device)</b> on a processor will show all available operations. <b>Double click</b> a processor will show its details.">Instructions</remark> + </div> <div class="panel-body"> <div class="cm-container" id="dag-node-menu" - bs-dropdown html="true" - template-url="views/apps/streamingapp/popups/processor_menu.html"></div> + bs-dropdown="processorActionMenu" html="true"></div> <vis-network data="visGraph.data" options="visGraph.options" http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/apps/streamingapp/dag.js ---------------------------------------------------------------------- diff --git a/services/dashboard/views/apps/streamingapp/dag.js b/services/dashboard/views/apps/streamingapp/dag.js index 0c3f11e..310f555 100644 --- a/services/dashboard/views/apps/streamingapp/dag.js +++ b/services/dashboard/views/apps/streamingapp/dag.js @@ -21,7 +21,17 @@ angular.module('dashboard') function($scope, $state, $modal, $contextmenu, $vis) { 'use strict'; - // todo: while metrics is not available, keep loading, otherwise the bandwidth is not calculable. + $scope.activeProcessorId = -1; + $scope.processorActionMenu = [{ + text: '<i class="glyphicon glyphicon-stats"></i> <b>View Details</b>', + click: 'view()' + }, { + text: '<i class="glyphicon glyphicon-none"></i> Change Parallelism...', + click: 'modify({parallelism:true})' + }, { + text: '<i class="glyphicon glyphicon-none"></i> Change More...', + click: 'modify()' + }]; var editorDialog = $modal({ templateUrl: "views/apps/streamingapp/popups/dag_edit.html", @@ -31,6 +41,11 @@ angular.module('dashboard') controller: 'StreamingAppDagEditCtrl' }); + $scope.view = function() { + var options = {processorId: $scope.activeProcessorId}; + $state.go('streamingapp.processor', options); + }; + $scope.modify = function(options) { $scope.modifyOptions = options; editorDialog.$promise.then(editorDialog.show); @@ -40,27 +55,40 @@ angular.module('dashboard') options: $vis.newHierarchicalLayoutOptions({depth: $scope.dag.hierarchyDepth()}), data: $vis.newData(), events: { - doubleClick: function(data) { + onDoubleClick: function(data) { if (data.nodes.length === 1) { var processorId = Number(data.nodes[0]); $state.go('streamingapp.processor', {processorId: processorId}); } }, - oncontext: function(data) { + onContext: function(data) { if (data.hasOwnProperty('node')) { - var processorId = Number(data.node); - $scope.activeProcessor = $scope.dag.getProcessor(processorId); - showProcessorOperationsContextMenu(processorId, data.pointer.DOM); + $scope.activeProcessorId = Number(data.node); + $scope.$apply(); + showProcessorOperationsContextMenu(data.pointer.DOM); + } + }, + onSelectNode: function(data) { + if (data.nodes.length === 1) { + $scope.activeProcessorId = Number(data.nodes[0]); + $scope.$apply(); } + }, + onDeselectNode: function() { + $scope.activeProcessorId = -1; + $scope.$apply(); + }, + onHoverNode: function() { + $('html,body').css('cursor', 'pointer'); + }, + onBlurNode: function() { + $('html,body').css('cursor', 'default'); } } }; - function showProcessorOperationsContextMenu(processorId, position) { + function showProcessorOperationsContextMenu(position) { var elem = document.getElementById('dag-node-menu'); - $scope.view = function() { - $state.go('streamingapp.processor', {processorId: processorId}); - }; $contextmenu.popup(elem, position); } http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/apps/streamingapp/popups/dag_edit.js ---------------------------------------------------------------------- diff --git a/services/dashboard/views/apps/streamingapp/popups/dag_edit.js b/services/dashboard/views/apps/streamingapp/popups/dag_edit.js index 5ffd376..58daeb5 100644 --- a/services/dashboard/views/apps/streamingapp/popups/dag_edit.js +++ b/services/dashboard/views/apps/streamingapp/popups/dag_edit.js @@ -11,7 +11,7 @@ angular.module('dashboard') var options = $scope.modifyOptions || {}; $scope.changeParallelismOnly = options.parallelism; - var processor = $scope.activeProcessor; + var processor = $scope.dag.getProcessor($scope.activeProcessorId); $scope.processorId = processor.id; $scope.taskClass = processor.taskClass; $scope.description = processor.description; http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/apps/streamingapp/popups/processor_menu.html ---------------------------------------------------------------------- diff --git a/services/dashboard/views/apps/streamingapp/popups/processor_menu.html b/services/dashboard/views/apps/streamingapp/popups/processor_menu.html deleted file mode 100644 index bef7aaf..0000000 --- a/services/dashboard/views/apps/streamingapp/popups/processor_menu.html +++ /dev/null @@ -1,15 +0,0 @@ -<ul class="dropdown-menu dropdown-menu-sm"> - <li><a href="" ng-click="modify({parallelism:true})"> - <span class="glyphicon glyphicon-none"></span> - Change Parallelism</a> - </li> - <li><a href="" ng-click="modify()"> - <span class="glyphicon glyphicon-none"></span> - Modify</a> - </li> - <li role="separator" class="divider"></li> - <li><a href="" ng-click="view()"> - <span class="glyphicon glyphicon-stats"></span> - <b>View Details</b></a> - </li> -</ul> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/apps/streamingapp/vis/network.js ---------------------------------------------------------------------- diff --git a/services/dashboard/views/apps/streamingapp/vis/network.js b/services/dashboard/views/apps/streamingapp/vis/network.js index 184c7e7..f5c9f80 100644 --- a/services/dashboard/views/apps/streamingapp/vis/network.js +++ b/services/dashboard/views/apps/streamingapp/vis/network.js @@ -8,25 +8,22 @@ angular.module('dashboard') .directive('visNetwork', [function() { 'use strict'; - function overrideOnContextEvent(network, callback) { + function handleOnContextEvent(network, callback) { var rightClickHandler = function(args) { - function handleOnContext(data) { - + function handleCallback(data) { // always disable the default context menu "Save image as, Copy Image..." vis.util.preventDefault(args.event); - if (callback) { - callback(angular.merge(data, {pointer: args.pointer})); - } + callback(angular.merge(data, {pointer: args.pointer})); } var selection = network.getNodeAt(args.pointer.DOM); if (angular.isDefined(selection)) { - handleOnContext({node: selection}); + handleCallback({node: selection}); } else { selection = network.getEdgeAt(args.pointer.DOM); if (angular.isDefined(selection)) { - handleOnContext({edge: selection}); + handleCallback({edge: selection}); } } }; @@ -37,22 +34,19 @@ angular.module('dashboard') network.on('hold', rightClickHandler); } - function overrideHoverNodeEvent(network, callback) { - network.on('hoverNode', function(args) { - if (callback) { - var nodeId = parseInt(args.node); - var radius = network.findNode(nodeId)[0].options.size; - var position = network.getPositions([nodeId])[nodeId]; - position = network.canvasToDOM(position); - callback({ - node: nodeId, - radius: Math.ceil(radius), - position: position - }); - } - vis.util.preventDefault(args.event); - } - ); + function overrideHoverNodeCallback(network, callback) { + return function(args) { + var nodeId = parseInt(args.node); + var radius = network.findNode(nodeId)[0].options.size; + var position = network.getPositions([nodeId])[nodeId]; + position = network.canvasToDOM(position); + callback({ + node: nodeId, + radius: Math.ceil(radius), + position: position + }); + vis.util.preventDefault(args.event); + }; } function handleDeleteKeyPressed(network, callback) { @@ -80,17 +74,28 @@ angular.module('dashboard') angular.forEach(scope.events, function(callback, name) { switch (name) { - case 'click': - case 'doubleClick': - network.on(name, callback); + case 'onClick': + network.on('click', callback); + break; + case 'onDoubleClick': + network.on('doubleClick', callback); + break; + case 'onSelectNode': + network.on('selectNode', callback); + break; + case 'onDeselectNode': + network.on('deselectNode', callback); + break; + case 'onHoverNode': + network.on('hoverNode', overrideHoverNodeCallback(network, callback)); break; - case 'oncontext': - overrideOnContextEvent(network, callback); + case 'onBlurNode': + network.on('blurNode', overrideHoverNodeCallback(network, callback)); break; - case 'hoverNode': - overrideHoverNodeEvent(network, callback); + case 'onContext': + handleOnContextEvent(network, callback); break; - case 'ondeletepressed': + case 'onDeletePressed': handleDeleteKeyPressed(network, callback); break; } http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/widgets/metrics_period_switcher.html ---------------------------------------------------------------------- diff --git a/services/dashboard/views/widgets/metrics_period_switcher.html b/services/dashboard/views/widgets/metrics_period_switcher.html deleted file mode 100644 index 92312a0..0000000 --- a/services/dashboard/views/widgets/metrics_period_switcher.html +++ /dev/null @@ -1,3 +0,0 @@ -<radio-group - options="options" button-width="110px" - ng-model="value"></radio-group> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/widgets/metrics_period_switcher.js ---------------------------------------------------------------------- diff --git a/services/dashboard/views/widgets/metrics_period_switcher.js b/services/dashboard/views/widgets/metrics_period_switcher.js deleted file mode 100644 index 263ad7e..0000000 --- a/services/dashboard/views/widgets/metrics_period_switcher.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 - * See accompanying LICENSE file. - */ - -angular.module('dashboard') - - .directive('metricsPeriodSwitcher', function() { - 'use strict'; - - return { - restrict: 'E', - templateUrl: 'views/widgets/metrics_period_switcher.html', - scope: { - pastHours: '=', - viewCurrent: '=' - }, - link: function(scope) { - 'use strict'; - - scope.options = { - current: 'Current', - hist: 'Past %d Hours'.replace('%d', scope.pastHours) - }; - scope.value = scope.viewCurrent ? 'current' : 'hist'; - scope.$watch('value', function(value) { - scope.viewCurrent = String(value) === 'current'; - }); - } - } - }) -; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/widgets/radio_group.html ---------------------------------------------------------------------- diff --git a/services/dashboard/views/widgets/radio_group.html b/services/dashboard/views/widgets/radio_group.html deleted file mode 100644 index 0c68574..0000000 --- a/services/dashboard/views/widgets/radio_group.html +++ /dev/null @@ -1,12 +0,0 @@ -<div class="row"> - <div class="col-md-12 text-center"> - <div class="btn-group btn-group-xs"> - <button ng-repeat="(value, text) in options track by $index" - type="button" class="btn btn-default btn-default-outline" - ng-style="{width: buttonWidth}" - ng-class="{'btn-primary btn-primary-outline': value == ngModel}" - ng-bind="text" - ng-click="toggle(value)"></button> - </div> - </div> -</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/views/widgets/radio_group.js ---------------------------------------------------------------------- diff --git a/services/dashboard/views/widgets/radio_group.js b/services/dashboard/views/widgets/radio_group.js deleted file mode 100644 index 80aea1b..0000000 --- a/services/dashboard/views/widgets/radio_group.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 - * See accompanying LICENSE file. - */ - -angular.module('dashboard') - - .directive('radioGroup', function() { - 'use strict'; - - return { - restrict: 'E', - templateUrl: 'views/widgets/radio_group.html', - replace: true, - scope: { - ngModel: '=', - options: '=' - }, - link: function(scope, elem, attrs) { - 'use strict'; - - scope.buttonWidth = attrs.buttonWidth || '96px'; - scope.toggle = function(value) { - scope.ngModel = value; - }; - } - } - }) -; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/widgets/metrics_period_switcher.html ---------------------------------------------------------------------- diff --git a/services/dashboard/widgets/metrics_period_switcher.html b/services/dashboard/widgets/metrics_period_switcher.html new file mode 100644 index 0000000..92312a0 --- /dev/null +++ b/services/dashboard/widgets/metrics_period_switcher.html @@ -0,0 +1,3 @@ +<radio-group + options="options" button-width="110px" + ng-model="value"></radio-group> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/widgets/metrics_period_switcher.js ---------------------------------------------------------------------- diff --git a/services/dashboard/widgets/metrics_period_switcher.js b/services/dashboard/widgets/metrics_period_switcher.js new file mode 100644 index 0000000..b40aa23 --- /dev/null +++ b/services/dashboard/widgets/metrics_period_switcher.js @@ -0,0 +1,32 @@ +/* + * Licensed under the Apache License, Version 2.0 + * See accompanying LICENSE file. + */ + +angular.module('dashboard') + + .directive('metricsPeriodSwitcher', function() { + 'use strict'; + + return { + restrict: 'E', + templateUrl: 'widgets/metrics_period_switcher.html', + scope: { + pastHours: '=', + viewCurrent: '=' + }, + link: function(scope) { + 'use strict'; + + scope.options = { + current: 'Current', + hist: 'Past %d Hours'.replace('%d', scope.pastHours) + }; + scope.value = scope.viewCurrent ? 'current' : 'hist'; + scope.$watch('value', function(value) { + scope.viewCurrent = String(value) === 'current'; + }); + } + } + }) +; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/widgets/radio_group.html ---------------------------------------------------------------------- diff --git a/services/dashboard/widgets/radio_group.html b/services/dashboard/widgets/radio_group.html new file mode 100644 index 0000000..0c68574 --- /dev/null +++ b/services/dashboard/widgets/radio_group.html @@ -0,0 +1,12 @@ +<div class="row"> + <div class="col-md-12 text-center"> + <div class="btn-group btn-group-xs"> + <button ng-repeat="(value, text) in options track by $index" + type="button" class="btn btn-default btn-default-outline" + ng-style="{width: buttonWidth}" + ng-class="{'btn-primary btn-primary-outline': value == ngModel}" + ng-bind="text" + ng-click="toggle(value)"></button> + </div> + </div> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-gearpump/blob/3bf290e4/services/dashboard/widgets/radio_group.js ---------------------------------------------------------------------- diff --git a/services/dashboard/widgets/radio_group.js b/services/dashboard/widgets/radio_group.js new file mode 100644 index 0000000..aa5427d --- /dev/null +++ b/services/dashboard/widgets/radio_group.js @@ -0,0 +1,29 @@ +/* + * Licensed under the Apache License, Version 2.0 + * See accompanying LICENSE file. + */ + +angular.module('dashboard') + + .directive('radioGroup', function() { + 'use strict'; + + return { + restrict: 'E', + templateUrl: 'widgets/radio_group.html', + replace: true, + scope: { + ngModel: '=', + options: '=' + }, + link: function(scope, elem, attrs) { + 'use strict'; + + scope.buttonWidth = attrs.buttonWidth || '96px'; + scope.toggle = function(value) { + scope.ngModel = value; + }; + } + } + }) +; \ No newline at end of file
