Added d3 force graph to GUI2 topology

Change-Id: I6860472efaf51ea27fad74e630e687f0c6abad3d
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
index d74991c..d72a2e0 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.html
@@ -21,13 +21,13 @@
 <onos-details #details></onos-details>
 
 <div id="ov-topo2">
-    <svg viewBox="0 0 1000 1000" id="topo2">
+    <svg:svg #svgZoom xmlns:svg="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000" id="topo2">
         <svg:g onos-nodeviceconnected />
-        <svg:g id="topo-zoomlayer">
+        <svg:g id="topo-zoomlayer" onosZoomableOf [zoomableOf]="svgZoom">
             <svg:g #background onos-backgroundsvg/>
-            <svg:g #force onos-forcesvg/>
+            <svg:g #force onos-forcesvg (selectedNodeEvent)="nodeSelected($event)"/>
         </svg:g>
-    </svg>
+    </svg:svg>
 </div>
 
 <div id="breadcrumbs"></div>
\ No newline at end of file
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
index d98a55c..a9c6194 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.spec.ts
@@ -34,6 +34,7 @@
     FnService,
     LogService
 } from 'gui2-fw-lib';
+import {ZoomableDirective} from '../layer/zoomable.directive';
 
 
 class MockActivatedRoute extends ActivatedRoute {
@@ -107,14 +108,15 @@
                 SummaryComponent,
                 ToolbarComponent,
                 DetailsComponent,
-                FlashComponent
+                FlashComponent,
+                ZoomableDirective
             ],
             providers: [
                 { provide: FnService, useValue: fs },
                 { provide: LogService, useValue: logSpy },
                 { provide: 'Window', useValue: windowMock },
                 { provide: HttpClient, useClass: MockHttpClient },
-                { provide: TopologyService, useClass: MockTopologyService }
+                { provide: TopologyService, useClass: MockTopologyService },
             ]
         }).compileComponents();
         logServiceSpy = TestBed.get(LogService);
diff --git a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
index 728347d..d4decb0 100644
--- a/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
+++ b/web/gui2/src/main/webapp/app/view/topology/topology/topology.component.ts
@@ -13,20 +13,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
+import {
+    Component,
+    OnDestroy,
+    OnInit,
+    ViewChild
+} from '@angular/core';
 import * as d3 from 'd3';
 import {
     FnService,
-    KeysService, KeysToken,
-    LogService, PrefsService,
-    SvgUtilService, WebSocketService, Zoomer, ZoomOpts, ZoomService
+    KeysService,
+    KeysToken,
+    LogService,
+    PrefsService,
+    SvgUtilService,
+    WebSocketService,
+    Zoomer,
+    ZoomOpts,
+    ZoomService
 } from 'gui2-fw-lib';
-import { InstanceComponent } from '../panel/instance/instance.component';
-import { SummaryComponent } from '../panel/summary/summary.component';
-import { DetailsComponent } from '../panel/details/details.component';
-import { BackgroundSvgComponent } from '../layer/backgroundsvg/backgroundsvg.component';
-import { ForceSvgComponent } from '../layer/forcesvg/forcesvg.component';
-import { TopologyService } from '../topology.service';
+import {InstanceComponent} from '../panel/instance/instance.component';
+import {SummaryComponent} from '../panel/summary/summary.component';
+import {DetailsComponent} from '../panel/details/details.component';
+import {BackgroundSvgComponent} from '../layer/backgroundsvg/backgroundsvg.component';
+import {ForceSvgComponent} from '../layer/forcesvg/forcesvg.component';
+import {TopologyService} from '../topology.service';
+import {Node} from '../layer/forcesvg/models';
 
 /**
  * ONOS GUI Topology View
@@ -236,6 +248,7 @@
     protected cycleDeviceLabels() {
         this.log.debug('Cycling device labels');
         // TODO: Reinstate with components
+        this.force.updateDeviceLabelToggle();
         // let deviceLabelIndex = t2ps.get('dlbls') + 1;
         // let newDeviceLabelIndex = deviceLabelIndex % 3;
         //
@@ -262,9 +275,12 @@
     }
 
     protected toggleDetails(token: KeysToken) {
-        this.flashMsg = 'Toggling details';
-        this.details.togglePanel(() => {});
-        this.log.debug('Toggling details', token);
+        if (this.details.selectedNode) {
+            this.flashMsg = 'Toggling details';
+            this.details.togglePanel(() => {
+            });
+            this.log.debug('Toggling details', token);
+        }
     }
 
     protected toggleInstancePanel(token: KeysToken) {
@@ -426,4 +442,9 @@
         this.zoomer.panZoom(translate, scale, transition);
     }
 
+    nodeSelected(node: Node) {
+        this.details.selectedNode = node;
+        this.details.on = Boolean(node);
+    }
+
 }