Drawing tree chart from real data
diff --git a/gui/ngXosViews/serviceTopology/bower.json b/gui/ngXosViews/serviceTopology/bower.json
index e945bd7..3d01c48 100644
--- a/gui/ngXosViews/serviceTopology/bower.json
+++ b/gui/ngXosViews/serviceTopology/bower.json
@@ -15,7 +15,8 @@
     "tests"
   ],
   "dependencies": {
-    "d3": "~3.5.13"
+    "d3": "~3.5.13",
+    "lodash": "~4.0.0"
   },
   "devDependencies": {
     "jquery": "~2.1.4",
diff --git a/gui/ngXosViews/serviceTopology/src/index.html b/gui/ngXosViews/serviceTopology/src/index.html
index 1627e38..c2a289e 100644
--- a/gui/ngXosViews/serviceTopology/src/index.html
+++ b/gui/ngXosViews/serviceTopology/src/index.html
@@ -21,6 +21,7 @@
 <script src="vendor/angular-resource/angular-resource.js"></script>
 <script src="vendor/ng-lodash/build/ng-lodash.js"></script>
 <script src="vendor/bootstrap-css/js/bootstrap.js"></script>
+<script src="vendor/lodash/lodash.js"></script>
 <!-- endbower --><!-- endjs -->
 <!-- inject:js -->
 <script src="/xosHelpers/src/xosHelpers.module.js"></script>
diff --git a/gui/ngXosViews/serviceTopology/src/js/main.js b/gui/ngXosViews/serviceTopology/src/js/main.js
index 1d86d86..3a46d61 100644
--- a/gui/ngXosViews/serviceTopology/src/js/main.js
+++ b/gui/ngXosViews/serviceTopology/src/js/main.js
@@ -17,22 +17,6 @@
 .config(function($httpProvider){
   $httpProvider.interceptors.push('NoHyperlinks');
 })
-.directive('usersList', function(){
-  return {
-    restrict: 'E',
-    scope: {},
-    bindToController: true,
-    controllerAs: 'vm',
-    templateUrl: 'templates/users-list.tpl.html',
-    controller: function(Services){
-      // retrieving user list
-      Services.query().$promise
-      .then((res) => {
-        console.log(res);
-      })
-      .catch((e) => {
-        throw new Error(e);
-      });
-    }
-  };
+.factory('_', function($window){
+  return window._;
 });
\ No newline at end of file
diff --git a/gui/ngXosViews/serviceTopology/src/js/services.js b/gui/ngXosViews/serviceTopology/src/js/services.js
index 93a1edb..640182d 100644
--- a/gui/ngXosViews/serviceTopology/src/js/services.js
+++ b/gui/ngXosViews/serviceTopology/src/js/services.js
@@ -3,7 +3,89 @@
 
   angular.module('xos.serviceTopology')
   .service('Services', function($resource){
-    return $resource('/xos/services');
+    return $resource('/xos/services/:id', {id: '@id'});
+  })
+  .service('Tenant', function($resource){
+    return $resource('/xos/tenants');
+  })
+  .service('ServiceRelation', function($q, _, lodash, Services, Tenant){
+
+    // find all the relation defined for a given root
+    const findLevelRelation = (tenants, rootId) => {
+      return lodash.filter(tenants, service => {
+        return service.subscriber_service === rootId;
+      });
+    };
+
+    // find all the service defined by a given array of relations
+    const findLevelServices = (relations, services) => {
+      const levelServices = [];
+      lodash.forEach(relations, (tenant) => {
+        var service = lodash.find(services, {id: tenant.provider_service});
+        levelServices.push(service);
+      });
+      return levelServices;
+    };
+
+    const buildLevel = (tenants, services, rootService, parentName = null) => {
+
+      const tree = {
+        name: rootService.humanReadableName,
+        parent: parentName,
+        children: []
+      };
+
+      // build an array of unlinked services
+      // these are the services that should still placed in the tree
+      var unlinkedServices = lodash.difference(services, [rootService]);
+
+      // find all relations relative to this rootElement
+      const levelRelation = findLevelRelation(tenants, rootService.id);
+
+      // find all items related to rootElement
+      const levelServices = findLevelServices(levelRelation, services);
+
+      // remove this item from the list (performance
+      unlinkedServices = lodash.difference(unlinkedServices, levelServices);
+
+      lodash.forEach(levelServices, (service) => {
+        tree.children.push(buildLevel(tenants, unlinkedServices, service, rootService.humanReadableName));
+      });
+
+      return tree;
+    };
+
+    const buildServiceTree = (services, tenants) => {
+
+      // find the root service
+      // it is the one attached to subsriber_root
+      // as now we have only one root so this can work
+      const rootServiceId = lodash.find(tenants, {subscriber_root: 1}).provider_service;
+      const rootService = lodash.find(services, {id: rootServiceId});
+
+      const serviceTree = buildLevel(tenants, services, rootService);
+
+      return serviceTree;
+    };
+
+    this.get = () => {
+      var deferred = $q.defer();
+      var services, tenants;
+      Services.query().$promise
+      .then((res) => {
+        services = res;
+        return Tenant.query().$promise;
+      })
+      .then((res) => {
+        tenants = res;
+        deferred.resolve(buildServiceTree(services, tenants));
+      })
+      .catch((e) => {
+        throw new Error(e);
+      });
+
+      return deferred.promise;
+    }
   });
 
 }());
\ No newline at end of file
diff --git a/gui/ngXosViews/serviceTopology/src/js/topologyCanvas.js b/gui/ngXosViews/serviceTopology/src/js/topologyCanvas.js
index 88d1388..8206194 100644
--- a/gui/ngXosViews/serviceTopology/src/js/topologyCanvas.js
+++ b/gui/ngXosViews/serviceTopology/src/js/topologyCanvas.js
@@ -9,7 +9,7 @@
       bindToController: true,
       controllerAs: 'vm',
       templateUrl: 'templates/topology_canvas.tpl.html',
-      controller: function($element, $window, d3, serviceTopologyConfig){
+      controller: function($element, $window, d3, serviceTopologyConfig, ServiceRelation){
 
         // count the mas depth of an object
         const depthOf = (obj) => {
@@ -25,6 +25,11 @@
           return 1 + depth
         };
 
+        ServiceRelation.get()
+          .then(res => {
+            //console.log(res);
+          });
+
         const treeData = [
           {
             'name': 'Top Level',
@@ -68,14 +73,13 @@
           .append('g')
           .attr("transform", "translate(" + serviceTopologyConfig.widthMargin+ "," + serviceTopologyConfig.heightMargin + ")");;
 
-        const resizeCanvas = () => {
-          var targetSize = svg.node().getBoundingClientRect();
-
-          d3.select(self.frameElement)
-            .attr('width', `${targetSize.width}px`)
-            .attr('height', `${targetSize.height}px`)
-        };
-
+        //const resizeCanvas = () => {
+        //  var targetSize = svg.node().getBoundingClientRect();
+        //
+        //  d3.select(self.frameElement)
+        //    .attr('width', `${targetSize.width}px`)
+        //    .attr('height', `${targetSize.height}px`)
+        //};
         //d3.select(window)
         //  .on('load', () => {
         //    resizeCanvas();
@@ -85,15 +89,17 @@
         //    resizeCanvas();
         //    update(root);
         //  });
-
-        var root = treeData[0];
-        root.x0 = $window.innerHeight / 2;
-        root.y0 = 0;
-
+        var root;
         var i = 0;
         var duration = 750;
 
-        update(root);
+        const draw = (tree) => {
+          root = tree;
+          root.x0 = $window.innerHeight / 2;
+          root.y0 = 0;
+
+          update(root);
+        };
 
         function update(source) {
 
@@ -194,6 +200,13 @@
             d.y0 = d.y;
           });
         }
+
+        ServiceRelation.get()
+        .then((tree) => {
+          console.log(tree);
+          draw(tree);
+        });
+        //draw(treeData[0]);
       }
     }
   });