GUI2 Extract Topology view in to its own library
Change-Id: I45597d0902c99b5b3d606966866cc518011c54a0
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.css b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.css
new file mode 100644
index 0000000..92a114f
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.css
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*
+ ONOS GUI -- Topology View (forces host visual) -- CSS file
+ */
+.node.host text {
+ stroke: none;
+ font-size: 13px;
+ fill: #846;
+}
+
+.node.host circle {
+ stroke: #a3a596;
+ fill: #e0dfd6;
+}
+
+.node.host.selected > circle {
+ stroke-width: 2.0;
+ stroke: #009fdb;
+}
+
+.node.host use {
+ fill: #3c3a3a;
+}
+
+.node.host rect {
+ fill: #ffffff;
+}
\ No newline at end of file
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html
new file mode 100644
index 0000000..ccce65a
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.html
@@ -0,0 +1,70 @@
+<!--
+~ Copyright 2018-present Open Networking Foundation
+~
+~ Licensed under the Apache License, Version 2.0 (the "License");
+~ you may not use this file except in compliance with the License.
+~ You may obtain a copy of the License at
+~
+~ http://www.apache.org/licenses/LICENSE-2.0
+~
+~ Unless required by applicable law or agreed to in writing, software
+~ distributed under the License is distributed on an "AS IS" BASIS,
+~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+~ See the License for the specific language governing permissions and
+~ limitations under the License.
+-->
+<svg:defs xmlns:svg="http://www.w3.org/2000/svg">
+ <!-- Template explanation: Define an SVG Filter that in
+ line 1) render the target object in to a bit map and apply a blur to it
+ based on its alpha channel
+ line 2) take that blurred layer and shift it down and to the right by 4
+ line 3) Merge this blurred and shifted layer and overlay it with the
+ original target object
+ -->
+ <svg:filter id="drop-shadow-host" x="-25%" y="-25%" width="200%" height="200%">
+ <svg:feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur" />
+ <svg:feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
+ <svg:feMerge >
+ <svg:feMergeNode in="offsetBlur" />
+ <svg:feMergeNode in="SourceGraphic" />
+ </svg:feMerge>
+ </svg:filter>
+ <svg:radialGradient id="three_stops_radial">
+ <svg:stop offset= "0%" style="stop-color: #e3e5d6;" />
+ <svg:stop offset= "70%" style="stop-color: #c3c5b6;" />
+ <svg:stop offset="100%" style="stop-color: #a3a596;" />
+ </svg:radialGradient>
+</svg:defs>
+<!-- Template explanation: Creates an SVG Group and in
+ line 1) transform it to the position calculated by the d3 force graph engine
+ line 2) Give it various CSS styles depending on attributes
+ line 3) When it is clicked, call the method that toggles the selection and
+ emits an event.
+ Other child objects have their own description
+-->
+<svg:g xmlns:svg="http://www.w3.org/2000/svg"
+ [attr.transform]="'translate(' + host?.x + ',' + host?.y + '), scale(' + scale + ')'"
+ [ngClass]="['node', 'host', 'endstation', 'fixed', selected?'selected':'', 'hovered']"
+ (click)="toggleSelected(host)">
+ <svg:desc>Host {{host.id}}</svg:desc>
+ <!-- Template explanation: Creates an SVG Circle and in
+ line 1) Apply the drop shadow defined above to this circle
+ line 2) Apply the radial gradient defined above to the circle
+ -->
+ <svg:circle r="15"
+ filter="url(#drop-shadow-host)"
+ style="fill: url(#three_stops_radial)">
+ </svg:circle>
+ <svg:use xlink:href="#m_endstation" width="22.5" height="22.5" x="-11.25" y="-11.25">
+ </svg:use>
+ <!-- Template explanation: Creates an SVG Text
+ line 1) if the labelToggle is not 0
+ line 2) shift it below the circle, and have it centred with the circle
+ line 3) apply a scale and call on the hostName(0 method to get the
+ displayed value
+ -->
+ <svg:text
+ *ngIf="labelToggle != 0"
+ dy="30" text-anchor="middle"
+ >{{hostName()}}</svg:text>
+</svg:g>
\ No newline at end of file
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.spec.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.spec.ts
new file mode 100644
index 0000000..e3efb3f
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.spec.ts
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HostNodeSvgComponent } from './hostnodesvg.component';
+import {ActivatedRoute, Params} from '@angular/router';
+import {of} from 'rxjs';
+import {LogService} from 'gui2-fw-lib';
+import {Host} from '../../models';
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
+import {ChangeDetectorRef} from '@angular/core';
+
+class MockActivatedRoute extends ActivatedRoute {
+ constructor(params: Params) {
+ super();
+ this.queryParams = of(params);
+ }
+}
+
+describe('HostNodeSvgComponent', () => {
+ let logServiceSpy: jasmine.SpyObj<LogService>;
+ let component: HostNodeSvgComponent;
+ let fixture: ComponentFixture<HostNodeSvgComponent>;
+ let ar: MockActivatedRoute;
+ let testHost: Host;
+
+ beforeEach(async(() => {
+ const logSpy = jasmine.createSpyObj('LogService', ['info', 'debug', 'warn', 'error']);
+ ar = new MockActivatedRoute({ 'debug': 'txrx' });
+ testHost = new Host('host:1');
+ testHost.ips = ['10.205.86.123', '192.168.56.10'];
+
+ TestBed.configureTestingModule({
+ imports: [ BrowserAnimationsModule ],
+ declarations: [ HostNodeSvgComponent ],
+ providers: [
+ { provide: LogService, useValue: logSpy },
+ { provide: ActivatedRoute, useValue: ar },
+ { provide: ChangeDetectorRef, useClass: ChangeDetectorRef }
+ ]
+ })
+ .compileComponents();
+ logServiceSpy = TestBed.get(LogService);
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(HostNodeSvgComponent);
+ component = fixture.componentInstance;
+ component.host = testHost;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts
new file mode 100644
index 0000000..26c105a
--- /dev/null
+++ b/web/gui2-topo-lib/projects/gui2-topo-lib/src/lib/layer/forcesvg/visuals/hostnodesvg/hostnodesvg.component.ts
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {
+ Component,
+ EventEmitter,
+ Input,
+ OnChanges,
+ Output,
+ SimpleChanges
+} from '@angular/core';
+import {Host, HostLabelToggle, Node} from '../../models';
+import {LogService} from 'gui2-fw-lib';
+import {NodeVisual} from '../nodevisual';
+
+/**
+ * The Host node in the force graph
+ *
+ * Note: here the selector is given square brackets [] so that it can be
+ * inserted in SVG element like a directive
+ */
+@Component({
+ selector: '[onos-hostnodesvg]',
+ templateUrl: './hostnodesvg.component.html',
+ styleUrls: ['./hostnodesvg.component.css']
+})
+export class HostNodeSvgComponent extends NodeVisual implements OnChanges {
+ @Input() host: Host;
+ @Input() scale: number = 1.0;
+ @Input() labelToggle: HostLabelToggle.Enum = HostLabelToggle.Enum.IP;
+ @Output() selectedEvent = new EventEmitter<Node>();
+
+ constructor(
+ protected log: LogService
+ ) {
+ super();
+ }
+
+ ngOnChanges(changes: SimpleChanges) {
+ if (!this.host.x) {
+ this.host.x = 0;
+ this.host.y = 0;
+ }
+ }
+
+ hostName(): string {
+ if (this.host === undefined) {
+ return undefined;
+ } else if (this.labelToggle === HostLabelToggle.Enum.IP) {
+ return this.host.ips.join(',');
+ } else if (this.labelToggle === HostLabelToggle.Enum.MAC) {
+ return this.host.id;
+ } else {
+ return this.host.id; // Todo - replace with a friendly name
+ }
+
+ }
+}