blob: 048e2f9e5ce6ef63cd66ad8bdc2d5916bc1559a3 [file] [log] [blame]
Steven Burrowsec1f45c2016-08-08 16:14:41 +01001/*
2 * Copyright 2016-present Open Networking Laboratory
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 */
16
17/*
Steven Burrows1c5c8612016-10-05 13:45:13 -050018 ONOS GUI -- Topology Node Module.
19 Module that contains model for nodes within the topology
Steven Burrowsec1f45c2016-08-08 16:14:41 +010020 */
21
22(function () {
23 'use strict';
24
Steven Burrows1c5c8612016-10-05 13:45:13 -050025 var ps, sus, is, ts, t2mcs, t2nps, fn;
Steven Burrowsec1f45c2016-08-08 16:14:41 +010026
Steven Burrows6deb4ce2016-08-26 16:06:23 +010027 var devIconDim = 36,
Steven Burrows0616e802016-10-06 21:45:07 -050028 devIconDimMin = 20,
29 devIconDimMax = 40,
Steven Burrowsbbe3dda2016-09-26 14:41:59 -070030 labelPad = 5,
31 textPad = 5,
32 halfDevIcon = devIconDim / 2;
33
34 // note: these are the device icon colors without affinity (no master)
35 var dColTheme = {
36 light: {
37 online: '#444444',
38 offline: '#cccccc'
39 },
40 dark: {
41 // TODO: theme
42 online: '#444444',
43 offline: '#cccccc'
44 }
45 };
46
47 function devGlyphColor(d) {
48 var o = this.get('online'),
49 id = this.get('master'),
50 otag = o ? 'online' : 'offline';
51 return o ? sus.cat7().getColor(id, 0, ts.theme()) :
52 dColTheme[ts.theme()][otag];
53 }
Steven Burrows6deb4ce2016-08-26 16:06:23 +010054
Steven Burrowsec1f45c2016-08-08 16:14:41 +010055 angular.module('ovTopo2')
56 .factory('Topo2NodeModel',
Steven Burrows1c5c8612016-10-05 13:45:13 -050057 ['Topo2Model', 'FnService', 'Topo2PrefsService',
Steven Burrows482d9502016-09-27 11:24:58 -070058 'SvgUtilService', 'IconService', 'ThemeService',
Steven Burrows1c5c8612016-10-05 13:45:13 -050059 'Topo2MapConfigService', 'Topo2ZoomService', 'Topo2NodePositionService',
60 function (Model, _fn_, _ps_, _sus_, _is_, _ts_,
61 _t2mcs_, zoomService, _t2nps_) {
Steven Burrowsec1f45c2016-08-08 16:14:41 +010062
Steven Burrowsbbe3dda2016-09-26 14:41:59 -070063 ts = _ts_;
Steven Burrowsec1f45c2016-08-08 16:14:41 +010064 fn = _fn_;
Steven Burrows37549ee2016-09-21 14:41:39 +010065 ps = _ps_;
Steven Burrowsbbe3dda2016-09-26 14:41:59 -070066 sus = _sus_;
67 is = _is_;
Steven Burrowse7cc3082016-09-27 11:24:58 -070068 t2mcs = _t2mcs_;
Steven Burrows1c5c8612016-10-05 13:45:13 -050069 t2nps = _t2nps_;
Steven Burrowsec1f45c2016-08-08 16:14:41 +010070
71 return Model.extend({
72 initialize: function () {
73 this.node = this.createNode();
Steven Burrows1c5c8612016-10-05 13:45:13 -050074 this._events = {
75 'mouseover': 'mouseoverHandler',
76 'mouseout': 'mouseoutHandler'
77 };
Steven Burrowsec1f45c2016-08-08 16:14:41 +010078 },
Steven Burrowse7cc3082016-09-27 11:24:58 -070079 createNode: function () {
Steven Burrowse7cc3082016-09-27 11:24:58 -070080 this.set('svgClass', this.svgClassName());
Steven Burrows1c5c8612016-10-05 13:45:13 -050081 t2nps.positionNode(this);
Steven Burrowse7cc3082016-09-27 11:24:58 -070082 return this;
83 },
Steven Burrowsbbe3dda2016-09-26 14:41:59 -070084 setUpEvents: function () {
Steven Burrows1c5c8612016-10-05 13:45:13 -050085 var _this = this,
86 events = angular.extend({}, this._events, this.events);
87 angular.forEach(events, function (handler, key) {
Steven Burrowsbbe3dda2016-09-26 14:41:59 -070088 _this.el.on(key, _this[handler].bind(_this));
89 });
90 },
Steven Burrows1c5c8612016-10-05 13:45:13 -050091 mouseoverHandler: function () {
92 this.set('hovered', true);
93 },
94 mouseoutHandler: function () {
95 this.set('hovered', false);
96 },
Steven Burrowsbbe3dda2016-09-26 14:41:59 -070097 icon: function () {
98 return 'unknown';
99 },
Steven Burrows583f4be2016-11-04 14:06:50 +0100100 labelIndex: function () {
101 return ps.get('dlbls');
102 },
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100103 label: function () {
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100104 var props = this.get('props'),
105 id = this.get('id'),
Steven Burrows1c5c8612016-10-05 13:45:13 -0500106 friendlyName = props && props.name ? props.name : id,
107 labels = ['', friendlyName || id, id],
Steven Burrows583f4be2016-11-04 14:06:50 +0100108 nli = this.labelIndex(),
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100109 idx = (nli < labels.length) ? nli : 0;
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100110
111 return labels[idx];
112 },
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100113 trimLabel: function (label) {
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100114 return (label && label.trim()) || '';
115 },
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100116 computeLabelWidth: function (el) {
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100117 var text = el.select('text'),
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100118 box = text.node().getBBox();
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100119 return box.width + labelPad * 2;
120 },
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100121 addLabelElements: function (label) {
Steven Burrows1c5c8612016-10-05 13:45:13 -0500122 var rect = this.el.append('rect')
123 .attr('class', 'node-container');
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700124 var glythRect = this.el.append('rect')
125 .attr('y', -halfDevIcon)
126 .attr('x', -halfDevIcon)
127 .attr('width', devIconDim)
128 .attr('height', devIconDim)
129 .style('fill', devGlyphColor.bind(this));
130
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100131 var text = this.el.append('text').text(label)
132 .attr('text-anchor', 'left')
133 .attr('y', '0.3em')
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700134 .attr('x', halfDevIcon + labelPad + textPad);
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100135
136 return {
137 rect: rect,
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700138 glythRect: glythRect,
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100139 text: text
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100140 };
Steven Burrows6deb4ce2016-08-26 16:06:23 +0100141 },
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700142 labelBox: function (dim, labelWidth) {
143 var _textPad = (textPad * 2) - labelPad;
144
145 if (labelWidth === 0) {
146 _textPad = 0;
147 }
148
149 return {
150 x: -dim / 2 - labelPad,
151 y: -dim / 2 - labelPad,
152 width: dim + labelWidth + (labelPad * 2) + _textPad,
153 height: dim + (labelPad * 2)
154 };
155 },
156 iconBox: function (dim, labelWidth) {
Steven Burrows37549ee2016-09-21 14:41:39 +0100157 return {
158 x: -dim / 2,
159 y: -dim / 2,
160 width: dim + labelWidth,
161 height: dim
162 };
163 },
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100164 svgClassName: function () {
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100165 return fn.classNames('node',
166 this.nodeType,
167 this.get('type'),
168 {
Steven Burrows1c5c8612016-10-05 13:45:13 -0500169 online: this.get('online'),
170 selected: this.get('selected')
Steven Burrowsdfa52b02016-09-02 13:50:43 +0100171 }
172 );
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100173 },
Steven Burrowse7cc3082016-09-27 11:24:58 -0700174 lngLatFromCoord: function (coord) {
175 var p = t2mcs.projection();
176 return p ? p.invert(coord) : [0, 0];
177 },
Steven Burrows1c5c8612016-10-05 13:45:13 -0500178 resetPosition: function () {
179 t2nps.setLongLat(this);
180 },
Steven Burrows37549ee2016-09-21 14:41:39 +0100181 update: function () {
182 this.updateLabel();
183 },
184 updateLabel: function () {
185 var node = this.el,
186 label = this.trimLabel(this.label()),
187 labelWidth;
188
189 node.select('text').text(label);
190 labelWidth = label ? this.computeLabelWidth(node) : 0;
191
192 node.select('rect')
193 .transition()
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700194 .attr(this.labelBox(devIconDim, labelWidth));
Steven Burrows37549ee2016-09-21 14:41:39 +0100195 },
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700196 onEnter: function (el) {
197 this.el = d3.select(el);
198 this.render();
199 },
Steven Burrows0616e802016-10-06 21:45:07 -0500200 setScale: function () {
201
202 var dim = devIconDim,
203 multipler = 1;
204
205 if (dim * zoomService.scale() < devIconDimMin) {
206 multipler = devIconDimMin / (dim * zoomService.scale());
207 } else if (dim * zoomService.scale() > devIconDimMax) {
208 multipler = devIconDimMax / (dim * zoomService.scale());
209 }
210
Steven Burrows1c5c8612016-10-05 13:45:13 -0500211 this.el.selectAll('*')
212 .style('transform', 'scale(' + multipler + ')');
Steven Burrows0616e802016-10-06 21:45:07 -0500213 },
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700214 render: function () {
215 var node = this.el,
216 glyphId = this.icon(this.get('type')),
217 label = this.trimLabel(this.label()),
218 glyph, labelWidth;
219
220 // Label
221 var labelElements = this.addLabelElements(label);
222 labelWidth = label ? this.computeLabelWidth(node) : 0;
Steven Burrows1c5c8612016-10-05 13:45:13 -0500223 labelElements.rect
224 .attr(this.labelBox(devIconDim, labelWidth));
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700225
226 // Icon
227 glyph = is.addDeviceIcon(node, glyphId, devIconDim);
228 glyph.attr(this.iconBox(devIconDim, 0));
229 glyph.style('fill', 'white');
230
Steven Burrows583f4be2016-11-04 14:06:50 +0100231 node.attr('transform',
232 sus.translate(-halfDevIcon, -halfDevIcon));
Steven Burrowsbbe3dda2016-09-26 14:41:59 -0700233
234 if (this.events) {
235 this.setUpEvents();
236 }
Steven Burrows0616e802016-10-06 21:45:07 -0500237
238 this.setScale();
Steven Burrowsec1f45c2016-08-08 16:14:41 +0100239 }
240 });
241 }]
242 );
243})();