1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-23 07:19:41 +02:00

Add actions to show upstream and downstream dependencies of a container for easy visualization.

Additionally updated angular-vis to use version 0.0.4 which already includes the changes of https://github.com/visjs/angular-visjs/pull/22.
This commit is contained in:
Roger Abelenda 2015-05-02 12:04:31 -03:00
parent 9e713b7b81
commit edd6a41d6e
4 changed files with 102 additions and 30 deletions

View file

@ -41,7 +41,7 @@ DockerUI listens on port 9000 by default. If you run DockerUI inside a container
* [Gritter](https://github.com/jboesch/Gritter) * [Gritter](https://github.com/jboesch/Gritter)
* [Spin.js](https://github.com/fgnass/spin.js/) * [Spin.js](https://github.com/fgnass/spin.js/)
* [Golang](https://golang.org/) * [Golang](https://golang.org/)
* [Vis.js](http://visjs.org/) - We are using a [patched version](https://github.com/visjs/angular-visjs/pull/22) * [Vis.js](http://visjs.org/)
### Todo: ### Todo:

View file

@ -11,6 +11,8 @@
<div class="row"> <div class="row">
<div class="btn-group"> <div class="btn-group">
<button class="btn btn-warning" ng-click="network.hideSelected()">Hide Selected</button> <button class="btn btn-warning" ng-click="network.hideSelected()">Hide Selected</button>
<button class="btn btn-info" ng-click="network.showSelectedDownstream()">Show Selected Downstream</button>
<button class="btn btn-info" ng-click="network.showSelectedUpstream()">Show Selected Upstream</button>
<button class="btn btn-success" ng-click="network.showAll()">Show All</button> <button class="btn btn-success" ng-click="network.showAll()">Show All</button>
</div> </div>
</div> </div>

View file

@ -8,7 +8,7 @@ angular.module('containersNetwork', ['ngVis'])
this.Image = data.Config.Image; this.Image = data.Config.Image;
var dataLinks = data.HostConfig.Links; var dataLinks = data.HostConfig.Links;
if (dataLinks != null) { if (dataLinks != null) {
this.Links = []; this.Links = {};
for (var i = 0; i < dataLinks.length; i++) { for (var i = 0; i < dataLinks.length; i++) {
// links have the following format: /TargetContainerName:/SourceContainerName/LinkAlias // links have the following format: /TargetContainerName:/SourceContainerName/LinkAlias
var link = dataLinks[i].split(":"); var link = dataLinks[i].split(":");
@ -23,7 +23,7 @@ angular.module('containersNetwork', ['ngVis'])
var dataVolumes = data.HostConfig.VolumesFrom; var dataVolumes = data.HostConfig.VolumesFrom;
//converting array into properties for simpler and faster access //converting array into properties for simpler and faster access
if (dataVolumes != null) { if (dataVolumes != null) {
this.VolumesFrom = []; this.VolumesFrom = {};
for (var j = 0; j < dataVolumes.length; j++) { for (var j = 0; j < dataVolumes.length; j++) {
this.VolumesFrom[dataVolumes[j]] = true; this.VolumesFrom[dataVolumes[j]] = true;
} }
@ -69,12 +69,12 @@ angular.module('containersNetwork', ['ngVis'])
function ContainersNetwork() { function ContainersNetwork() {
this.data = new ContainersNetworkData(); this.data = new ContainersNetworkData();
this.containers = []; this.containers = {};
this.selectedContainers = []; this.selectedContainersIds = [];
this.shownContainers = []; this.shownContainersIds = [];
this.events = { this.events = {
select : function(event) { select : function(event) {
$scope.network.selectedContainers = event.nodes; $scope.network.selectedContainersIds = event.nodes;
$scope.$apply( function() { $scope.$apply( function() {
$scope.query = ''; $scope.query = '';
}); });
@ -104,11 +104,11 @@ angular.module('containersNetwork', ['ngVis'])
this.addContainer = function(data) { this.addContainer = function(data) {
var container = new ContainerNode(data); var container = new ContainerNode(data);
this.containers.push(container); this.containers[container.Id] = container;
this.shownContainers.push(container); this.shownContainersIds.push(container.Id);
this.data.addContainerNode(container); this.data.addContainerNode(container);
for (var i = 0; i < this.containers.length; i++) { for (var otherContainerId in this.containers) {
var otherContainer = this.containers[i]; var otherContainer = this.containers[otherContainerId];
this.data.addLinkEdgeIfExists(container, otherContainer); this.data.addLinkEdgeIfExists(container, otherContainer);
this.data.addLinkEdgeIfExists(otherContainer, container); this.data.addLinkEdgeIfExists(otherContainer, container);
this.data.addVolumeEdgeIfExists(container, otherContainer); this.data.addVolumeEdgeIfExists(container, otherContainer);
@ -118,8 +118,8 @@ angular.module('containersNetwork', ['ngVis'])
this.selectContainers = function(query) { this.selectContainers = function(query) {
if (this.component != null) { if (this.component != null) {
this.selectedContainers = this.searchContainers(query); this.selectedContainersIds = this.searchContainers(query);
this.component.selectNodes(this.selectedContainers); this.component.selectNodes(this.selectedContainersIds);
} }
}; };
@ -127,38 +127,103 @@ angular.module('containersNetwork', ['ngVis'])
if (query.trim() === "") { if (query.trim() === "") {
return []; return [];
} }
var selectedContainers = []; var selectedContainersIds = [];
for (var i=0; i < this.shownContainers.length; i++) { for (var i=0; i < this.shownContainersIds.length; i++) {
var container = this.shownContainers[i]; var container = this.containers[this.shownContainersIds[i]];
if (container.Name.indexOf(query) > -1 || if (container.Name.indexOf(query) > -1 ||
container.Image.indexOf(query) > -1 || container.Image.indexOf(query) > -1 ||
container.Id.indexOf(query) > -1) { container.Id.indexOf(query) > -1) {
selectedContainers.push(container.Id); selectedContainersIds.push(container.Id);
} }
} }
return selectedContainers; return selectedContainersIds;
}; };
this.hideSelected = function() { this.hideSelected = function() {
var i=0; var i=0;
while ( i < this.shownContainers.length ) { while ( i < this.shownContainersIds.length ) {
if (this.selectedContainers.indexOf(this.shownContainers[i].Id) > -1) { if (this.selectedContainersIds.indexOf(this.shownContainersIds[i]) > -1) {
this.shownContainers.splice(i, 1); this.shownContainersIds.splice(i, 1);
} else { } else {
i++; i++;
} }
} }
this.data.removeContainersNodes(this.selectedContainers); this.data.removeContainersNodes(this.selectedContainersIds);
$scope.query = ''; $scope.query = '';
this.selectedContainers = []; this.selectedContainersIds = [];
};
this.searchDownstream = function(containerId, downstreamContainersIds) {
if (downstreamContainersIds.indexOf(containerId) > -1) {
return;
}
downstreamContainersIds.push(containerId);
var container = this.containers[containerId];
if (container.Links == null && container.VolumesFrom == null) {
return;
}
for (var otherContainerId in this.containers) {
var otherContainer = this.containers[otherContainerId];
if (container.Links != null && container.Links[otherContainer.Name] != null) {
this.searchDownstream(otherContainer.Id, downstreamContainersIds);
} else if (container.VolumesFrom != null &&
container.VolumesFrom[otherContainer.Id] != null) {
this.searchDownstream(otherContainer.Id, downstreamContainersIds);
}
}
};
this.updateShownContainers = function(newShownContainersIds) {
for (var containerId in this.containers) {
if (newShownContainersIds.indexOf(containerId) > -1 &&
this.shownContainersIds.indexOf(containerId) === -1) {
this.data.addContainerNode(this.containers[containerId]);
} else if (newShownContainersIds.indexOf(containerId) === -1 &&
this.shownContainersIds.indexOf(containerId) > -1) {
this.data.removeContainersNodes(containerId);
}
}
this.shownContainersIds = newShownContainersIds;
};
this.showSelectedDownstream = function() {
var downstreamContainersIds = [];
for (var i=0; i < this.selectedContainersIds.length; i++) {
this.searchDownstream(this.selectedContainersIds[i], downstreamContainersIds);
}
this.updateShownContainers(downstreamContainersIds);
};
this.searchUpstream = function(containerId, upstreamContainersIds) {
if (upstreamContainersIds.indexOf(containerId) > -1) {
return;
}
upstreamContainersIds.push(containerId);
var container = this.containers[containerId];
for (var otherContainerId in this.containers) {
var otherContainer = this.containers[otherContainerId];
if (otherContainer.Links != null && otherContainer.Links[container.Name] != null) {
this.searchUpstream(otherContainer.Id, upstreamContainersIds);
} else if (otherContainer.VolumesFrom != null &&
otherContainer.VolumesFrom[container.Id] != null) {
this.searchUpstream(otherContainer.Id, upstreamContainersIds);
}
}
};
this.showSelectedUpstream = function() {
var upstreamContainersIds = [];
for (var i=0; i < this.selectedContainersIds.length; i++) {
this.searchUpstream(this.selectedContainersIds[i], upstreamContainersIds);
}
this.updateShownContainers(upstreamContainersIds);
}; };
this.showAll = function() { this.showAll = function() {
for (var i=0; i < this.containers.length; i++) { for (var containerId in this.containers) {
var container = this.containers[i]; if (this.shownContainersIds.indexOf(containerId) === -1) {
if (this.shownContainers.indexOf(container) === -1) { this.data.addContainerNode(this.containers[containerId]);
this.data.addContainerNode(container); this.shownContainersIds.push(containerId);
this.shownContainers.push(container);
} }
} }
}; };

View file

@ -19,7 +19,8 @@ angular.module('ngVis', [])
scope: { scope: {
data: '=', data: '=',
options: '=', options: '=',
events: '=' events: '=',
component: '='
}, },
link: function (scope, element, attr) { link: function (scope, element, attr) {
var timelineEvents = [ var timelineEvents = [
@ -46,6 +47,7 @@ angular.module('ngVis', [])
// Create the timeline object // Create the timeline object
timeline = new vis.Timeline(element[0]); timeline = new vis.Timeline(element[0]);
scope.component = timeline;
// Attach an event handler if defined // Attach an event handler if defined
angular.forEach(scope.events, function (callback, event) { angular.forEach(scope.events, function (callback, event) {
@ -169,7 +171,8 @@ angular.module('ngVis', [])
scope: { scope: {
data: '=', data: '=',
options: '=', options: '=',
events: '=' events: '=',
component: '='
}, },
link: function (scope, element, attr) { link: function (scope, element, attr) {
var graphEvents = [ var graphEvents = [
@ -181,6 +184,7 @@ angular.module('ngVis', [])
// Create the chart // Create the chart
var graph = new vis.Graph2d(element[0]); var graph = new vis.Graph2d(element[0]);
scope.component = graph;
scope.$watch('data', function () { scope.$watch('data', function () {
// Sanity check // Sanity check
@ -196,6 +200,7 @@ angular.module('ngVis', [])
// Create the graph2d object // Create the graph2d object
graph = new vis.Graph2d(element[0]); graph = new vis.Graph2d(element[0]);
scope.component = graph;
// Attach an event handler if defined // Attach an event handler if defined
angular.forEach(scope.events, function (callback, event) { angular.forEach(scope.events, function (callback, event) {