blob: c2e7a620470541cee1e6eb8d6376a25e48f54e7e [file] [log] [blame]
Simon Hunt99ee1e22015-02-13 09:24:43 -08001/*
2 * Copyright 2015 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/*
18 ONOS GUI -- Topology layer filtering Module.
19 Provides functionality to visually differentiate between the packet and
20 optical layers of the topology.
21 */
22
23(function () {
24 'use strict';
25
26 // injected refs
27 var $log, fs, flash, tps, tts;
28
29 // api to topoForce
30 var api;
31 /*
Simon Hunteb0fa052015-02-17 19:20:28 -080032 node() // get ref to D3 selection of nodes
33 link() // get ref to D3 selection of links
Simon Hunt99ee1e22015-02-13 09:24:43 -080034 */
35
Simon Hunteb0fa052015-02-17 19:20:28 -080036 // which "layer" a particular item "belongs to"
37 var layerLookup = {
38 host: {
39 endstation: 'pkt', // default, if host event does not define type
40 router: 'pkt',
41 bgpSpeaker: 'pkt'
42 },
43 device: {
44 switch: 'pkt',
45 roadm: 'opt'
46 },
47 link: {
48 hostLink: 'pkt',
49 direct: 'pkt',
50 indirect: '',
51 tunnel: '',
52 optical: 'opt'
53 }
54 };
Simon Hunt99ee1e22015-02-13 09:24:43 -080055
Simon Hunteb0fa052015-02-17 19:20:28 -080056 var idPrefix = 'topo-rb-';
57
58 var dispatch = {
59 all: function () { suppressLayers(false); },
60 pkt: function () { showLayer('pkt'); },
61 opt: function () { showLayer('opt'); }
62 },
63 filterButtons = [
64 { text: 'All Layers', id: 'all' },
65 { text: 'Packet Only', id: 'pkt' },
66 { text: 'Optical Only', id: 'opt' }
67 ],
68 btnG,
69 btnDef = {},
70 targetDiv;
71
72
73 function injectButtons(div) {
74 targetDiv = div;
75
76 btnG = div.append('div').attr('id', 'topo-radio-group');
77
78 filterButtons.forEach(function (btn, i) {
79 var bid = btn.id,
80 txt = btn.text,
81 uid = idPrefix + bid,
82 button = btnG.append('span')
83 .attr({
84 id: uid,
85 'class': 'radio'
86 })
87 .text(txt);
88 btnDef[uid] = btn;
89
90 if (i === 0) {
91 button.classed('active', true);
92 btnG.selected = bid;
93 }
94 });
95
96 btnG.selectAll('span')
97 .on('click', function () {
98 var button = d3.select(this),
99 uid = button.attr('id'),
100 btn = btnDef[uid],
101 act = button.classed('active');
102
103 if (!act) {
104 btnG.selectAll('span').classed('active', false);
105 button.classed('active', true);
106 btnG.selected = btn.id;
107 clickAction(btn.id);
108 }
109 });
110 }
111
112 function clickAction(which) {
113 dispatch[which]();
114 }
115
116 function selected() {
117 return btnG ? btnG.selected : '';
118 }
119
120 // code to manipulate the nodes and links as per the filter settings
121 function inLayer(d, layer) {
122 var type = d.class === 'link' ? d.type() : d.type,
123 look = layerLookup[d.class],
124 lyr = look && look[type];
125 return lyr === layer;
126 }
127
128 function unsuppressLayer(which) {
129 api.node().each(function (d) {
130 var node = d.el;
131 if (inLayer(d, which)) {
132 node.classed('suppressed', false);
133 }
134 });
135
136 api.link().each(function (d) {
137 var link = d.el;
138 if (inLayer(d, which)) {
139 link.classed('suppressed', false);
140 }
141 });
142 }
143
144 function suppressLayers(b) {
145 api.node().classed('suppressed', b);
146 api.link().classed('suppressed', b);
147// d3.selectAll('svg .port').classed('inactive', false);
148// d3.selectAll('svg .portText').classed('inactive', false);
149 }
150
151 function showLayer(which) {
152 suppressLayers(true);
153 unsuppressLayer(which);
154 }
Simon Hunt99ee1e22015-02-13 09:24:43 -0800155
156 // === -----------------------------------------------------
157 // === MODULE DEFINITION ===
158
159 angular.module('ovTopo')
160 .factory('TopoFilterService',
161 ['$log', 'FnService',
162 'FlashService',
163 'TopoPanelService',
164 'TopoTrafficService',
165
166 function (_$log_, _fs_, _flash_, _tps_, _tts_) {
167 $log = _$log_;
168 fs = _fs_;
169 flash = _flash_;
170 tps = _tps_;
171 tts = _tts_;
172
Simon Hunteb0fa052015-02-17 19:20:28 -0800173 function initFilter(_api_, div) {
Simon Hunt99ee1e22015-02-13 09:24:43 -0800174 api = _api_;
Simon Hunteb0fa052015-02-17 19:20:28 -0800175 injectButtons(div);
Simon Hunt99ee1e22015-02-13 09:24:43 -0800176 }
177
Simon Hunteb0fa052015-02-17 19:20:28 -0800178 function destroyFilter() {
179 targetDiv.select('#topo-radio-group').remove();
180 btnG = null;
181 btnDef = {};
182 }
Simon Hunt99ee1e22015-02-13 09:24:43 -0800183
184 return {
185 initFilter: initFilter,
Simon Hunteb0fa052015-02-17 19:20:28 -0800186 destroyFilter: destroyFilter,
187
188 clickAction: clickAction,
189 selected: selected
Simon Hunt99ee1e22015-02-13 09:24:43 -0800190 };
191 }]);
192}());