Drawing logic layer shapes
diff --git a/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js b/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
index 56d1f56..d33de36 100644
--- a/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
+++ b/views/ngXosViews/diagnostic/src/js/logicTopologyHelper.js
@@ -2,104 +2,7 @@
   'use strict';
 
   angular.module('xos.serviceTopology')
-  .service('LogicTopologyHelper', function($window, $log, lodash, serviceTopologyConfig){
-
-    var hStep, vStep;
-
-    const createDevice = (container, device, xPos, yPos, target) => {
-
-      const deviceGroup = container.append('g')
-      .attr({
-        class: 'device',
-        transform: `translate(${xPos}, ${yPos})`
-      });
-
-      const deviceEl = deviceGroup.append('circle')
-      .attr({
-        r: serviceTopologyConfig.circle.radius
-      });
-
-      deviceGroup.append('text')
-      .attr({
-        x: - serviceTopologyConfig.circle.radius - 3,
-        dy: '.35em',
-        'text-anchor': 'end'
-      })
-      .text(device.name)
-
-      const [deviceX, deviceY] = d3.transform(deviceEl.attr('transform')).translate;
-      const [deviceGroupX, deviceGroupY] = d3.transform(deviceGroup.attr('transform')).translate;
-      let [targetX, targetY] = d3.transform(target.attr('transform')).translate;
-
-      targetX = targetX - deviceGroupX;
-      targetY = targetY - deviceGroupY;
-
-      console.log('Device: ' + deviceX, deviceY);
-      console.log('Subscriber: ' + targetX, targetY);
-
-      var diagonal = d3.svg.diagonal()
-      .source({x: deviceX, y: deviceY})
-      .target({x: targetX, y: targetY})
-      // .projection(d => {
-      //   return [d.y, d.x];
-      // });
-
-      deviceGroup
-        .append('path')
-        .attr('class', 'device-link')
-        .attr('d', diagonal);
-    }
-
-    const createSubscriber = (container, subscriber, xPos, yPos) => {
-
-      const subscriberGroup = container.append('g')
-      .attr({
-        class: 'subscriber',
-        transform: `translate(${xPos * 2}, ${yPos})`
-      });
-
-      subscriberGroup.append('circle')
-      .attr({
-        r: serviceTopologyConfig.circle.radius
-      });
-
-      subscriberGroup.append('text')
-      .attr({
-        x: serviceTopologyConfig.circle.radius + 3,
-        dy: '.35em',
-        'text-anchor': 'start'
-      })
-      .text(subscriber.humanReadableName)
-
-      // TODO
-      // starting from the subscriber position, we should center
-      // the device goup based on his own height
-      // const deviceContainer = container.append('g')
-      // .attr({
-      //   class: 'devices-container',
-      //   transform: `translate(${xPos}, ${yPos -(vStep / 2)})`
-      // });
-
-      angular.forEach(subscriber.devices, (device, j) => {
-        createDevice(container, device, xPos, ((vStep / subscriber.devices.length) * j) + (yPos - vStep / 2), subscriberGroup);
-      });
-    }
-
-    this.handleSubscribers = (svg, subscribers) => {
-
-      // HACKY
-      hStep = angular.element(svg[0])[0].clientWidth / 7;
-      vStep = angular.element(svg[0])[0].clientHeight / (subscribers.length + 1);
-
-      const container = svg.append('g')
-      .attr({
-        class: 'subscribers-container'
-      });
-
-      lodash.forEach(subscribers, (subscriber, i) => {
-        createSubscriber(container, subscriber, hStep, vStep * (i + 1));
-      })
-    }
+  .service('LogicTopologyHelper', function($window, $log, lodash, serviceTopologyConfig, NodeDrawer){
 
     var diagonal, nodes, links, i = 0, svgWidth, svgHeight, layout;
 
@@ -127,6 +30,10 @@
       ]
     };
 
+    /**
+    * from a nested data structure,
+    * create nodes and links for a D3 Tree Layout
+    */
     const computeLayout = (data) => {
       let nodes = layout.nodes(data);
 
@@ -138,41 +45,35 @@
       });
 
       let links = layout.links(nodes);
-      console.log(nodes.length, links.length);
+
       return [nodes, links];
     };
 
+    /**
+    * Draw the containing group for any node or update the existing one
+    */
     const drawNodes = (svg, nodes) => {
       // Update the nodes…
       var node = svg.selectAll('g.node')
-      .data(nodes, d => {return d.id || (d.id = `tree-${i++}`)});
+      .data(nodes, d => {
+        if(!angular.isString(d.d3Id)){
+          d.d3Id = `tree-${++i}`;
+        }
+        return d.d3Id;
+      });
 
-      // Enter any new nodes at the parent's previous position.
+      // Enter any new nodes
       var nodeEnter = node.enter().append('g')
       .attr({
         class: d => `node ${d.type}`,
         transform: `translate(${svgWidth / 2}, ${svgHeight / 2})`
       });
 
-      nodeEnter.append('circle')
-        .attr('r', 10)
-        .style('fill', d => d._children ? 'lightsteelblue' : '#fff');
-
-      nodeEnter.append('text')
-        .attr({
-          x: d => d.children ? serviceTopologyConfig.circle.selectedRadius + 3 : -serviceTopologyConfig.circle.selectedRadius - 3,
-          dy: '.35em',
-          transform: d => {
-            if (d.children && d.parent){
-              if(d.parent.x < d.x){
-                return 'rotate(-30)';
-              }
-              return 'rotate(30)';
-            }
-          },
-          'text-anchor': d => d.children ? 'start' : 'end'
-        })
-        .text(d => d.name);
+      NodeDrawer.addNetworks(nodeEnter.filter('.network'));
+      NodeDrawer.addRack(nodeEnter.filter('.rack'));
+      NodeDrawer.addPhisical(nodeEnter.filter('.router'));
+      NodeDrawer.addPhisical(nodeEnter.filter('.subscriber'));
+      NodeDrawer.addDevice(nodeEnter.filter('.device'));
 
       // Transition nodes to their new position.
       var nodeUpdate = node.transition()
@@ -184,6 +85,9 @@
       // TODO handle node remove
     };
 
+    /**
+    * Handle links in the tree layout
+    */
     const drawLinks = (svg, links) => {
 
       diagonal = d3.svg.diagonal()
@@ -192,7 +96,7 @@
       // Update the links…
       var link = svg.selectAll('path.link')
         .data(links, d => {
-          return d.target.id
+          return d.target.d3Id
         });
 
       // Enter any new links at the parent's previous position.
@@ -209,6 +113,9 @@
         .attr('d', diagonal);
     };
 
+    /**
+    * Calculate the svg size and setup tree layout
+    */
     this.drawTree = (svg) => {
       
 
@@ -229,10 +136,11 @@
       
     };
 
+    /**
+    * Add Subscribers to the tree
+    */
     this.addSubscribers = (svg, subscribers) => {
 
-      console.log(subscribers);
-
       subscribers.map((subscriber) => {
         subscriber.children = subscriber.devices;
       });
@@ -240,8 +148,6 @@
       // add subscriber to data tree
       baseData.children[0].children[0].children[0].children = subscribers;
 
-      console.log(baseData);
-
       [nodes, links] = computeLayout(baseData);
 
       drawNodes(svg, nodes);