diff --git a/README.md b/README.md
index 178451b16..7b1b693a3 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ DockerUI listens on port 9000 by default. If you run DockerUI inside a container
* [Gritter](https://github.com/jboesch/Gritter)
* [Spin.js](https://github.com/fgnass/spin.js/)
* [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:
diff --git a/app/components/containersNetwork/containersNetwork.html b/app/components/containersNetwork/containersNetwork.html
index fe2eea40f..e9bce03de 100644
--- a/app/components/containersNetwork/containersNetwork.html
+++ b/app/components/containersNetwork/containersNetwork.html
@@ -11,6 +11,8 @@
+
+
diff --git a/app/components/containersNetwork/containersNetworkController.js b/app/components/containersNetwork/containersNetworkController.js
index d2537dc7b..3219a0951 100644
--- a/app/components/containersNetwork/containersNetworkController.js
+++ b/app/components/containersNetwork/containersNetworkController.js
@@ -8,7 +8,7 @@ angular.module('containersNetwork', ['ngVis'])
this.Image = data.Config.Image;
var dataLinks = data.HostConfig.Links;
if (dataLinks != null) {
- this.Links = [];
+ this.Links = {};
for (var i = 0; i < dataLinks.length; i++) {
// links have the following format: /TargetContainerName:/SourceContainerName/LinkAlias
var link = dataLinks[i].split(":");
@@ -23,7 +23,7 @@ angular.module('containersNetwork', ['ngVis'])
var dataVolumes = data.HostConfig.VolumesFrom;
//converting array into properties for simpler and faster access
if (dataVolumes != null) {
- this.VolumesFrom = [];
+ this.VolumesFrom = {};
for (var j = 0; j < dataVolumes.length; j++) {
this.VolumesFrom[dataVolumes[j]] = true;
}
@@ -69,12 +69,12 @@ angular.module('containersNetwork', ['ngVis'])
function ContainersNetwork() {
this.data = new ContainersNetworkData();
- this.containers = [];
- this.selectedContainers = [];
- this.shownContainers = [];
+ this.containers = {};
+ this.selectedContainersIds = [];
+ this.shownContainersIds = [];
this.events = {
select : function(event) {
- $scope.network.selectedContainers = event.nodes;
+ $scope.network.selectedContainersIds = event.nodes;
$scope.$apply( function() {
$scope.query = '';
});
@@ -104,11 +104,11 @@ angular.module('containersNetwork', ['ngVis'])
this.addContainer = function(data) {
var container = new ContainerNode(data);
- this.containers.push(container);
- this.shownContainers.push(container);
+ this.containers[container.Id] = container;
+ this.shownContainersIds.push(container.Id);
this.data.addContainerNode(container);
- for (var i = 0; i < this.containers.length; i++) {
- var otherContainer = this.containers[i];
+ for (var otherContainerId in this.containers) {
+ var otherContainer = this.containers[otherContainerId];
this.data.addLinkEdgeIfExists(container, otherContainer);
this.data.addLinkEdgeIfExists(otherContainer, container);
this.data.addVolumeEdgeIfExists(container, otherContainer);
@@ -118,8 +118,8 @@ angular.module('containersNetwork', ['ngVis'])
this.selectContainers = function(query) {
if (this.component != null) {
- this.selectedContainers = this.searchContainers(query);
- this.component.selectNodes(this.selectedContainers);
+ this.selectedContainersIds = this.searchContainers(query);
+ this.component.selectNodes(this.selectedContainersIds);
}
};
@@ -127,38 +127,103 @@ angular.module('containersNetwork', ['ngVis'])
if (query.trim() === "") {
return [];
}
- var selectedContainers = [];
- for (var i=0; i < this.shownContainers.length; i++) {
- var container = this.shownContainers[i];
+ var selectedContainersIds = [];
+ for (var i=0; i < this.shownContainersIds.length; i++) {
+ var container = this.containers[this.shownContainersIds[i]];
if (container.Name.indexOf(query) > -1 ||
container.Image.indexOf(query) > -1 ||
container.Id.indexOf(query) > -1) {
- selectedContainers.push(container.Id);
+ selectedContainersIds.push(container.Id);
}
}
- return selectedContainers;
+ return selectedContainersIds;
};
this.hideSelected = function() {
var i=0;
- while ( i < this.shownContainers.length ) {
- if (this.selectedContainers.indexOf(this.shownContainers[i].Id) > -1) {
- this.shownContainers.splice(i, 1);
+ while ( i < this.shownContainersIds.length ) {
+ if (this.selectedContainersIds.indexOf(this.shownContainersIds[i]) > -1) {
+ this.shownContainersIds.splice(i, 1);
} else {
i++;
}
}
- this.data.removeContainersNodes(this.selectedContainers);
+ this.data.removeContainersNodes(this.selectedContainersIds);
$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() {
- for (var i=0; i < this.containers.length; i++) {
- var container = this.containers[i];
- if (this.shownContainers.indexOf(container) === -1) {
- this.data.addContainerNode(container);
- this.shownContainers.push(container);
+ for (var containerId in this.containers) {
+ if (this.shownContainersIds.indexOf(containerId) === -1) {
+ this.data.addContainerNode(this.containers[containerId]);
+ this.shownContainersIds.push(containerId);
}
}
};
diff --git a/assets/js/angular-vis.js b/assets/js/angular-vis.js
index a0347fb5d..4d594a00b 100755
--- a/assets/js/angular-vis.js
+++ b/assets/js/angular-vis.js
@@ -19,7 +19,8 @@ angular.module('ngVis', [])
scope: {
data: '=',
options: '=',
- events: '='
+ events: '=',
+ component: '='
},
link: function (scope, element, attr) {
var timelineEvents = [
@@ -46,6 +47,7 @@ angular.module('ngVis', [])
// Create the timeline object
timeline = new vis.Timeline(element[0]);
+ scope.component = timeline;
// Attach an event handler if defined
angular.forEach(scope.events, function (callback, event) {
@@ -169,7 +171,8 @@ angular.module('ngVis', [])
scope: {
data: '=',
options: '=',
- events: '='
+ events: '=',
+ component: '='
},
link: function (scope, element, attr) {
var graphEvents = [
@@ -181,6 +184,7 @@ angular.module('ngVis', [])
// Create the chart
var graph = new vis.Graph2d(element[0]);
+ scope.component = graph;
scope.$watch('data', function () {
// Sanity check
@@ -196,6 +200,7 @@ angular.module('ngVis', [])
// Create the graph2d object
graph = new vis.Graph2d(element[0]);
+ scope.component = graph;
// Attach an event handler if defined
angular.forEach(scope.events, function (callback, event) {