blob: 8202c6783571c11483df3fd56e795a5da18b457d [file] [log] [blame]
Sean Condon50855cf2018-12-23 15:37:42 +00001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the 'License');
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an 'AS IS' BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16import {
17 ChangeDetectorRef,
18 Component, EventEmitter,
19 Input, OnChanges, Output, SimpleChanges,
20} from '@angular/core';
21import {Link, LinkHighlight, UiElement} from '../../models';
22import {LogService} from 'gui2-fw-lib';
23import {NodeVisual} from '../nodevisual';
24import {animate, state, style, transition, trigger} from '@angular/animations';
25
26interface Point {
27 x: number;
28 y: number;
29}
30
31enum LinkEnd {
32 A,
33 B
34}
35
36@Component({
37 selector: '[onos-linksvg]',
38 templateUrl: './linksvg.component.html',
39 styleUrls: ['./linksvg.component.css'],
40 animations: [
41 trigger('linkLabelVisible', [
42 state('true', style( {
43 opacity: 1.0,
44 })),
45 state( 'false', style({
46 opacity: 0
47 })),
48 transition('false => true', animate('500ms ease-in')),
49 transition('true => false', animate('1000ms ease-out'))
50 ])
51 ]
52})
53export class LinkSvgComponent extends NodeVisual implements OnChanges {
54 @Input() link: Link;
55 @Input() highlighted: string = '';
56 @Input() label: string;
57 isHighlighted: boolean = false;
58 @Output() selectedEvent = new EventEmitter<UiElement>();
59 @Output() enhancedEvent = new EventEmitter<Link>();
60 enhanced: boolean = false;
61 labelPosSrc: Point = {x: 0, y: 0};
62 labelPosTgt: Point = {x: 0, y: 0};
63
64 constructor(
65 protected log: LogService,
66 private ref: ChangeDetectorRef
67 ) {
68 super();
69 }
70
71 ngOnChanges(changes: SimpleChanges) {
72 if (changes['linkHighlight']) {
73 const hl: LinkHighlight = changes['linkHighlight'].currentValue;
74 this.highlighted = hl.css;
75 this.label = hl.label;
76 this.isHighlighted = true;
77 setTimeout(() => {
78 this.isHighlighted = false;
79 this.highlighted = '';
80 this.ref.markForCheck();
81 }, 4990);
82
83 }
84
85 this.ref.markForCheck();
86 }
87
88 enhance() {
89 this.enhancedEvent.emit(this.link);
90 this.enhanced = true;
91 this.repositionLabels();
92 setTimeout(() => {
93 this.enhanced = false;
94 this.ref.markForCheck();
95 }, 1000);
96 }
97
98 /**
99 * We want to place the label for the port about 40 px from the node
100 * If the distance between the nodes is less than 100, then just place the
101 * label 1/3 of the way from the node
102 */
103 repositionLabels(): void {
104 const x1: number = this.link.source.x;
105 const y1: number = this.link.source.y;
106 const x2: number = this.link.target.x;
107 const y2: number = this.link.target.y;
108
109 const dist = Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
110 const offset = dist > 100 ? 40 : dist / 3;
111 this.labelPosSrc = <Point>{
112 x: x1 + (x2 - x1) * offset / dist,
113 y: y1 + (y2 - y1) * offset / dist
114 };
115
116 this.labelPosTgt = <Point>{
117 x: x2 - (x2 - x1) * offset / dist,
118 y: y2 - (y2 - y1) * offset / dist
119 };
120 }
121
122 /**
123 * For the 14pt font we are using, the average width seems to be about 8px
124 * @param text The string we want to calculate a width for
125 */
126 textLength(text: string) {
127 return text.length * 8;
128 }
129}