summaryrefslogtreecommitdiffstats
path: root/framework/src/onos/web/gui/src/main/webapp/app/view/topo
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/web/gui/src/main/webapp/app/view/topo')
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/README.txt3
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.css780
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.html7
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js557
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoD3.js641
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js190
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoEvent.js134
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoFilter.js149
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoForce.js1182
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoInst.js373
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoLink.js338
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoModel.js439
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoOblique.js257
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoOverlay.js412
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoPanel.js539
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoSelect.js314
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoSprite.js262
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js295
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoTraffic.js229
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoTrafficNew.js159
20 files changed, 0 insertions, 7260 deletions
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/README.txt b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/README.txt
deleted file mode 100644
index 61089bf6..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/README.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-# ONOS Topology View
-
-Code and resources for implementing the client-side for the Topology View.
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.css b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.css
deleted file mode 100644
index 0319b9b7..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.css
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * Copyright 2014,2015 Open Networking Laboratory
- *
- * 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 -- CSS file
- */
-
-/* --- Base SVG Layer --- */
-
-#ov-topo svg {
- /* prevents the little cut/copy/paste square that would appear on iPad */
- -webkit-user-select: none;
-}
-.light #ov-topo svg {
- background-color: #fff;
-}
-.dark #ov-topo svg {
- background-color: #2b2b2b;
-}
-
-
-/* --- "No Devices" Layer --- */
-
-#ov-topo svg #topo-noDevsLayer {
- visibility: hidden;
-}
-
-.light #ov-topo svg .noDevsBird {
- fill: #ecd;
-}
-.dark #ov-topo svg .noDevsBird {
- fill: #683434;
-}
-
-#ov-topo svg #topo-noDevsLayer text {
- font-size: 60pt;
- font-style: italic;
-}
-.light #ov-topo svg #topo-noDevsLayer text {
- fill: #dde;
-}
-.dark #ov-topo svg #topo-noDevsLayer text {
- fill: #3b3b4f;
-}
-
-
-/* --- Topo Map --- */
-
-#ov-topo svg #topo-map {
- stroke-width: 2px;
- fill: transparent;
-}
-
-.light #ov-topo svg #topo-map {
- stroke: #ddd;
-}
-.dark #ov-topo svg #topo-map {
- stroke: #444;
-}
-
-
-/* --- Topo Summary Panel --- */
-
-#topo-p-summary {
- /* Base css from panel.css */
-}
-
-/* --- Topo Detail Panel --- */
-
-#topo-p-detail {
- /* Base css from panel.css */
- top: 338px;
-}
-html[data-platform='iPad'] #topo-p-detail {
- top: 354px;
-}
-
-#topo-p-detail .actionBtns .actionBtn {
- display: inline-block;
-}
-#topo-p-detail .actionBtns .actionBtn svg {
- width: 30px;
- height: 30px;
-}
-
-/* --- Topo Dialog Panel --- */
-
-#topo-p-dialog .dialog-button {
- display: inline-block;
- cursor: pointer;
- height: 20px;
- padding: 2px 6px;
- margin: 4px;
- float: right;
-}
-
-.light #topo-p-dialog .dialog-button {
- background-color: #fec;
-}
-.dark #topo-p-dialog .dialog-button {
- background-color: #369;
-}
-
-/* --- general topo-panel styling --- */
-
-.topo-p div.header div.icon {
- vertical-align: middle;
- display: inline-block;
-}
-.topo-p div.body {
- overflow-y: scroll;
-}
-
-.topo-p div.body::-webkit-scrollbar {
- display: none;
-}
-
-.topo-p svg {
- display: inline-block;
- width: 42px;
- height: 42px;
-}
-
-.light .topo-p svg .glyph {
- fill: #222;
-}
-
-.dark .topo-p svg .glyph.overlay {
- fill: #222;
-}
-
-.dark .topo-p svg .glyph {
- fill: #ddd;
-}
-.light .topo-p svg .glyph.overlay {
- fill: #fff;
-}
-
-
-.topo-p h2 {
- padding: 0 4px;
- margin: 0;
- word-wrap: break-word;
- display: inline-block;
- width: 210px;
- vertical-align: middle;
-}
-.light .topo-p h2 {
- color: black;
-}
-.dark .topo-p h2 {
- color: #ddd;
-}
-
-.topo-p h3 {
- padding: 0 4px;
- margin: 0;
- word-wrap: break-word;
- top: 20px;
- left: 50px;
-}
-.light .topo-p h3 {
- color: black;
-}
-.dark .topo-p h3 {
- color: #ddd;
-}
-
-.topo-p p, table {
- padding: 4px;
- margin: 0;
-}
-
-.topo-p td {
- word-wrap: break-word;
-}
-.topo-p td.label {
- font-style: italic;
- padding-right: 12px;
- /* works for both light and dark themes ... */
- color: #777;
-}
-.topo-p td.value {
-}
-
-.topo-p hr {
- height: 1px;
- border: 0;
-}
-.light .topo-p hr {
- background-color: #ccc;
- color: #ccc;
-}
-.dark .topo-p hr {
- background-color: #888;
- color: #888;
-}
-
-/* --- Topo Instance Panel --- */
-
-#topo-p-instance {
- height: 100px;
-}
-
-#topo-p-instance div.onosInst {
- display: inline-block;
- width: 170px;
- height: 85px;
- cursor: pointer;
-}
-
-#topo-p-instance svg rect {
- stroke-width: 3.5;
-}
-#topo-p-instance .online svg rect {
- opacity: 1;
-}
-.light #topo-p-instance svg rect {
- fill: #ccc;
- stroke: #aaa;
-}
-.light #topo-p-instance .online svg rect {
- fill: #9cf;
- stroke: #555;
-}
-.dark #topo-p-instance svg rect {
- fill: #666;
- stroke: #222;
-}
-.dark #topo-p-instance .online svg rect {
- fill: #9cf;
- stroke: #999;
-}
-
-
-#topo-p-instance svg .glyph {
- fill: #888;
- fill-rule: evenodd;
-}
-#topo-p-instance .online svg .glyph {
- fill: #000;
-}
-
-#topo-p-instance svg .badgeIcon {
- fill-rule: evenodd;
- opacity: 0.4;
-}
-.light #topo-p-instance svg .badgeIcon {
- fill: #777;
-}
-.dark #topo-p-instance svg .badgeIcon {
- fill: #555;
-}
-
-#topo-p-instance .online svg .badgeIcon {
- opacity: 1.0;
-}
-.light #topo-p-instance .online svg .badgeIcon {
- fill: #fff;
-}
-.dark #topo-p-instance .online svg .badgeIcon {
- fill: #fff;
-}
-
-#topo-p-instance svg text {
- text-anchor: middle;
- opacity: 0.3;
-}
-#topo-p-instance .online svg text {
- opacity: 1.0;
-}
-.light #topo-p-instance svg text {
- fill: #444;
-}
-.light #topo-p-instance .online svg text {
- fill: #eee;
-}
-.dark #topo-p-instance svg text {
- fill: #aaa;
-}
-.dark #topo-p-instance .online svg text {
- fill: #ccc;
-}
-
-#topo-p-instance svg text.instTitle {
- font-size: 11pt;
- font-weight: bold;
-}
-#topo-p-instance svg text.instLabel {
- font-size: 9pt;
- font-style: italic;
-}
-
-#topo-p-instance .onosInst.mastership {
- opacity: 0.3;
-}
-#topo-p-instance .onosInst.mastership.affinity {
- opacity: 1.0;
-}
-.light #topo-p-instance .onosInst.mastership.affinity svg rect {
- filter: url(#blue-glow);
-}
-.dark #topo-p-instance .onosInst.mastership.affinity svg rect {
- filter: url(#yellow-glow);
-}
-.light.firefox #topo-p-instance .onosInst.mastership.affinity svg rect {
- filter: url("data:image/svg+xml;utf8, <svg xmlns = \'http://www.w3.org/2000/svg\'><filter x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\" id=\"blue-glow\"><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0 0 0 1 0 \"></feColorMatrix><feGaussianBlur stdDeviation=\"3\" result=\"coloredBlur\"></feGaussianBlur><feMerge><feMergeNode in=\"coloredBlur\"></feMergeNode><feMergeNode in=\"SourceGraphic\"></feMergeNode></feMerge></filter></svg>#blue-glow");
-}
-.dark.firefox #topo-p-instance .onosInst.mastership.affinity svg rect {
- filter: url("data:image/svg+xml;utf8, <svg xmlns = \'http://www.w3.org/2000/svg\'><filter x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\" id=\"yellow-glow\"><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1.0 0 0 0 0 1.0 0 0 0 0 0.3 0 0 0 1 0 \"></feColorMatrix><feGaussianBlur stdDeviation=\"3\" result=\"coloredBlur\"></feGaussianBlur><feMerge><feMergeNode in=\"coloredBlur\"></feMergeNode><feMergeNode in=\"SourceGraphic\"></feMergeNode></feMerge></filter></svg>#yellow-glow");
-}
-
-
-/* --- Toolbar --- */
-
-#toolbar-topo-tbar .tbar-row.right {
- width: 100%;
-}
-
-#toolbar-topo-tbar .tbar-row-text {
- height: 21px;
- text-align: right;
- padding: 8px 60px 0 0;
- font-style: italic;
-}
-
-
-/* --- Topo Nodes --- */
-
-#ov-topo svg .suppressed {
- opacity: 0.5 !important;
-}
-
-#ov-topo svg .suppressedmax {
- opacity: 0.2 !important;
-}
-
-#ov-topo svg .node {
- cursor: pointer;
-}
-
-.light #ov-topo svg .node.selected rect,
-.light #ov-topo svg .node.selected circle {
- fill: #f90;
- filter: url(#blue-glow);
-}
-.dark #ov-topo svg .node.selected rect,
-.dark #ov-topo svg .node.selected circle {
- fill: #f90;
- filter: url(#yellow-glow);
-}
-.light.firefox #ov-topo svg .node.selected rect,
-.light.firefox #ov-topo svg .node.selected circle {
- filter: url("data:image/svg+xml;utf8, <svg xmlns = \'http://www.w3.org/2000/svg\'><filter x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\" id=\"blue-glow\"><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0 0 0 1 0 \"></feColorMatrix><feGaussianBlur stdDeviation=\"3\" result=\"coloredBlur\"></feGaussianBlur><feMerge><feMergeNode in=\"coloredBlur\"></feMergeNode><feMergeNode in=\"SourceGraphic\"></feMergeNode></feMerge></filter></svg>#blue-glow");
-}
-.dark.firefox #ov-topo svg .node.selected rect,
-.dark.firefox #ov-topo svg .node.selected circle {
- filter: url("data:image/svg+xml;utf8, <svg xmlns = \'http://www.w3.org/2000/svg\'><filter x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\" id=\"yellow-glow\"><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1.0 0 0 0 0 1.0 0 0 0 0 0.3 0 0 0 1 0 \"></feColorMatrix><feGaussianBlur stdDeviation=\"3\" result=\"coloredBlur\"></feGaussianBlur><feMerge><feMergeNode in=\"coloredBlur\"></feMergeNode><feMergeNode in=\"SourceGraphic\"></feMergeNode></feMerge></filter></svg>#yellow-glow");
-}
-
-#ov-topo svg .node text {
- pointer-events: none;
-}
-
-/* Device Nodes */
-
-#ov-topo svg .node.device {
-}
-
-#ov-topo svg .node.device rect {
- stroke-width: 1.5;
-}
-
-#ov-topo svg .node.device.fixed rect {
- stroke-width: 1.5;
-}
-.light #ov-topo svg .node.device.fixed rect {
- stroke: #aaa;
-}
-.dark #ov-topo svg .node.device.fixed rect {
- stroke: #999;
-}
-
-/* note: device is offline without the 'online' class */
-.light #ov-topo svg .node.device {
- fill: #777;
-}
-.dark #ov-topo svg .node.device {
- fill: #555;
-}
-
-.light #ov-topo svg .node.device rect {
- stroke: #666;
-}
-.light #ov-topo svg .node.device rect {
- stroke: #999;
-}
-
-.light #ov-topo svg .node.device.online {
- fill: #6e7fa3;
-}
-.dark #ov-topo svg .node.device.online {
- fill: #4E5C7F;
-}
-
-/* note: device is offline without the 'online' class */
-#ov-topo svg .node.device text {
- fill: #bbb;
- font: 10pt sans-serif;
-}
-
-#ov-topo svg .node.device.online text {
- fill: white;
-}
-
-#ov-topo svg .node.device .svgIcon rect {
- fill: #aaa;
-}
-#ov-topo svg .node.device .svgIcon use {
- fill: #777;
-}
-#ov-topo svg .node.device.selected .svgIcon rect {
- fill: #f90;
-}
-#ov-topo svg .node.device.online .svgIcon rect {
- fill: #ccc;
-}
-#ov-topo svg .node.device.online .svgIcon use {
- fill: #000;
-}
-#ov-topo svg .node.device.online.selected .svgIcon rect {
- fill: #f90;
-}
-
-/* Badges */
-/* (... works for both light and dark themes...) */
-#ov-topo svg .node .badge circle {
- stroke: #aaa;
-}
-
-#ov-topo svg .node .badge.badgeInfo circle {
- fill: #99d;
-}
-
-#ov-topo svg .node .badge.badgeWarn circle {
- fill: #da2;
-}
-
-#ov-topo svg .node .badge.badgeError circle {
- fill: #e44;
-}
-
-#ov-topo svg .node .badge use {
- fill: white !important;
-}
-
-#ov-topo svg .node .badge.badgeInfo use {
- fill: #448;
-}
-
-#ov-topo svg .node .badge text {
- fill: white !important;
-}
-
-#ov-topo svg .node .badge.badgeInfo text {
- fill: #448;
-}
-
-/* Host Nodes */
-
-#ov-topo svg .node.host {
-}
-
-#ov-topo svg .node.host text {
- stroke: none;
- font: 9pt sans-serif;
-}
-.light #ov-topo svg .node.host text {
- fill: #846;
-}
-.dark #ov-topo svg .node.host text {
- fill: #BB809D;
-}
-
-.light svg .node.host circle {
- stroke: #000;
- fill: #edb;
-}
-.dark svg .node.host circle {
- stroke: #eee;
- fill: #B2A180;
-}
-
-.light svg .node.host .svgIcon {
- fill: #444;
-}
-.dark svg .node.host .svgIcon {
- fill: #222;
-}
-
-/* --- Topo Links --- */
-
-#ov-topo svg .link {
- opacity: .9;
-}
-
-#ov-topo svg .link.selected,
-#ov-topo svg .link.enhanced {
- stroke-width: 4.5px;
-}
-.light #ov-topo svg .link.selected,
-.light #ov-topo svg .link.enhanced {
- filter: url(#blue-glow);
-}
-.dark #ov-topo svg .link.selected,
-.dark #ov-topo svg .link.enhanced {
- filter: url(#yellow-glow);
-}
-.light.firefox #ov-topo svg .link.selected,
-.light.firefox #ov-topo svg .link.enhanced {
- filter: url("data:image/svg+xml;utf8, <svg xmlns = \'http://www.w3.org/2000/svg\'><filter x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\" id=\"blue-glow\"><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.7 0 0 0 1 0 \"></feColorMatrix><feGaussianBlur stdDeviation=\"3\" result=\"coloredBlur\"></feGaussianBlur><feMerge><feMergeNode in=\"coloredBlur\"></feMergeNode><feMergeNode in=\"SourceGraphic\"></feMergeNode></feMerge></filter></svg>#blue-glow");
-}
-.dark.firefox #ov-topo svg .link.selected,
-.dark.firefox #ov-topo svg .link.enhanced {
- filter: url("data:image/svg+xml;utf8, <svg xmlns = \'http://www.w3.org/2000/svg\'><filter x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\" id=\"yellow-glow\"><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1.0 0 0 0 0 1.0 0 0 0 0 0.3 0 0 0 1 0 \"></feColorMatrix><feGaussianBlur stdDeviation=\"3\" result=\"coloredBlur\"></feGaussianBlur><feMerge><feMergeNode in=\"coloredBlur\"></feMergeNode><feMergeNode in=\"SourceGraphic\"></feMergeNode></feMerge></filter></svg>#yellow-glow");
-
-}
-
-#ov-topo svg .link.inactive {
- opacity: .5;
- stroke-dasharray: 8 4;
-}
-
-#ov-topo svg .link.secondary {
- stroke-width: 3px;
-}
-.light #ov-topo svg .link.secondary {
- stroke: rgba(0,153,51,0.5);
-}
-.dark #ov-topo svg .link.secondary {
- stroke: rgba(121,231,158,0.5);
-}
-
-/* Port traffic color visualization for Kbps, Mbps, and Gbps */
-
-.light #ov-topo svg .link.secondary.port-traffic-Kbps {
- stroke: rgb(0,153,51);
- stroke-width: 5.0;
-}
-.dark #ov-topo svg .link.secondary.port-traffic-Kbps {
- stroke: rgb(98, 153, 118);
- stroke-width: 5.0;
-}
-
-.light #ov-topo svg .link.secondary.port-traffic-Mbps {
- stroke: rgb(128,145,27);
- stroke-width: 6.5;
-}
-.dark #ov-topo svg .link.secondary.port-traffic-Mbps {
- stroke: rgb(91, 109, 54);
- stroke-width: 6.5;
-}
-
-.light #ov-topo svg .link.secondary.port-traffic-Gbps {
- stroke: rgb(255, 137, 3);
- stroke-width: 8.0;
-}
-.dark #ov-topo svg .link.secondary.port-traffic-Gbps {
- stroke: rgb(174, 119, 55);
- stroke-width: 8.0;
-}
-
-.light #ov-topo svg .link.secondary.port-traffic-Gbps-choked {
- stroke: rgb(183, 30, 21);
- stroke-width: 8.0;
-}
-.dark #ov-topo svg .link.secondary.port-traffic-Gbps-choked {
- stroke: rgb(127, 40, 39);
- stroke-width: 8.0;
-}
-
-
-#ov-topo svg .link.animated {
- stroke-dasharray: 8 5;
- animation: ants 5s infinite linear;
- /* below line will be added via Javascript based on path */
- /*animation-direction: reverse;*/
-}
-@keyframes ants {
- from {
- stroke-dashoffset: 0;
- }
- to {
- stroke-dashoffset: 400;
- }
-}
-
-#ov-topo svg .link.primary {
- stroke-width: 4px;
-}
-.light #ov-topo svg .link.primary {
- stroke: #ffA300;
-}
-.dark #ov-topo svg .link.primary {
- stroke: #D58E0F;
-}
-
-#ov-topo svg .link.secondary.optical {
- stroke-width: 4px;
-}
-.light #ov-topo svg .link.secondary.optical {
- stroke: rgba(128,64,255,0.5);
-}
-.dark #ov-topo svg .link.secondary.optical {
- stroke: rgba(164,139,215,0.5);
-}
-
-#ov-topo svg .link.primary.optical {
- stroke-width: 6px;
-}
-.light #ov-topo svg .link.primary.optical {
- stroke: #74f;
-}
-.dark #ov-topo svg .link.primary.optical {
- stroke: #7352CD;
-}
-
-/* Link Labels */
-
-#ov-topo svg .linkLabel rect {
- stroke: none;
-}
-.light #ov-topo svg .linkLabel rect {
- fill: #eee;
-}
-.dark #ov-topo svg .linkLabel rect {
- fill: #555;
-}
-
-#ov-topo svg .linkLabel text {
- text-anchor: middle;
- stroke-width: 0.1;
- font-size: 9pt;
-}
-.light #ov-topo svg .linkLabel text {
- fill: #444;
-}
-.dark #ov-topo svg .linkLabel text {
- fill: #eee;
-}
-
-/* Port Labels */
-
-#ov-topo svg .portLabel rect {
- stroke: none;
-}
-.light #ov-topo svg .portLabel rect {
- fill: #eee;
-}
-.dark #ov-topo svg .portLabel rect {
- fill: #222;
-}
-
-#ov-topo svg .portLabel text {
- text-anchor: middle;
- stroke-width: 0.1;
- font-size: 11pt;
-}
-.light #ov-topo svg .portLabel text {
- fill: #444;
-}
-.dark #ov-topo svg .portLabel text {
- fill: #eee;
-}
-
-/* Number of Links Labels */
-#ov-topo line.numLinkHash {
- stroke-width: 3;
-}
-
-#ov-topo text.numLinkText {
- font-size: 15pt;
-}
-
-#ov-topo text.numLinkText {
- text-anchor: middle;
-}
-
-.light #ov-topo text.numLinkText {
- fill: #444;
-}
-.dark #ov-topo text.numLinkText {
- fill: #eee;
-}
-
-/* ------------------------------------------------- */
-/* Sprite Layer */
-
-#ov-topo svg #topo-sprites use {
- stroke-width: 2;
-}
-#ov-topo svg #topo-sprites text {
- text-anchor: middle;
- font-size: 20pt;
- font-style: italic;
-}
-
-.light #ov-topo svg #topo-sprites .gold1 use {
- stroke: #fda;
- fill: none;
-}
-.dark #ov-topo svg #topo-sprites .gold1 use {
- stroke: #541;
- fill: none;
-}
-.light #ov-topo svg #topo-sprites .gold1 text {
- fill: #eda;
-}
-.dark #ov-topo svg #topo-sprites .gold1 text {
- fill: #543;
-}
-
-.light #ov-topo svg #topo-sprites .blue1 use {
- stroke: #bbd;
- fill: none;
-}
-.dark #ov-topo svg #topo-sprites .blue1 use {
- stroke: #445;
- fill: none;
-}
-.light #ov-topo svg #topo-sprites .blue1 text {
- fill: #cce;
-}
-.dark #ov-topo svg #topo-sprites .blue1 text {
- fill: #446;
-}
-
-.light #ov-topo svg #topo-sprites .gray1 use {
- stroke: #ccc;
- fill: none;
-}
-.dark #ov-topo svg #topo-sprites .gray1 use {
- stroke: #333;
- fill: none;
-}
-.light #ov-topo svg #topo-sprites .gray1 text {
- fill: #ddd;
-}
-.dark #ov-topo svg #topo-sprites .gray1 text {
- fill: #444;
-}
-
-/* fills */
-.light #ov-topo svg #topo-sprites use.fill-gray2 {
- fill: #eee;
-}
-.dark #ov-topo svg #topo-sprites use.fill-gray2 {
- fill: #444;
-}
-
-.light #ov-topo svg #topo-sprites use.fill-blue2 {
- fill: #bce;
-}
-.dark #ov-topo svg #topo-sprites use.fill-blue2 {
- fill: #447;
-}
-
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.html b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.html
deleted file mode 100644
index 8a64abb5..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!-- Topology View partial HTML -->
-<div id="ov-topo">
- <svg viewBox="0 0 1000 1000"
- resize offset-height="56" offset-width="12"
- notifier="notifyResize()">
- </svg>
-</div>
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js
deleted file mode 100644
index 3564eb33..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topo.js
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Copyright 2014,2015 Open Networking Laboratory
- *
- * 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 Module
- */
-
-(function () {
- 'use strict';
-
- var moduleDependencies = [
- 'ngCookies',
- 'onosUtil',
- 'onosSvg',
- 'onosRemote'
- ];
-
- // references to injected services etc.
- var $scope, $log, $cookies, fs, ks, zs, gs, ms, sus, flash, wss, ps,
- tds, tes, tfs, tps, tis, tss, tls, tts, tos, fltr, ttbs, ttip, tov;
-
- // DOM elements
- var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer;
-
- // Internal state
- var zoomer, actionMap;
-
- // --- Short Cut Keys ------------------------------------------------
-
- function setUpKeys(overlayKeys) {
- // key bindings need to be made after the services have been injected
- // thus, deferred to here...
- actionMap = {
- I: [toggleInstances, 'Toggle ONOS instances panel'],
- O: [toggleSummary, 'Toggle ONOS summary panel'],
- D: [toggleUseDetailsFlag, 'Disable / enable details panel'],
-
- H: [toggleHosts, 'Toggle host visibility'],
- M: [toggleOffline, 'Toggle offline visibility'],
- P: [togglePorts, 'Toggle Port Highlighting'],
- dash: [tfs.showBadLinks, 'Show bad links'],
- B: [toggleMap, 'Toggle background map'],
- S: [toggleSprites, 'Toggle sprite layer'],
-
- //X: [toggleNodeLock, 'Lock / unlock node positions'],
- Z: [tos.toggleOblique, 'Toggle oblique view (Experimental)'],
- N: [fltr.clickAction, 'Cycle node layers'],
- L: [tfs.cycleDeviceLabels, 'Cycle device labels'],
- U: [tfs.unpin, 'Unpin node (hover mouse over)'],
- R: [resetZoom, 'Reset pan / zoom'],
- dot: [ttbs.toggleToolbar, 'Toggle Toolbar'],
-
- E: [equalizeMasters, 'Equalize mastership roles'],
-
- esc: handleEscape,
-
- _keyListener: ttbs.keyListener,
-
- _helpFormat: [
- ['I', 'O', 'D', 'H', 'M', 'P', 'dash', 'B', 'S' ],
- ['X', 'Z', 'N', 'L', 'U', 'R', '-', 'E', '-', 'dot'],
- [] // this column reserved for overlay actions
- ]
- };
-
- if (fs.isO(overlayKeys)) {
- mergeKeys(overlayKeys);
- }
-
- ks.keyBindings(actionMap);
-
- ks.gestureNotes([
- ['click', 'Select the item and show details'],
- ['shift-click', 'Toggle selection state'],
- ['drag', 'Reposition (and pin) device / host'],
- ['cmd-scroll', 'Zoom in / out'],
- ['cmd-drag', 'Pan']
- ]);
- }
-
- // when a topology overlay is activated, we need to bind their keystrokes
- // and include them in the quick-help panel
- function mergeKeys(extra) {
- var _hf = actionMap._helpFormat[2];
-
- ks.checkNotGlobal(extra);
-
- extra._keyOrder.forEach(function (k) {
- var d = extra[k],
- cb = d && d.cb,
- tt = d && d.tt;
- // NOTE: ignore keys that are already defined
- if (d && !actionMap[k]) {
- actionMap[k] = [cb, tt];
- _hf.push(k);
- }
- });
- }
-
- // --- Keystroke functions -------------------------------------------
-
- function toggleInstances(x) {
- updatePrefsState('insts', tis.toggle(x));
- tfs.updateDeviceColors();
- }
-
- function toggleSummary(x) {
- updatePrefsState('summary', tps.toggleSummary(x));
- }
-
- function toggleUseDetailsFlag(x) {
- updatePrefsState('detail', tps.toggleUseDetailsFlag(x));
- }
-
- function toggleHosts(x) {
- updatePrefsState('hosts', tfs.toggleHosts(x));
- }
-
- function toggleOffline(x) {
- updatePrefsState('offdev', tfs.toggleOffline(x));
- }
-
- function togglePorts(x) {
- updatePrefsState('porthl', tfs.togglePorts(x));
- }
-
- function _togSvgLayer(x, G, tag, what) {
- var on = (x === 'keyev') ? !sus.visible(G) : !!x,
- verb = on ? 'Show' : 'Hide';
- sus.visible(G, on);
- updatePrefsState(tag, on);
- flash.flash(verb + ' ' + what);
- }
-
- function toggleMap(x) {
- _togSvgLayer(x, mapG, 'bg', 'background map');
- }
-
- function toggleSprites(x) {
- _togSvgLayer(x, spriteG, 'spr', 'sprite layer');
- }
-
- function resetZoom() {
- zoomer.reset();
- flash.flash('Pan and zoom reset');
- }
-
- function equalizeMasters() {
- wss.sendEvent('equalizeMasters');
- flash.flash('Equalizing master roles');
- }
-
- function handleEscape() {
- if (tis.showMaster()) {
- // if an instance is selected, cancel the affinity mapping
- tis.cancelAffinity()
-
- } else if (tov.hooks.escape()) {
- // else if the overlay consumed the ESC event...
- // (work already done)
-
- } else if (tss.deselectAll()) {
- // else if we have node selections, deselect them all
- // (work already done)
-
- } else if (tls.deselectLink()) {
- // else if we have a link selected, deselect it
- // (work already done)
-
- } else if (tis.isVisible()) {
- // else if the Instance Panel is visible, hide it
- tis.hide();
- tfs.updateDeviceColors();
-
- } else if (tps.summaryVisible()) {
- // else if the Summary Panel is visible, hide it
- tps.hideSummaryPanel();
- }
- }
-
- // --- Toolbar Functions ---------------------------------------------
-
- function notValid(what) {
- $log.warn('topo.js getActionEntry(): Not a valid ' + what);
- }
-
- function getActionEntry(key) {
- var entry;
-
- if (!key) {
- notValid('key');
- return null;
- }
-
- entry = actionMap[key];
-
- if (!entry) {
- notValid('actionMap entry');
- return null;
- }
- return fs.isA(entry) || [entry, ''];
- }
-
- function setUpToolbar() {
- ttbs.init({
- getActionEntry: getActionEntry,
- setUpKeys: setUpKeys
- });
- ttbs.createToolbar();
- }
-
- // --- Glyphs, Icons, and the like -----------------------------------
-
- function setUpDefs() {
- defs = svg.append('defs');
- gs.loadDefs(defs);
- sus.loadGlowDefs(defs);
- }
-
-
- // --- Pan and Zoom --------------------------------------------------
-
- // zoom enabled predicate. ev is a D3 source event.
- function zoomEnabled(ev) {
- return fs.isMobile() || (ev.metaKey || ev.altKey);
- }
-
- function zoomCallback() {
- var sc = zoomer.scale(),
- tr = zoomer.translate();
-
- ps.setPrefs('topo_zoom', {tx:tr[0], ty:tr[1], sc:sc});
-
- // keep the map lines constant width while zooming
- mapG.style('stroke-width', (2.0 / sc) + 'px');
- }
-
- function setUpZoom() {
- zoomLayer = svg.append('g').attr('id', 'topo-zoomlayer');
- zoomer = zs.createZoomer({
- svg: svg,
- zoomLayer: zoomLayer,
- zoomEnabled: zoomEnabled,
- zoomCallback: zoomCallback
- });
- }
-
-
- // callback invoked when the SVG view has been resized..
- function svgResized(s) {
- tfs.newDim([s.width, s.height]);
- }
-
- // --- Background Map ------------------------------------------------
-
- function setUpNoDevs() {
- var g, box;
- noDevsLayer = svg.append('g').attr({
- id: 'topo-noDevsLayer',
- transform: sus.translate(500,500)
- });
- // Note, SVG viewbox is '0 0 1000 1000', defined in topo.html.
- // We are translating this layer to have its origin at the center
-
- g = noDevsLayer.append('g');
- gs.addGlyph(g, 'bird', 100).attr('class', 'noDevsBird');
- g.append('text').text('No devices are connected')
- .attr({ x: 120, y: 80});
-
- box = g.node().getBBox();
- box.x -= box.width/2;
- box.y -= box.height/2;
- g.attr('transform', sus.translate(box.x, box.y));
-
- showNoDevs(true);
- }
-
- function showNoDevs(b) {
- sus.visible(noDevsLayer, b);
- }
-
-
- var countryFilters = {
- world: function (c) {
- return c.properties.continent !== 'Antarctica';
- },
-
- // NOTE: for "usa" we are using our hand-crafted topojson file
-
- s_america: function (c) {
- return c.properties.continent === 'South America';
- },
-
- ns_america: function (c) {
- return c.properties.custom === 'US-cont' ||
- c.properties.subregion === 'Central America' ||
- c.properties.continent === 'South America';
- },
-
- japan: function (c) {
- return c.properties.geounit === 'Japan';
- },
-
- europe: function (c) {
- return c.properties.continent === 'Europe';
- },
-
- italy: function (c) {
- return c.properties.geounit === 'Italy';
- },
-
- uk: function (c) {
- // technically, Ireland is not part of the United Kingdom,
- // but the map looks weird without it showing.
- return c.properties.adm0_a3 === 'GBR' ||
- c.properties.adm0_a3 === 'IRL';
- },
-
- s_korea: function (c) {
- return c.properties.adm0_a3 === 'KOR';
- },
-
- australia: function (c) {
- return c.properties.adm0_a3 === 'AUS';
- }
- };
-
-
- function setUpMap($loc) {
- var s1 = $loc.search().mapid,
- s2 = ps.getPrefs('topo_mapid'),
- mapId = s1 || (s2 && s2.id) || 'usa',
- promise,
- cfilter,
- opts;
-
- mapG = zoomLayer.append('g').attr('id', 'topo-map');
- if (mapId === 'usa') {
- promise = ms.loadMapInto(mapG, '*continental_us');
- } else {
- ps.setPrefs('topo_mapid', {id:mapId});
- cfilter = countryFilters[mapId] || countryFilters.world;
- opts = { countryFilter: cfilter };
- promise = ms.loadMapRegionInto(mapG, opts);
- }
- return promise;
- }
-
- function opacifyMap(b) {
- mapG.transition()
- .duration(1000)
- .attr('opacity', b ? 1 : 0);
- }
-
- function setUpSprites($loc, tspr) {
- var s1 = $loc.search().sprites,
- s2 = ps.getPrefs('topo_sprites'),
- sprId = s1 || (s2 && s2.id);
-
- spriteG = zoomLayer.append ('g').attr('id', 'topo-sprites');
- if (sprId) {
- ps.setPrefs('topo_sprites', {id:sprId});
- tspr.loadSprites(spriteG, defs, sprId);
- }
- }
-
- // --- User Preferemces ----------------------------------------------
-
- var prefsState = {};
-
- function updatePrefsState(what, b) {
- prefsState[what] = b ? 1 : 0;
- ps.setPrefs('topo_prefs', prefsState);
- }
-
-
- function restoreConfigFromPrefs() {
- // NOTE: toolbar will have set this for us..
- prefsState = ps.asNumbers(ps.getPrefs('topo_prefs'));
-
- $log.debug('TOPO- Prefs State:', prefsState);
-
- flash.enable(false);
- toggleInstances(prefsState.insts);
- toggleSummary(prefsState.summary);
- toggleUseDetailsFlag(prefsState.detail);
- toggleHosts(prefsState.hosts);
- toggleOffline(prefsState.offdev);
- togglePorts(prefsState.porthl);
- toggleMap(prefsState.bg);
- toggleSprites(prefsState.spr);
- flash.enable(true);
- }
-
-
- // somewhat hackish, because summary update cannot happen until we
- // have opened the websocket to the server; hence this extra function
- // invoked after tes.start()
- function restoreSummaryFromPrefs() {
- prefsState = ps.asNumbers(ps.getPrefs('topo_prefs'));
- $log.debug('TOPO- Prefs SUMMARY State:', prefsState.summary);
-
- flash.enable(false);
- toggleSummary(prefsState.summary);
- flash.enable(true);
- }
-
- function topoStartDone() {
- var d = $scope.intentData;
- if (d) {
- tts.selectIntent(d);
- }
- }
-
- // --- Controller Definition -----------------------------------------
-
- angular.module('ovTopo', moduleDependencies)
- .controller('OvTopoCtrl', ['$scope', '$log', '$location', '$timeout',
- '$cookies', 'FnService', 'MastService', 'KeyService', 'ZoomService',
- 'GlyphService', 'MapService', 'SvgUtilService', 'FlashService',
- 'WebSocketService', 'PrefsService', 'TopoDialogService',
- 'TopoEventService', 'TopoForceService', 'TopoPanelService',
- 'TopoInstService', 'TopoSelectService', 'TopoLinkService',
- 'TopoTrafficService', 'TopoObliqueService', 'TopoFilterService',
- 'TopoToolbarService', 'TopoSpriteService', 'TooltipService',
- 'TopoOverlayService',
-
- function (_$scope_, _$log_, $loc, $timeout, _$cookies_, _fs_, mast, _ks_,
- _zs_, _gs_, _ms_, _sus_, _flash_, _wss_, _ps_, _tds_, _tes_,
- _tfs_, _tps_, _tis_, _tss_, _tls_, _tts_, _tos_, _fltr_,
- _ttbs_, tspr, _ttip_, _tov_) {
- var params = $loc.search(),
- projection,
- dim,
- uplink = {
- // provides function calls back into this space
- showNoDevs: showNoDevs,
- projection: function () { return projection; },
- zoomLayer: function () { return zoomLayer; },
- zoomer: function () { return zoomer; },
- opacifyMap: opacifyMap,
- topoStartDone: topoStartDone
- };
-
- $scope = _$scope_;
- $log = _$log_;
- $cookies = _$cookies_;
- fs = _fs_;
- ks = _ks_;
- zs = _zs_;
- gs = _gs_;
- ms = _ms_;
- sus = _sus_;
- flash = _flash_;
- wss = _wss_;
- ps = _ps_;
- tds = _tds_;
- tes = _tes_;
- tfs = _tfs_;
- // TODO: consider funnelling actions through TopoForceService...
- // rather than injecting references to these 'sub-modules',
- // just so we can invoke functions on them.
- tps = _tps_;
- tis = _tis_;
- tss = _tss_;
- tls = _tls_;
- tts = _tts_;
- tos = _tos_;
- fltr = _fltr_;
- ttbs = _ttbs_;
- ttip = _ttip_;
- tov = _tov_;
-
- if (params.intentKey && params.intentAppId && params.intentAppName) {
- $scope.intentData = {
- key: params.intentKey,
- appId: params.intentAppId,
- appName: params.intentAppName
- };
- }
-
- $scope.notifyResize = function () {
- svgResized(fs.windowSize(mast.mastHeight()));
- };
-
- // Cleanup on destroyed scope..
- $scope.$on('$destroy', function () {
- $log.log('OvTopoCtrl is saying Buh-Bye!');
- tes.stop();
- ks.unbindKeys();
- tps.destroyPanels();
- tds.closeDialog();
- tis.destroyInst();
- tfs.destroyForce();
- ttbs.destroyToolbar();
- });
-
- // svg layer and initialization of components
- ovtopo = d3.select('#ov-topo');
- svg = ovtopo.select('svg');
- // set the svg size to match that of the window, less the masthead
- svg.attr(fs.windowSize(mast.mastHeight()));
- dim = [svg.attr('width'), svg.attr('height')];
-
- setUpKeys();
- setUpToolbar();
- setUpDefs();
- setUpZoom();
- setUpNoDevs();
- setUpMap($loc).then(
- function (proj) {
- var z = ps.getPrefs('topo_zoom') || {tx:0, ty:0, sc:1};
- zoomer.panZoom([z.tx, z.ty], z.sc);
- $log.debug('** Zoom restored:', z);
-
- projection = proj;
- $log.debug('** We installed the projection:', proj);
- flash.enable(false);
- toggleMap(prefsState.bg);
- flash.enable(true);
-
- // now we have the map projection, we are ready for
- // the server to send us device/host data...
- tes.start();
- // need to do the following so we immediately get
- // the summary panel data back from the server
- restoreSummaryFromPrefs();
- }
- );
- setUpSprites($loc, tspr);
-
- forceG = zoomLayer.append('g').attr('id', 'topo-force');
- tfs.initForce(svg, forceG, uplink, dim);
- tis.initInst({ showMastership: tfs.showMastership });
- tps.initPanels();
-
- // temporary solution for persisting user settings
- restoreConfigFromPrefs();
- ttbs.setDefaultOverlay();
-
- $log.debug('registered overlays...', tov.list());
- $log.log('OvTopoCtrl has been created');
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoD3.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoD3.js
deleted file mode 100644
index 5bf2eb4f..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoD3.js
+++ /dev/null
@@ -1,641 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 D3 Module.
- Functions for manipulating the D3 visualizations of the Topology
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, fs, sus, is, ts;
-
- // api to topoForce
- var api;
- /*
- node() // get ref to D3 selection of nodes
- link() // get ref to D3 selection of links
- linkLabel() // get ref to D3 selection of link labels
- instVisible() // true if instances panel is visible
- posNode() // position node
- showHosts() // true if hosts are to be shown
- restyleLinkElement() // update link styles based on backing data
- updateLinkLabelModel() // update backing data for link labels
- */
-
- // configuration
- var devCfg = {
- xoff: -20,
- yoff: -18
- },
- labelConfig = {
- imgPad: 16,
- padLR: 4,
- padTB: 3,
- marginLR: 3,
- marginTB: 2,
- port: {
- gap: 3,
- width: 18,
- height: 14
- }
- },
- badgeConfig = {
- radius: 12,
- yoff: 5,
- gdelta: 10
- },
- icfg;
-
- var status = {
- i: 'badgeInfo',
- w: 'badgeWarn',
- e: 'badgeError'
- };
-
- function badgeStatus(badge) {
- return status[badge.status] || status.i;
- }
-
- // internal state
- var deviceLabelIndex = 0,
- hostLabelIndex = 0;
-
-
- var dCol = {
- black: '#000',
- paleblue: '#acf',
- offwhite: '#ddd',
- darkgrey: '#444',
- midgrey: '#888',
- lightgrey: '#bbb',
- orange: '#f90'
- };
-
- // note: these are the device icon colors without affinity
- var dColTheme = {
- light: {
- rfill: dCol.offwhite,
- online: {
- glyph: dCol.darkgrey,
- rect: dCol.paleblue
- },
- offline: {
- glyph: dCol.midgrey,
- rect: dCol.lightgrey
- }
- },
- dark: {
- rfill: dCol.midgrey,
- online: {
- glyph: dCol.darkgrey,
- rect: dCol.paleblue
- },
- offline: {
- glyph: dCol.midgrey,
- rect: dCol.darkgrey
- }
- }
- };
-
- function devBaseColor(d) {
- var o = d.online ? 'online' : 'offline';
- return dColTheme[ts.theme()][o];
- }
-
- function setDeviceColor(d) {
- var o = d.online,
- s = d.el.classed('selected'),
- c = devBaseColor(d),
- a = instColor(d.master, o),
- icon = d.el.select('g.deviceIcon'),
- g, r;
-
- if (s) {
- g = c.glyph;
- r = dCol.orange;
- } else if (api.instVisible()) {
- g = o ? a : c.glyph;
- r = o ? c.rfill : a;
- } else {
- g = c.glyph;
- r = c.rect;
- }
-
- icon.select('use').style('fill', g);
- icon.select('rect').style('fill', r);
- }
-
- function instColor(id, online) {
- return sus.cat7().getColor(id, !online, ts.theme());
- }
-
- // ====
-
- function incDevLabIndex() {
- deviceLabelIndex = (deviceLabelIndex+1) % 3;
- switch(deviceLabelIndex) {
- case 0: return 'Hide device labels';
- case 1: return 'Show friendly device labels';
- case 2: return 'Show device ID labels';
- }
- }
-
- // Returns the newly computed bounding box of the rectangle
- function adjustRectToFitText(n) {
- var text = n.select('text'),
- box = text.node().getBBox(),
- lab = labelConfig;
-
- text.attr('text-anchor', 'middle')
- .attr('y', '-0.8em')
- .attr('x', lab.imgPad/2);
-
- // translate the bbox so that it is centered on [x,y]
- box.x = -box.width / 2;
- box.y = -box.height / 2;
-
- // add padding
- box.x -= (lab.padLR + lab.imgPad/2);
- box.width += lab.padLR * 2 + lab.imgPad;
- box.y -= lab.padTB;
- box.height += lab.padTB * 2;
-
- return box;
- }
-
- function hostLabel(d) {
- var idx = (hostLabelIndex < d.labels.length) ? hostLabelIndex : 0;
- return d.labels[idx];
- }
- function deviceLabel(d) {
- var idx = (deviceLabelIndex < d.labels.length) ? deviceLabelIndex : 0;
- return d.labels[idx];
- }
- function trimLabel(label) {
- return (label && label.trim()) || '';
- }
-
- function emptyBox() {
- return {
- x: -2,
- y: -2,
- width: 4,
- height: 4
- };
- }
-
- function updateDeviceRendering(d) {
- var label = trimLabel(deviceLabel(d)),
- noLabel = !label,
- node = d.el,
- dim = icfg.device.dim,
- box, dx, dy, bsel,
- bdg = d.badge,
- bcr = badgeConfig.radius,
- bcgd = badgeConfig.gdelta;
-
- node.select('text')
- .text(label)
- .style('opacity', 0)
- .transition()
- .style('opacity', 1);
-
- if (noLabel) {
- box = emptyBox();
- dx = -dim/2;
- dy = -dim/2;
- } else {
- box = adjustRectToFitText(node);
- dx = box.x + devCfg.xoff;
- dy = box.y + devCfg.yoff;
- }
-
- node.select('rect')
- .transition()
- .attr(box);
-
- node.select('g.deviceIcon')
- .transition()
- .attr('transform', sus.translate(dx, dy));
-
- // handle badge, if defined
- if (bdg) {
- renderBadge(node, bdg, { dx: dx + dim, dy: dy });
- }
- }
-
- function updateHostRendering(d) {
- var node = d.el,
- bdg = d.badge;
-
- updateHostLabel(d);
-
- // handle badge, if defined
- if (bdg) {
- renderBadge(node, bdg, icfg.host.badge);
- }
- }
-
- function renderBadge(node, bdg, boff) {
- var bsel,
- bcr = badgeConfig.radius,
- bcgd = badgeConfig.gdelta;
-
- node.select('g.badge').remove();
-
- bsel = node.append('g')
- .classed('badge', true)
- .classed(badgeStatus(bdg), true)
- .attr('transform', sus.translate(boff.dx, boff.dy));
-
- bsel.append('circle')
- .attr('r', bcr);
-
- if (bdg.txt) {
- bsel.append('text')
- .attr('dy', badgeConfig.yoff)
- .attr('text-anchor', 'middle')
- .text(bdg.txt);
- } else if (bdg.gid) {
- bsel.append('use')
- .attr({
- width: bcgd * 2,
- height: bcgd * 2,
- transform: sus.translate(-bcgd, -bcgd),
- 'xlink:href': '#' + bdg.gid
- });
- }
- }
-
- function updateHostLabel(d) {
- var label = trimLabel(hostLabel(d));
- d.el.select('text').text(label);
- }
-
- function updateDeviceColors(d) {
- if (d) {
- setDeviceColor(d);
- } else {
- api.node().filter('.device').each(function (d) {
- setDeviceColor(d);
- });
- }
- }
-
-
- // ==========================
- // updateNodes - subfunctions
-
- function deviceExisting(d) {
- var node = d.el;
- node.classed('online', d.online);
- updateDeviceRendering(d);
- api.posNode(d, true);
- }
-
- function hostExisting(d) {
- updateHostRendering(d);
- api.posNode(d, true);
- }
-
- function deviceEnter(d) {
- var node = d3.select(this),
- glyphId = d.type || 'unknown',
- label = trimLabel(deviceLabel(d)),
- //devCfg = deviceIconConfig,
- noLabel = !label,
- box, dx, dy, icon;
-
- d.el = node;
-
- node.append('rect').attr({ rx: 5, ry: 5 });
- node.append('text').text(label).attr('dy', '1.1em');
- box = adjustRectToFitText(node);
- node.select('rect').attr(box);
-
- icon = is.addDeviceIcon(node, glyphId);
-
- if (noLabel) {
- dx = -icon.dim/2;
- dy = -icon.dim/2;
- } else {
- box = adjustRectToFitText(node);
- dx = box.x + devCfg.xoff;
- dy = box.y + devCfg.yoff;
- }
-
- icon.attr('transform', sus.translate(dx, dy));
- }
-
- function hostEnter(d) {
- var node = d3.select(this),
- gid = d.type || 'unknown',
- rad = icfg.host.radius,
- r = d.type ? rad.withGlyph : rad.noGlyph,
- textDy = r + 10;
-
- d.el = node;
- sus.visible(node, api.showHosts());
-
- is.addHostIcon(node, r, gid);
-
- node.append('text')
- .text(hostLabel)
- .attr('dy', textDy)
- .attr('text-anchor', 'middle');
- }
-
- function hostExit(d) {
- var node = d.el;
- node.select('use')
- .style('opacity', 0.5)
- .transition()
- .duration(800)
- .style('opacity', 0);
-
- node.select('text')
- .style('opacity', 0.5)
- .transition()
- .duration(800)
- .style('opacity', 0);
-
- node.select('circle')
- .style('stroke-fill', '#555')
- .style('fill', '#888')
- .style('opacity', 0.5)
- .transition()
- .duration(1500)
- .attr('r', 0);
- }
-
- function deviceExit(d) {
- var node = d.el;
- node.select('use')
- .style('opacity', 0.5)
- .transition()
- .duration(800)
- .style('opacity', 0);
-
- node.selectAll('rect')
- .style('stroke-fill', '#555')
- .style('fill', '#888')
- .style('opacity', 0.5);
- }
-
-
- // ==========================
- // updateLinks - subfunctions
-
- function linkEntering(d) {
- var link = d3.select(this);
- d.el = link;
- api.restyleLinkElement(d);
- if (d.type() === 'hostLink') {
- sus.visible(link, api.showHosts());
- }
- }
-
- var linkLabelOffset = '0.3em';
-
- function applyLinkLabels() {
- var entering;
-
- api.updateLinkLabelModel();
-
- // for elements already existing, we need to update the text
- // and adjust the rectangle size to fit
- api.linkLabel().each(function (d) {
- var el = d3.select(this),
- rect = el.select('rect'),
- text = el.select('text');
- text.text(d.label);
- rect.attr(rectAroundText(el));
- });
-
- entering = api.linkLabel().enter().append('g')
- .classed('linkLabel', true)
- .attr('id', function (d) { return d.id; });
-
- entering.each(function (d) {
- var el = d3.select(this),
- rect,
- text;
-
- if (d.ldata.type() === 'hostLink') {
- el.classed('hostLinkLabel', true);
- sus.visible(el, api.showHosts());
- }
-
- d.el = el;
- rect = el.append('rect');
- text = el.append('text').text(d.label);
- rect.attr(rectAroundText(el));
- text.attr('dy', linkLabelOffset);
-
- el.attr('transform', transformLabel(d.ldata.position));
- });
-
- // Remove any labels that are no longer required.
- api.linkLabel().exit().remove();
- }
-
- function rectAroundText(el) {
- var text = el.select('text'),
- box = text.node().getBBox();
-
- // translate the bbox so that it is centered on [x,y]
- box.x = -box.width / 2;
- box.y = -box.height / 2;
-
- // add padding
- box.x -= 1;
- box.width += 2;
- return box;
- }
-
- function transformLabel(p) {
- var dx = p.x2 - p.x1,
- dy = p.y2 - p.y1,
- xMid = dx/2 + p.x1,
- yMid = dy/2 + p.y1;
- return sus.translate(xMid, yMid);
- }
-
- function applyPortLabels(data, portLabelG) {
- var entering = portLabelG.selectAll('.portLabel')
- .data(data).enter().append('g')
- .classed('portLabel', true)
- .attr('id', function (d) { return d.id; });
-
- entering.each(function (d) {
- var el = d3.select(this),
- rect = el.append('rect'),
- text = el.append('text').text(d.num);
-
- rect.attr(rectAroundText(el));
- text.attr('dy', linkLabelOffset);
- el.attr('transform', sus.translate(d.x, d.y));
- });
- }
-
- function labelPoint(linkPos) {
- var lengthUpLine = 1 / 3,
- dx = linkPos.x2 - linkPos.x1,
- dy = linkPos.y2 - linkPos.y1,
- movedX = dx * lengthUpLine,
- movedY = dy * lengthUpLine;
-
- return {
- x: movedX,
- y: movedY
- };
- }
-
- function calcGroupPos(linkPos) {
- var moved = labelPoint(linkPos);
- return sus.translate(linkPos.x1 + moved.x, linkPos.y1 + moved.y);
- }
-
- // calculates where on the link that the hash line for 5+ label appears
- function hashAttrs(linkPos) {
- var hashLength = 25,
- halfLength = hashLength / 2,
- dx = linkPos.x2 - linkPos.x1,
- dy = linkPos.y2 - linkPos.y1,
- length = Math.sqrt((dx * dx) + (dy * dy)),
- moveAmtX = (dx / length) * halfLength,
- moveAmtY = (dy / length) * halfLength,
- mid = labelPoint(linkPos),
- angle = Math.atan(dy / dx) + 45;
-
- return {
- x1: mid.x - moveAmtX,
- y1: mid.y - moveAmtY,
- x2: mid.x + moveAmtX,
- y2: mid.y + moveAmtY,
- stroke: api.linkConfig()[ts.theme()].baseColor,
- transform: 'rotate(' + angle + ',' + mid.x + ',' + mid.y + ')'
- };
- }
-
- function textLabelPos(linkPos) {
- var point = labelPoint(linkPos),
- dist = 20;
- return {
- x: point.x + dist,
- y: point.y + dist
- };
- }
-
- function applyNumLinkLabels(data, lblsG) {
- var labels = lblsG.selectAll('g.numLinkLabel')
- .data(data, function (d) { return 'pair-' + d.id; }),
- entering;
-
- // update existing labels
- labels.each(function (d) {
- var el = d3.select(this);
-
- el.attr({
- transform: function (d) { return calcGroupPos(d.linkCoords); }
- });
- el.select('line')
- .attr(hashAttrs(d.linkCoords));
- el.select('text')
- .attr(textLabelPos(d.linkCoords))
- .text(d.num);
- });
-
- // add new labels
- entering = labels
- .enter()
- .append('g')
- .attr({
- transform: function (d) { return calcGroupPos(d.linkCoords); },
- id: function (d) { return 'pair-' + d.id; }
- })
- .classed('numLinkLabel', true);
-
- entering.each(function (d) {
- var el = d3.select(this);
-
- el.append('line')
- .classed('numLinkHash', true)
- .attr(hashAttrs(d.linkCoords));
- el.append('text')
- .classed('numLinkText', true)
- .attr(textLabelPos(d.linkCoords))
- .text(d.num);
- });
-
- // remove old labels
- labels.exit().remove();
- }
-
- // ==========================
- // Module definition
-
- angular.module('ovTopo')
- .factory('TopoD3Service',
- ['$log', 'FnService', 'SvgUtilService', 'IconService', 'ThemeService',
-
- function (_$log_, _fs_, _sus_, _is_, _ts_) {
- $log = _$log_;
- fs = _fs_;
- sus = _sus_;
- is = _is_;
- ts = _ts_;
-
- icfg = is.iconConfig();
-
- function initD3(_api_) {
- api = _api_;
- }
-
- function destroyD3() { }
-
- return {
- initD3: initD3,
- destroyD3: destroyD3,
-
- incDevLabIndex: incDevLabIndex,
- adjustRectToFitText: adjustRectToFitText,
- hostLabel: hostLabel,
- deviceLabel: deviceLabel,
- trimLabel: trimLabel,
-
- updateDeviceLabel: updateDeviceRendering,
- updateHostLabel: updateHostLabel,
- updateDeviceColors: updateDeviceColors,
-
- deviceExisting: deviceExisting,
- hostExisting: hostExisting,
- deviceEnter: deviceEnter,
- hostEnter: hostEnter,
- hostExit: hostExit,
- deviceExit: deviceExit,
-
- linkEntering: linkEntering,
- applyLinkLabels: applyLinkLabels,
- transformLabel: transformLabel,
- applyPortLabels: applyPortLabels,
- applyNumLinkLabels: applyNumLinkLabels
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js
deleted file mode 100644
index 0c47511b..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoDialog.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Dialog Module.
- Defines functions for manipulating a dialog box.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, $window, $rootScope, fs, ps, bns;
-
- // constants
- var pCls = 'topo-p dialog',
- idDialog = 'topo-p-dialog',
- panelOpts = {
- width: 300,
- edge: 'left'
- };
-
- // internal state
- var pApi, panel, dApi;
-
- // TODO: ESC key invokes Cancel callback
- // TODO: Enter invokes OK callback
-
- // create the dialog; return its API
- function createDialog() {
- var header, body, footer,
- p = ps.createPanel(idDialog, panelOpts);
- p.classed(pCls, true);
- panel = p;
-
- function reset() {
- p.empty();
- p.append('div').classed('header', true);
- p.append('div').classed('body', true);
- p.append('div').classed('footer', true);
-
- header = p.el().select('.header');
- body = p.el().select('.body');
- footer = p.el().select('.footer');
- }
-
- function hAppend(x) {
- if (typeof x === 'string') {
- return header.append(x);
- }
- header.node().appendChild(x.node());
- return header;
- }
-
- function bAppend(x) {
- if (typeof x === 'string') {
- return body.append(x);
- }
- body.node().appendChild(x.node());
- return body;
- }
-
- function fAppend(x) {
- if (typeof x === 'string') {
- return footer.append(x);
- }
- footer.node().appendChild(x.node());
- return footer;
- }
-
- function destroy() {
- ps.destroyPanel(idDialog);
- }
-
- return {
- reset: reset,
- appendHeader: hAppend,
- appendBody: bAppend,
- appendFooter: fAppend,
- destroy: destroy
- };
- }
-
- function makeButton(text, callback) {
- var cb = fs.isF(callback);
-
- function invoke() {
- cb && cb();
- panel.hide();
- }
- return createDiv('dialog-button')
- .text(text)
- .on('click', invoke);
- }
-
- function setTitle(title) {
- if (pApi) {
- pApi.appendHeader('h2').text(title);
- }
- return dApi;
- }
-
- function addContent(content) {
- if (pApi) {
- pApi.appendBody(content);
- }
- return dApi;
- }
-
- function addButton(text, cb) {
- if (pApi) {
- pApi.appendFooter(makeButton(text, cb));
- }
- return dApi;
- }
-
- // opens the dialog (creates if necessary)
- function openDialog() {
- $log.debug('Open DIALOG');
- if (!pApi) {
- pApi = createDialog();
- }
- pApi.reset();
- panel.show();
-
- // return the dialog object API
- dApi = {
- setTitle: setTitle,
- addContent: addContent,
- addButton: addButton
- };
- return dApi;
- }
-
- // closes the dialog (destroying panel)
- function closeDialog() {
- $log.debug('Close DIALOG');
- if (pApi) {
- panel.hide();
- pApi.destroy();
- pApi = null;
- dApi = null;
- }
- }
-
- // creates a detached div, returning D3 selection
- // optional CSS class may be provided
- function createDiv(cls) {
- var div = d3.select(document.createElement('div'));
- if (cls) {
- div.classed(cls, true);
- }
- return div;
- }
-
- // ==========================
-
- angular.module('ovTopo')
- .factory('TopoDialogService',
- ['$log', '$window', '$rootScope', 'FnService', 'PanelService', 'ButtonService',
-
- function (_$log_, _$window_, _$rootScope_,
- _fs_, _ps_, _bns_) {
- $log = _$log_;
- $window = _$window_;
- $rootScope = _$rootScope_;
- fs = _fs_;
- ps = _ps_;
- bns = _bns_;
-
- return {
- openDialog: openDialog,
- closeDialog: closeDialog,
- createDiv: createDiv
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoEvent.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoEvent.js
deleted file mode 100644
index 9b07f878..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoEvent.js
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Event Module.
-
- Defines the conduit between the client and the server:
- - provides a clean API for sending events to the server
- - dispatches incoming events from the server to the appropriate sub-module
-
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, $interval, wss, tps, tis, tfs, tss, tov, tspr;
-
- // internal state
- var handlerMap,
- openListener,
- heartbeatTimer;
-
- var heartbeatPeriod = 9000; // 9 seconds
-
- // ==========================
-
- function createHandlerMap() {
- handlerMap = {
- showSummary: tps,
-
- showDetails: tss,
-
- showHighlights: tov,
-
- addInstance: tis,
- updateInstance: tis,
- removeInstance: tis,
-
- addDevice: tfs,
- updateDevice: tfs,
- removeDevice: tfs,
- addHost: tfs,
- updateHost: tfs,
- moveHost: tfs,
- removeHost: tfs,
- addLink: tfs,
- updateLink: tfs,
- removeLink: tfs,
-
- topoStartDone: tfs,
-
- spriteListResponse: tspr,
- spriteDataResponse: tspr
- };
- }
-
- function wsOpen(host, url) {
- $log.debug('TOPO: web socket open - cluster node:', host, 'URL:', url);
- // Request batch of initial data from the new server
- wss.sendEvent('topoStart');
- }
-
- function cancelHeartbeat() {
- if (heartbeatTimer) {
- $interval.cancel(heartbeatTimer);
- }
- heartbeatTimer = null;
- }
-
- function scheduleHeartbeat() {
- cancelHeartbeat();
- heartbeatTimer = $interval(function () {
- wss.sendEvent('topoHeartbeat');
- }, heartbeatPeriod);
- }
-
-
- angular.module('ovTopo')
- .factory('TopoEventService',
- ['$log', '$interval', 'WebSocketService',
- 'TopoPanelService', 'TopoInstService', 'TopoForceService',
- 'TopoSelectService', 'TopoOverlayService', 'TopoSpriteService',
-
- function (_$log_, _$interval_, _wss_,
- _tps_, _tis_, _tfs_, _tss_, _tov_, _tspr_) {
- $log = _$log_;
- $interval = _$interval_;
- wss = _wss_;
- tps = _tps_;
- tis = _tis_;
- tfs = _tfs_;
- tss = _tss_;
- tov = _tov_;
- tspr = _tspr_;
-
- createHandlerMap();
-
- function start() {
- openListener = wss.addOpenListener(wsOpen);
- wss.bindHandlers(handlerMap);
- wss.sendEvent('topoStart');
- scheduleHeartbeat();
- $log.debug('topo comms started');
- }
-
- function stop() {
- cancelHeartbeat();
- wss.sendEvent('topoStop');
- wss.unbindHandlers(handlerMap);
- wss.removeOpenListener(openListener);
- openListener = null;
- $log.debug('topo comms stopped');
- }
-
- return {
- start: start,
- stop: stop
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoFilter.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoFilter.js
deleted file mode 100644
index f9b96ae8..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoFilter.js
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 layer filtering Module.
- Provides functionality to visually differentiate between the packet and
- optical layers of the topology.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, fs, flash, tps, tts;
-
- // api to topoForce
- var api;
- /*
- node() // get ref to D3 selection of nodes
- link() // get ref to D3 selection of links
- */
-
- var smax = 'suppressedmax';
-
- // which "layer" a particular item "belongs to"
- var layerLookup = {
- host: {
- endstation: 'pkt', // default, if host event does not define type
- router: 'pkt',
- bgpSpeaker: 'pkt'
- },
- device: {
- switch: 'pkt',
- roadm: 'opt'
- },
- link: {
- hostLink: 'pkt',
- direct: 'pkt',
- indirect: '',
- tunnel: '',
- optical: 'opt'
- }
- },
- // order of layer cycling in button
- dispatch = [
- {
- type: 'all',
- action: function () { suppressLayers(false); },
- msg: 'All Layers Shown'
- },
- {
- type: 'pkt',
- action: function () { showLayer('pkt'); },
- msg: 'Packet Layer Shown'
- },
- {
- type: 'opt',
- action: function () { showLayer('opt'); },
- msg: 'Optical Layer Shown'
- }
- ],
- layer = 0;
-
- function clickAction() {
- layer = (layer + 1) % dispatch.length;
- dispatch[layer].action();
- flash.flash(dispatch[layer].msg);
- }
-
- function selected() {
- return dispatch[layer].type;
- }
-
- function inLayer(d, layer) {
- var type = d.class === 'link' ? d.type() : d.type,
- look = layerLookup[d.class],
- lyr = look && look[type];
- return lyr === layer;
- }
-
- function unsuppressLayer(which) {
- api.node().each(function (d) {
- var node = d.el;
- if (inLayer(d, which)) {
- node.classed(smax, false);
- }
- });
-
- api.link().each(function (d) {
- var link = d.el;
- if (inLayer(d, which)) {
- link.classed(smax, false);
- }
- });
- }
-
- function suppressLayers(b) {
- api.node().classed(smax, b);
- api.link().classed(smax, b);
- }
-
- function showLayer(which) {
- suppressLayers(true);
- unsuppressLayer(which);
- }
-
- // === -----------------------------------------------------
- // === MODULE DEFINITION ===
-
- angular.module('ovTopo')
- .factory('TopoFilterService',
- ['$log', 'FnService',
- 'FlashService',
- 'TopoPanelService',
- 'TopoTrafficService',
-
- function (_$log_, _fs_, _flash_, _tps_, _tts_) {
- $log = _$log_;
- fs = _fs_;
- flash = _flash_;
- tps = _tps_;
- tts = _tts_;
-
- function initFilter(_api_) {
- api = _api_;
- }
-
- return {
- initFilter: initFilter,
-
- clickAction: clickAction,
- selected: selected,
- inLayer: inLayer
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoForce.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoForce.js
deleted file mode 100644
index 175ee796..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoForce.js
+++ /dev/null
@@ -1,1182 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Force Module.
- Visualization of the topology in an SVG layer, using a D3 Force Layout.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, $timeout, fs, sus, ts, flash, wss, tov,
- tis, tms, td3, tss, tts, tos, fltr, tls, uplink, svg;
-
- // configuration
- var linkConfig = {
- light: {
- baseColor: '#666',
- inColor: '#66f',
- outColor: '#f00'
- },
- dark: {
- baseColor: '#aaa',
- inColor: '#66f',
- outColor: '#f66'
- },
- inWidth: 12,
- outWidth: 10
- };
-
- // internal state
- var settings, // merged default settings and options
- force, // force layout object
- drag, // drag behavior handler
- network = {
- nodes: [],
- links: [],
- linksByDevice: {},
- lookup: {},
- revLinkToKey: {}
- },
- lu, // shorthand for lookup
- rlk, // shorthand for revLinktoKey
- showHosts = false, // whether hosts are displayed
- showOffline = true, // whether offline devices are displayed
- nodeLock = false, // whether nodes can be dragged or not (locked)
- fTimer, // timer for delayed force layout
- fNodesTimer, // timer for delayed nodes update
- fLinksTimer, // timer for delayed links update
- dim, // the dimensions of the force layout [w,h]
- linkNums = []; // array of link number labels
-
- // SVG elements;
- var linkG, linkLabelG, numLinkLblsG, portLabelG, nodeG;
-
- // D3 selections;
- var link, linkLabel, node;
-
- // default settings for force layout
- var defaultSettings = {
- gravity: 0.4,
- friction: 0.7,
- charge: {
- // note: key is node.class
- device: -8000,
- host: -5000,
- _def_: -12000
- },
- linkDistance: {
- // note: key is link.type
- direct: 100,
- optical: 120,
- hostLink: 3,
- _def_: 50
- },
- linkStrength: {
- // note: key is link.type
- // range: {0.0 ... 1.0}
- //direct: 1.0,
- //optical: 1.0,
- //hostLink: 1.0,
- _def_: 1.0
- }
- };
-
-
- // ==========================
- // === EVENT HANDLERS
-
- function addDevice(data) {
- var id = data.id,
- d;
-
- uplink.showNoDevs(false);
-
- // although this is an add device event, if we already have the
- // device, treat it as an update instead..
- if (lu[id]) {
- updateDevice(data);
- return;
- }
-
- d = tms.createDeviceNode(data);
- network.nodes.push(d);
- lu[id] = d;
- updateNodes();
- fStart();
- }
-
- function updateDevice(data) {
- var id = data.id,
- d = lu[id],
- wasOnline;
-
- if (d) {
- wasOnline = d.online;
- angular.extend(d, data);
- if (tms.positionNode(d, true)) {
- sendUpdateMeta(d);
- }
- updateNodes();
- if (wasOnline !== d.online) {
- tms.findAttachedLinks(d.id).forEach(restyleLinkElement);
- updateOfflineVisibility(d);
- }
- }
- }
-
- function removeDevice(data) {
- var id = data.id,
- d = lu[id];
- if (d) {
- removeDeviceElement(d);
- }
- }
-
- function addHost(data) {
- var id = data.id,
- d, lnk;
-
- // although this is an add host event, if we already have the
- // host, treat it as an update instead..
- if (lu[id]) {
- updateHost(data);
- return;
- }
-
- d = tms.createHostNode(data);
- network.nodes.push(d);
- lu[id] = d;
- updateNodes();
-
- lnk = tms.createHostLink(data);
- if (lnk) {
- d.linkData = lnk; // cache ref on its host
- network.links.push(lnk);
- lu[d.ingress] = lnk;
- lu[d.egress] = lnk;
- updateLinks();
- }
- fStart();
- }
-
- function updateHost(data) {
- var id = data.id,
- d = lu[id];
- if (d) {
- angular.extend(d, data);
- if (tms.positionNode(d, true)) {
- sendUpdateMeta(d);
- }
- updateNodes();
- }
- }
-
- function moveHost(data) {
- var id = data.id,
- d = lu[id],
- lnk;
- if (d) {
- // first remove the old host link
- removeLinkElement(d.linkData);
-
- // merge new data
- angular.extend(d, data);
- if (tms.positionNode(d, true)) {
- sendUpdateMeta(d);
- }
-
- // now create a new host link
- lnk = tms.createHostLink(data);
- if (lnk) {
- d.linkData = lnk;
- network.links.push(lnk);
- lu[d.ingress] = lnk;
- lu[d.egress] = lnk;
- }
-
- updateNodes();
- updateLinks();
- fResume();
- }
- }
-
- function removeHost(data) {
- var id = data.id,
- d = lu[id];
- if (d) {
- removeHostElement(d, true);
- }
- }
-
- function addLink(data) {
- var result = tms.findLink(data, 'add'),
- bad = result.badLogic,
- d = result.ldata;
-
- if (bad) {
- //logicError(bad + ': ' + link.id);
- return;
- }
-
- if (d) {
- // we already have a backing store link for src/dst nodes
- addLinkUpdate(d, data);
- return;
- }
-
- // no backing store link yet
- d = tms.createLink(data);
- if (d) {
- network.links.push(d);
- aggregateLink(d, data);
- lu[d.key] = d;
- updateLinks();
- fStart();
- }
- }
-
- function updateLink(data) {
- var result = tms.findLink(data, 'update'),
- bad = result.badLogic;
- if (bad) {
- //logicError(bad + ': ' + link.id);
- return;
- }
- result.updateWith(link);
- }
-
- function removeLink(data) {
- var result = tms.findLink(data, 'remove');
-
- if (!result.badLogic) {
- result.removeRawLink();
- }
- }
-
- function topoStartDone(data) {
- // called when the initial barrage of data has been sent from server
- uplink.topoStartDone();
- }
-
- // ========================
-
- function nodeById(id) {
- return lu[id];
- }
-
- function makeNodeKey(node1, node2) {
- return node1 + '-' + node2;
- }
-
- function findNodePair(key, keyRev) {
- if (network.linksByDevice[key]) {
- return key;
- } else if (network.linksByDevice[keyRev]) {
- return keyRev;
- } else {
- return false;
- }
- }
-
- function aggregateLink(ldata, link) {
- var key = makeNodeKey(link.src, link.dst),
- keyRev = makeNodeKey(link.dst, link.src),
- found = findNodePair(key, keyRev);
-
- if (found) {
- network.linksByDevice[found].push(ldata);
- ldata.devicePair = found;
- } else {
- network.linksByDevice[key] = [ ldata ];
- ldata.devicePair = key;
- }
- }
-
- function addLinkUpdate(ldata, link) {
- // add link event, but we already have the reverse link installed
- ldata.fromTarget = link;
- rlk[link.id] = ldata.key;
- // possible solution to el being undefined in restyleLinkElement:
- //_updateLinks();
- restyleLinkElement(ldata);
- }
-
-
- var widthRatio = 1.4,
- linkScale = d3.scale.linear()
- .domain([1, 12])
- .range([widthRatio, 12 * widthRatio])
- .clamp(true),
- allLinkTypes = 'direct indirect optical tunnel';
-
- function restyleLinkElement(ldata, immediate) {
- // this fn's job is to look at raw links and decide what svg classes
- // need to be applied to the line element in the DOM
- var th = ts.theme(),
- el = ldata.el,
- type = ldata.type(),
- lw = ldata.linkWidth(),
- online = ldata.online(),
- delay = immediate ? 0 : 1000;
-
- // FIXME: understand why el is sometimes undefined on addLink events...
- // Investigated:
- // el is undefined when it's a reverse link that is being added.
- // updateLinks (which sets ldata.el) isn't called before this is called.
- // Calling _updateLinks in addLinkUpdate fixes it, but there might be
- // a more efficient way to fix it.
- if (el && !el.empty()) {
- el.classed('link', true);
- el.classed('inactive', !online);
- el.classed(allLinkTypes, false);
- if (type) {
- el.classed(type, true);
- }
- el.transition()
- .duration(delay)
- .attr('stroke-width', linkScale(lw))
- .attr('stroke', linkConfig[th].baseColor);
- }
- }
-
- function removeLinkElement(d) {
- var idx = fs.find(d.key, network.links, 'key'),
- removed;
- if (idx >=0) {
- // remove from links array
- removed = network.links.splice(idx, 1);
- // remove from lookup cache
- delete lu[removed[0].key];
- updateLinks();
- fResume();
- }
- }
-
- function removeHostElement(d, upd) {
- // first, remove associated hostLink...
- removeLinkElement(d.linkData);
-
- // remove hostLink bindings
- delete lu[d.ingress];
- delete lu[d.egress];
-
- // remove from lookup cache
- delete lu[d.id];
- // remove from nodes array
- var idx = fs.find(d.id, network.nodes);
- network.nodes.splice(idx, 1);
-
- // remove from SVG
- // NOTE: upd is false if we were called from removeDeviceElement()
- if (upd) {
- updateNodes();
- fResume();
- }
- }
-
- function removeDeviceElement(d) {
- var id = d.id,
- idx;
- // first, remove associated hosts and links..
- tms.findAttachedHosts(id).forEach(removeHostElement);
- tms.findAttachedLinks(id).forEach(removeLinkElement);
-
- // remove from lookup cache
- delete lu[id];
- // remove from nodes array
- idx = fs.find(id, network.nodes);
- if (idx > -1) {
- network.nodes.splice(idx, 1);
- }
-
- if (!network.nodes.length) {
- uplink.showNoDevs(true);
- }
-
- // remove from SVG
- updateNodes();
- fResume();
- }
-
- function updateHostVisibility() {
- sus.visible(nodeG.selectAll('.host'), showHosts);
- sus.visible(linkG.selectAll('.hostLink'), showHosts);
- sus.visible(linkLabelG.selectAll('.hostLinkLabel'), showHosts);
- }
-
- function updateOfflineVisibility(dev) {
- function updDev(d, show) {
- var b;
- sus.visible(d.el, show);
-
- tms.findAttachedLinks(d.id).forEach(function (link) {
- b = show && ((link.type() !== 'hostLink') || showHosts);
- sus.visible(link.el, b);
- });
- tms.findAttachedHosts(d.id).forEach(function (host) {
- b = show && showHosts;
- sus.visible(host.el, b);
- });
- }
-
- if (dev) {
- // updating a specific device that just toggled off/on-line
- updDev(dev, dev.online || showOffline);
- } else {
- // updating all offline devices
- tms.findDevices(true).forEach(function (d) {
- updDev(d, showOffline);
- });
- }
- }
-
-
- function sendUpdateMeta(d, clearPos) {
- var metaUi = {},
- ll;
-
- // if we are not clearing the position data (unpinning),
- // attach the x, y, longitude, latitude...
- if (!clearPos) {
- ll = tms.lngLatFromCoord([d.x, d.y]);
- metaUi = {x: d.x, y: d.y, lng: ll[0], lat: ll[1]};
- }
- d.metaUi = metaUi;
- wss.sendEvent('updateMeta', {
- id: d.id,
- class: d.class,
- memento: metaUi
- });
- }
-
-
- function mkSvgClass(d) {
- return d.fixed ? d.svgClass + ' fixed' : d.svgClass;
- }
-
- function vis(b) {
- return b ? 'visible' : 'hidden';
- }
-
- function toggleHosts(x) {
- var kev = (x === 'keyev'),
- on = kev ? !showHosts : !!x;
-
- showHosts = on;
- updateHostVisibility();
- flash.flash('Hosts ' + vis(on));
- return on;
- }
-
- function toggleOffline(x) {
- var kev = (x === 'keyev'),
- on = kev ? !showOffline : !!x;
-
- showOffline = on;
- updateOfflineVisibility();
- flash.flash('Offline devices ' + vis(on));
- return on;
- }
-
- function cycleDeviceLabels() {
- flash.flash(td3.incDevLabIndex());
- tms.findDevices().forEach(function (d) {
- td3.updateDeviceLabel(d);
- });
- }
-
- function unpin() {
- var hov = tss.hovered();
- if (hov) {
- sendUpdateMeta(hov, true);
- hov.fixed = false;
- hov.el.classed('fixed', false);
- fResume();
- }
- }
-
- function showMastership(masterId) {
- if (!masterId) {
- restoreLayerState();
- } else {
- showMastershipFor(masterId);
- }
- }
-
- function restoreLayerState() {
- // NOTE: this level of indirection required, for when we have
- // the layer filter functionality re-implemented
- suppressLayers(false);
- }
-
- function showMastershipFor(id) {
- suppressLayers(true);
- node.each(function (n) {
- if (n.master === id) {
- n.el.classed('suppressedmax', false);
- }
- });
- }
-
- function supAmt(less) {
- return less ? "suppressed" : "suppressedmax";
- }
-
- function suppressLayers(b, less) {
- var cls = supAmt(less);
- node.classed(cls, b);
- link.classed(cls, b);
- }
-
- function unsuppressNode(id, less) {
- var cls = supAmt(less);
- node.each(function (n) {
- if (n.id === id) {
- n.el.classed(cls, false);
- }
- });
- }
-
- function unsuppressLink(key, less) {
- var cls = supAmt(less);
- link.each(function (n) {
- if (n.key === key) {
- n.el.classed(cls, false);
- }
- });
- }
-
- function showBadLinks() {
- var badLinks = tms.findBadLinks();
- flash.flash('Bad Links: ' + badLinks.length);
- $log.debug('Bad Link List (' + badLinks.length + '):');
- badLinks.forEach(function (d) {
- $log.debug('bad link: (' + d.bad + ') ' + d.key, d);
- if (d.el) {
- d.el.attr('stroke-width', linkScale(2.8))
- .attr('stroke', 'red');
- }
- });
- // back to normal after 2 seconds...
- $timeout(updateLinks, 2000);
- }
-
- // ==========================================
-
- function updateNodes() {
- if (fNodesTimer) {
- $timeout.cancel(fNodesTimer);
- }
- fNodesTimer = $timeout(_updateNodes, 150);
- }
-
- // IMPLEMENTATION NOTE: _updateNodes() should NOT stop, start, or resume
- // the force layout; that needs to be determined and implemented elsewhere
- function _updateNodes() {
- // select all the nodes in the layout:
- node = nodeG.selectAll('.node')
- .data(network.nodes, function (d) { return d.id; });
-
- // operate on existing nodes:
- node.filter('.device').each(td3.deviceExisting);
- node.filter('.host').each(td3.hostExisting);
-
- // operate on entering nodes:
- var entering = node.enter()
- .append('g')
- .attr({
- id: function (d) { return sus.safeId(d.id); },
- class: mkSvgClass,
- transform: function (d) {
- // Need to guard against NaN here ??
- return sus.translate(d.x, d.y);
- },
- opacity: 0
- })
- .call(drag)
- .on('mouseover', tss.nodeMouseOver)
- .on('mouseout', tss.nodeMouseOut)
- .transition()
- .attr('opacity', 1);
-
- // augment entering nodes:
- entering.filter('.device').each(td3.deviceEnter);
- entering.filter('.host').each(td3.hostEnter);
-
- // operate on both existing and new nodes:
- td3.updateDeviceColors();
-
- // operate on exiting nodes:
- // Note that the node is removed after 2 seconds.
- // Sub element animations should be shorter than 2 seconds.
- var exiting = node.exit()
- .transition()
- .duration(2000)
- .style('opacity', 0)
- .remove();
-
- // exiting node specifics:
- exiting.filter('.host').each(td3.hostExit);
- exiting.filter('.device').each(td3.deviceExit);
- }
-
- // ==========================
-
- function getDefaultPos(link) {
- return {
- x1: link.source.x,
- y1: link.source.y,
- x2: link.target.x,
- y2: link.target.y
- };
- }
-
- // returns amount of adjustment along the normal for given link
- function amt(numLinks, linkIdx) {
- var gap = 6;
- return (linkIdx - ((numLinks - 1) / 2)) * gap;
- }
-
- function calcMovement(d, amt, flipped) {
- var pos = getDefaultPos(d),
- mult = flipped ? -amt : amt,
- dx = pos.x2 - pos.x1,
- dy = pos.y2 - pos.y1,
- length = Math.sqrt((dx * dx) + (dy * dy));
-
- return {
- x1: pos.x1 + (mult * dy / length),
- y1: pos.y1 + (mult * -dx / length),
- x2: pos.x2 + (mult * dy / length),
- y2: pos.y2 + (mult * -dx / length)
- };
- }
-
- function calcPosition() {
- var lines = this,
- linkSrcId;
- linkNums = [];
- lines.each(function (d) {
- if (d.type() === 'hostLink') {
- d.position = getDefaultPos(d);
- }
- });
-
- function normalizeLinkSrc(link) {
- // ensure source device is consistent across set of links
- // temporary measure until link modeling is refactored
- if (!linkSrcId) {
- linkSrcId = link.source.id;
- return false;
- }
-
- return link.source.id !== linkSrcId;
- }
-
- angular.forEach(network.linksByDevice, function (linkArr, key) {
- var numLinks = linkArr.length,
- link;
-
- if (numLinks === 1) {
- link = linkArr[0];
- link.position = getDefaultPos(link);
- link.position.multiLink = false;
- } else if (numLinks >= 5) {
- // this code is inefficient, in the future the way links
- // are modeled will be changed
- angular.forEach(linkArr, function (link) {
- link.position = getDefaultPos(link);
- link.position.multiLink = true;
- });
- linkNums.push({
- id: key,
- num: numLinks,
- linkCoords: linkArr[0].position
- });
- } else {
- linkSrcId = null;
- angular.forEach(linkArr, function (link, index) {
- var offsetAmt = amt(numLinks, index),
- needToFlip = normalizeLinkSrc(link);
- link.position = calcMovement(link, offsetAmt, needToFlip);
- link.position.multiLink = false;
- });
- }
- });
- }
-
- function updateLinks() {
- if (fLinksTimer) {
- $timeout.cancel(fLinksTimer);
- }
- fLinksTimer = $timeout(_updateLinks, 150);
- }
-
- // IMPLEMENTATION NOTE: _updateLinks() should NOT stop, start, or resume
- // the force layout; that needs to be determined and implemented elsewhere
- function _updateLinks() {
- var th = ts.theme();
-
- link = linkG.selectAll('.link')
- .data(network.links, function (d) { return d.key; });
-
- // operate on existing links:
- link.each(function (d) {
- // this is supposed to be an existing link, but we have observed
- // occasions (where links are deleted and added rapidly?) where
- // the DOM element has not been defined. So protect against that...
- if (d.el) {
- restyleLinkElement(d, true);
- }
- });
-
- // operate on entering links:
- var entering = link.enter()
- .append('line')
- .call(calcPosition)
- .attr({
- x1: function (d) { return d.position.x1; },
- y1: function (d) { return d.position.y1; },
- x2: function (d) { return d.position.x2; },
- y2: function (d) { return d.position.y2; },
- stroke: linkConfig[th].inColor,
- 'stroke-width': linkConfig.inWidth
- });
-
- // augment links
- entering.each(td3.linkEntering);
-
- // operate on both existing and new links:
- //link.each(...)
-
- // add labels for how many links are in a thick line
- td3.applyNumLinkLabels(linkNums, numLinkLblsG);
-
- // apply or remove labels
- td3.applyLinkLabels();
-
- // operate on exiting links:
- link.exit()
- .attr('stroke-dasharray', '3 3')
- .attr('stroke', linkConfig[th].outColor)
- .style('opacity', 0.5)
- .transition()
- .duration(1500)
- .attr({
- 'stroke-dasharray': '3 12',
- 'stroke-width': linkConfig.outWidth
- })
- .style('opacity', 0.0)
- .remove();
- }
-
-
- // ==========================
- // force layout tick function
-
- function fResume() {
- if (!tos.isOblique()) {
- force.resume();
- }
- }
-
- function fStart() {
- if (!tos.isOblique()) {
- if (fTimer) {
- $timeout.cancel(fTimer);
- }
- fTimer = $timeout(function () {
- $log.debug("Starting force-layout");
- force.start();
- }, 200);
- }
- }
-
- var tickStuff = {
- nodeAttr: {
- transform: function (d) {
- var dx = isNaN(d.x) ? 0 : d.x,
- dy = isNaN(d.y) ? 0 : d.y;
- return sus.translate(dx, dy);
- }
- },
- linkAttr: {
- x1: function (d) { return d.position.x1; },
- y1: function (d) { return d.position.y1; },
- x2: function (d) { return d.position.x2; },
- y2: function (d) { return d.position.y2; }
- },
- linkLabelAttr: {
- transform: function (d) {
- var lnk = tms.findLinkById(d.key);
- if (lnk) {
- return td3.transformLabel(lnk.position);
- }
- }
- }
- };
-
- function tick() {
- // guard against null (which can happen when our view pages out)...
- if (node && node.size()) {
- node.attr(tickStuff.nodeAttr);
- }
- if (link && link.size()) {
- link.call(calcPosition)
- .attr(tickStuff.linkAttr);
- td3.applyNumLinkLabels(linkNums, numLinkLblsG);
- }
- if (linkLabel && linkLabel.size()) {
- linkLabel.attr(tickStuff.linkLabelAttr);
- }
- }
-
-
- // ==========================
- // === MOUSE GESTURE HANDLERS
-
- function zoomingOrPanning(ev) {
- return ev.metaKey || ev.altKey;
- }
-
- function atDragEnd(d) {
- // once we've finished moving, pin the node in position
- d.fixed = true;
- d3.select(this).classed('fixed', true);
- sendUpdateMeta(d);
- tss.clickConsumed(true);
- }
-
- // predicate that indicates when dragging is active
- function dragEnabled() {
- var ev = d3.event.sourceEvent;
- // nodeLock means we aren't allowing nodes to be dragged...
- return !nodeLock && !zoomingOrPanning(ev);
- }
-
- // predicate that indicates when clicking is active
- function clickEnabled() {
- return true;
- }
-
- // =============================================
- // function entry points for overlay module
-
- // TODO: find an automatic way of tracking via the "showHighlights" events
- var allTrafficClasses = 'primary secondary optical animated ' +
- 'port-traffic-Kbps port-traffic-Mbps port-traffic-Gbps ' +
- 'port-traffic-Gbps-choked';
-
- function clearLinkTrafficStyle() {
- link.style('stroke-width', null)
- .classed(allTrafficClasses, false);
- }
-
- function removeLinkLabels() {
- network.links.forEach(function (d) {
- d.label = '';
- });
- }
-
- function clearNodeDeco() {
- node.selectAll('g.badge').remove();
- }
-
- function removeNodeBadges() {
- network.nodes.forEach(function (d) {
- d.badge = null;
- });
- }
-
- function updateLinkLabelModel() {
- // create the backing data for showing labels..
- var data = [];
- link.each(function (d) {
- if (d.label) {
- data.push({
- id: 'lab-' + d.key,
- key: d.key,
- label: d.label,
- ldata: d
- });
- }
- });
-
- linkLabel = linkLabelG.selectAll('.linkLabel')
- .data(data, function (d) { return d.id; });
- }
-
- // ==========================
- // Module definition
-
- function mkModelApi(uplink) {
- return {
- projection: uplink.projection,
- network: network,
- restyleLinkElement: restyleLinkElement,
- removeLinkElement: removeLinkElement
- };
- }
-
- function mkD3Api() {
- return {
- node: function () { return node; },
- link: function () { return link; },
- linkLabel: function () { return linkLabel; },
- instVisible: function () { return tis.isVisible(); },
- posNode: tms.positionNode,
- showHosts: function () { return showHosts; },
- restyleLinkElement: restyleLinkElement,
- updateLinkLabelModel: updateLinkLabelModel,
- linkConfig: function () { return linkConfig; }
- };
- }
-
- function mkSelectApi() {
- return {
- node: function () { return node; },
- zoomingOrPanning: zoomingOrPanning,
- updateDeviceColors: td3.updateDeviceColors,
- deselectLink: tls.deselectLink
- };
- }
-
- function mkTrafficApi() {
- return {
- hovered: tss.hovered,
- somethingSelected: tss.somethingSelected,
- selectOrder: tss.selectOrder
- };
- }
-
- function mkOverlayApi() {
- return {
- clearNodeDeco: clearNodeDeco,
- removeNodeBadges: removeNodeBadges,
- clearLinkTrafficStyle: clearLinkTrafficStyle,
- removeLinkLabels: removeLinkLabels,
- findLinkById: tms.findLinkById,
- findNodeById: nodeById,
- updateLinks: updateLinks,
- updateNodes: updateNodes,
- supLayers: suppressLayers,
- unsupNode: unsuppressNode,
- unsupLink: unsuppressLink
- };
- }
-
- function mkObliqueApi(uplink, fltr) {
- return {
- force: function() { return force; },
- zoomLayer: uplink.zoomLayer,
- nodeGBBox: function() { return nodeG.node().getBBox(); },
- node: function () { return node; },
- link: function () { return link; },
- linkLabel: function () { return linkLabel; },
- nodes: function () { return network.nodes; },
- tickStuff: tickStuff,
- nodeLock: function (b) {
- var old = nodeLock;
- nodeLock = b;
- return old;
- },
- opacifyMap: uplink.opacifyMap,
- inLayer: fltr.inLayer,
- calcLinkPos: calcPosition,
- applyNumLinkLabels: function () {
- td3.applyNumLinkLabels(linkNums, numLinkLblsG);
- }
- };
- }
-
- function mkFilterApi() {
- return {
- node: function () { return node; },
- link: function () { return link; }
- };
- }
-
- function mkLinkApi(svg, uplink) {
- return {
- svg: svg,
- zoomer: uplink.zoomer(),
- network: network,
- portLabelG: function () { return portLabelG; },
- showHosts: function () { return showHosts; }
- };
- }
-
- angular.module('ovTopo')
- .factory('TopoForceService',
- ['$log', '$timeout', 'FnService', 'SvgUtilService',
- 'ThemeService', 'FlashService', 'WebSocketService',
- 'TopoOverlayService', 'TopoInstService', 'TopoModelService',
- 'TopoD3Service', 'TopoSelectService', 'TopoTrafficService',
- 'TopoObliqueService', 'TopoFilterService', 'TopoLinkService',
-
- function (_$log_, _$timeout_, _fs_, _sus_, _ts_, _flash_, _wss_, _tov_,
- _tis_, _tms_, _td3_, _tss_, _tts_, _tos_, _fltr_, _tls_) {
- $log = _$log_;
- $timeout = _$timeout_;
- fs = _fs_;
- sus = _sus_;
- ts = _ts_;
- flash = _flash_;
- wss = _wss_;
- tov = _tov_;
- tis = _tis_;
- tms = _tms_;
- td3 = _td3_;
- tss = _tss_;
- tts = _tts_;
- tos = _tos_;
- fltr = _fltr_;
- tls = _tls_;
-
- var themeListener = ts.addListener(function () {
- updateLinks();
- updateNodes();
- });
-
- // forceG is the SVG group to display the force layout in
- // uplink is the api from the main topo source file
- // dim is the initial dimensions of the SVG as [w,h]
- // opts are, well, optional :)
- function initForce(_svg_, forceG, _uplink_, _dim_, opts) {
- uplink = _uplink_;
- dim = _dim_;
- svg = _svg_;
-
- lu = network.lookup;
- rlk = network.revLinkToKey;
-
- $log.debug('initForce().. dim = ' + dim);
-
- tov.setApi(mkOverlayApi(), tss);
- tms.initModel(mkModelApi(uplink), dim);
- td3.initD3(mkD3Api());
- tss.initSelect(mkSelectApi());
- tts.initTraffic(mkTrafficApi());
- tos.initOblique(mkObliqueApi(uplink, fltr));
- fltr.initFilter(mkFilterApi());
- tls.initLink(mkLinkApi(svg, uplink), td3);
-
- settings = angular.extend({}, defaultSettings, opts);
-
- linkG = forceG.append('g').attr('id', 'topo-links');
- linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels');
- numLinkLblsG = forceG.append('g').attr('id', 'topo-numLinkLabels');
- nodeG = forceG.append('g').attr('id', 'topo-nodes');
- portLabelG = forceG.append('g').attr('id', 'topo-portLabels');
-
- link = linkG.selectAll('.link');
- linkLabel = linkLabelG.selectAll('.linkLabel');
- node = nodeG.selectAll('.node');
-
- force = d3.layout.force()
- .size(dim)
- .nodes(network.nodes)
- .links(network.links)
- .gravity(settings.gravity)
- .friction(settings.friction)
- .charge(settings.charge._def_)
- .linkDistance(settings.linkDistance._def_)
- .linkStrength(settings.linkStrength._def_)
- .on('tick', tick);
-
- drag = sus.createDragBehavior(force,
- tss.selectObject, atDragEnd, dragEnabled, clickEnabled);
- }
-
- function newDim(_dim_) {
- dim = _dim_;
- force.size(dim);
- tms.newDim(dim);
- }
-
- function destroyForce() {
- force.stop();
-
- tls.destroyLink();
- tos.destroyOblique();
- tts.destroyTraffic();
- tss.destroySelect();
- td3.destroyD3();
- tms.destroyModel();
- // note: no need to destroy overlay service
- ts.removeListener(themeListener);
- themeListener = null;
-
- // clean up the DOM
- svg.selectAll('g').remove();
- svg.selectAll('defs').remove();
-
- // clean up internal state
- network.nodes = [];
- network.links = [];
- network.linksByDevice = {};
- network.lookup = {};
- network.revLinkToKey = {};
-
- linkNums = [];
-
- linkG = linkLabelG = numLinkLblsG = nodeG = portLabelG = null;
- link = linkLabel = node = null;
- force = drag = null;
-
- // clean up $timeout promises
- if (fTimer) {
- $timeout.cancel(fTimer);
- }
- if (fNodesTimer) {
- $timeout.cancel(fNodesTimer);
- }
- if (fLinksTimer) {
- $timeout.cancel(fLinksTimer);
- }
- }
-
- return {
- initForce: initForce,
- newDim: newDim,
- destroyForce: destroyForce,
-
- updateDeviceColors: td3.updateDeviceColors,
- toggleHosts: toggleHosts,
- togglePorts: tls.togglePorts,
- toggleOffline: toggleOffline,
- cycleDeviceLabels: cycleDeviceLabels,
- unpin: unpin,
- showMastership: showMastership,
- showBadLinks: showBadLinks,
-
- addDevice: addDevice,
- updateDevice: updateDevice,
- removeDevice: removeDevice,
- addHost: addHost,
- updateHost: updateHost,
- moveHost: moveHost,
- removeHost: removeHost,
- addLink: addLink,
- updateLink: updateLink,
- removeLink: removeLink,
- topoStartDone: topoStartDone
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoInst.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoInst.js
deleted file mode 100644
index 7e929977..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoInst.js
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Instances Module.
- Defines modeling of ONOS instances.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, ps, sus, gs, ts, fs, flash;
-
- // api from topo
- var api;
- /*
- showMastership( id )
- */
-
- // configuration
- var instCfg = {
- rectPad: 8,
- nodeOx: 9,
- nodeOy: 9,
- nodeDim: 40,
- birdOx: 19,
- birdOy: 21,
- birdDim: 21,
- uiDy: 45,
- titleDy: 30,
- textYOff: 20,
- textYSpc: 15
- },
- showLogicErrors = true,
- idIns = 'topo-p-instance',
- instOpts = {
- edge: 'left',
- width: 20
- };
-
- // internal state
- var onosInstances,
- onosOrder,
- oiShowMaster,
- oiBox,
- themeListener;
-
-
- // ==========================
-
- function addInstance(data) {
- var id = data.id;
-
- if (onosInstances[id]) {
- updateInstance(data);
- return;
- }
- onosInstances[id] = data;
- onosOrder.push(data);
- updateInstances();
- }
-
- function updateInstance(data) {
- var id = data.id,
- d = onosInstances[id];
- if (d) {
- angular.extend(d, data);
- updateInstances();
- } else {
- logicError('updateInstance: lookup fail: ID = "' + id + '"');
- }
- }
-
- function removeInstance(data) {
- var id = data.id,
- d = onosInstances[id];
- if (d) {
- var idx = fs.find(id, onosOrder);
- if (idx >= 0) {
- onosOrder.splice(idx, 1);
- }
- delete onosInstances[id];
- updateInstances();
- } else {
- logicError('removeInstance lookup fail. ID = "' + id + '"');
- }
- }
-
- // ==========================
-
- function computeDim(self) {
- var css = window.getComputedStyle(self);
- return {
- w: sus.stripPx(css.width),
- h: sus.stripPx(css.height)
- };
- }
-
- function clickInst(d) {
- var el = d3.select(this),
- aff = el.classed('affinity');
- if (!aff) {
- setAffinity(el, d);
- } else {
- cancelAffinity();
- }
- }
-
- function setAffinity(el, d) {
- d3.selectAll('.onosInst')
- .classed('mastership', true)
- .classed('affinity', false);
- el.classed('affinity', true);
-
- // suppress all elements except nodes whose master is this instance
- api.showMastership(d.id);
- oiShowMaster = true;
- }
-
- function cancelAffinity() {
- d3.selectAll('.onosInst')
- .classed('mastership affinity', false);
-
- api.showMastership(null);
- oiShowMaster = false;
- }
-
- function instRectAttr(dim) {
- var pad = instCfg.rectPad;
- return {
- x: pad,
- y: pad,
- width: dim.w - pad*2,
- height: dim.h - pad*2,
- rx: 6
- };
- }
-
- function viewBox(dim) {
- return '0 0 ' + dim.w + ' ' + dim.h;
- }
-
- function attachUiBadge(svg) {
- gs.addGlyph(svg, 'uiAttached', 30, true, [12, instCfg.uiDy])
- .classed('badgeIcon uiBadge', true);
- }
-
- function instColor(id, online) {
- return sus.cat7().getColor(id, !online, ts.theme());
- }
-
- // ==============================
-
- function updateInstances() {
- var onoses = oiBox.el().selectAll('.onosInst')
- .data(onosOrder, function (d) { return d.id; }),
- instDim = {w:0,h:0},
- c = instCfg;
-
- function nSw(n) {
- return '# Switches: ' + n;
- }
-
- // operate on existing onos instances if necessary
- onoses.each(function (d) {
- var el = d3.select(this),
- svg = el.select('svg');
- instDim = computeDim(this);
-
- // update online state
- el.classed('online', d.online);
-
- // update ui-attached state
- svg.select('use.uiBadge').remove();
- if (d.uiAttached) {
- attachUiBadge(svg);
- }
-
- function updAttr(id, value) {
- svg.select('text.instLabel.'+id).text(value);
- }
-
- updAttr('ip', d.ip);
- updAttr('ns', nSw(d.switches));
- });
-
-
- // operate on new onos instances
- var entering = onoses.enter()
- .append('div')
- .attr('class', 'onosInst')
- .classed('online', function (d) { return d.online; })
- .on('click', clickInst);
-
- entering.each(function (d) {
- var el = d3.select(this),
- rectAttr,
- svg;
- instDim = computeDim(this);
- rectAttr = instRectAttr(instDim);
-
- svg = el.append('svg').attr({
- width: instDim.w,
- height: instDim.h,
- viewBox: viewBox(instDim)
- });
-
- svg.append('rect').attr(rectAttr);
-
- gs.addGlyph(svg, 'bird', 28, true, [14, 14])
- .classed('badgeIcon', true);
-
- if (d.uiAttached) {
- attachUiBadge(svg);
- }
-
- var left = c.nodeOx + c.nodeDim,
- len = rectAttr.width - left,
- hlen = len / 2,
- midline = hlen + left;
-
- // title
- svg.append('text')
- .attr({
- class: 'instTitle',
- x: midline,
- y: c.titleDy
- })
- .text(d.id);
-
- // a couple of attributes
- var ty = c.titleDy + c.textYOff;
-
- function addAttr(id, label) {
- svg.append('text').attr({
- class: 'instLabel ' + id,
- x: midline,
- y: ty
- }).text(label);
- ty += c.textYSpc;
- }
-
- addAttr('ip', d.ip);
- addAttr('ns', nSw(d.switches));
- });
-
- // operate on existing + new onoses here
- // set the affinity colors...
- onoses.each(function (d) {
- var el = d3.select(this),
- rect = el.select('svg').select('rect'),
- col = instColor(d.id, d.online);
- rect.style('fill', col);
- });
-
- // adjust the panel size appropriately...
- oiBox.width(instDim.w * onosOrder.length);
- oiBox.height(instDim.h);
-
- // remove any outgoing instances
- onoses.exit().remove();
- }
-
-
- // ==========================
-
- function logicError(msg) {
- if (showLogicErrors) {
- $log.warn('TopoInstService: ' + msg);
- }
- }
-
- function initInst(_api_) {
- api = _api_;
- oiBox = ps.createPanel(idIns, instOpts);
- oiBox.show();
-
- onosInstances = {};
- onosOrder = [];
- oiShowMaster = false;
-
- // we want to update the instances, each time the theme changes
- themeListener = ts.addListener(updateInstances);
- }
-
- function destroyInst() {
- ts.removeListener(themeListener);
- themeListener = null;
-
- ps.destroyPanel(idIns);
- oiBox = null;
-
- onosInstances = {};
- onosOrder = [];
- oiShowMaster = false;
- }
-
- function showInsts() {
- oiBox.show();
- }
-
- function hideInsts() {
- oiBox.hide();
- }
-
- function toggleInsts(x) {
- var kev = (x === 'keyev'),
- on,
- verb;
-
- if (kev) {
- on = oiBox.toggle();
- } else {
- on = !!x;
- if (on) {
- showInsts();
- } else {
- hideInsts();
- }
- }
- verb = on ? 'Show' : 'Hide';
- flash.flash(verb + ' instances panel');
- return on;
- }
-
- // ==========================
-
- angular.module('ovTopo')
- .factory('TopoInstService',
- ['$log', 'PanelService', 'SvgUtilService', 'GlyphService',
- 'ThemeService', 'FnService', 'FlashService',
-
- function (_$log_, _ps_, _sus_, _gs_, _ts_, _fs_, _flash_) {
- $log = _$log_;
- ps = _ps_;
- sus = _sus_;
- gs = _gs_;
- ts = _ts_;
- fs = _fs_;
- flash = _flash_;
-
- return {
- initInst: initInst,
- destroyInst: destroyInst,
-
- addInstance: addInstance,
- updateInstance: updateInstance,
- removeInstance: removeInstance,
-
- cancelAffinity: cancelAffinity,
-
- isVisible: function () { return oiBox.isVisible(); },
- show: showInsts,
- hide: hideInsts,
- toggle: toggleInsts,
- showMaster: function () { return oiShowMaster; }
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoLink.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoLink.js
deleted file mode 100644
index 38f3a6c3..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoLink.js
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Link Module.
- Functions for highlighting/selecting links
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, fs, sus, ts, flash, tss, tps;
-
- // internal state
- var api,
- td3,
- network,
- showPorts = true, // enable port highlighting by default
- enhancedLink = null, // the link over which the mouse is hovering
- selectedLink = null; // the link which is currently selected
-
- // SVG elements;
- var svg;
-
-
- // ======== ALGORITHM TO FIND LINK CLOSEST TO MOUSE ========
-
- function getLogicalMousePosition(container) {
- var m = d3.mouse(container),
- sc = api.zoomer.scale(),
- tr = api.zoomer.translate(),
- mx = (m[0] - tr[0]) / sc,
- my = (m[1] - tr[1]) / sc;
- return {x: mx, y: my};
- }
-
-
- function sq(x) { return x * x; }
-
- function mdist(p, m) {
- return Math.sqrt(sq(p.x - m.x) + sq(p.y - m.y));
- }
-
- function prox(dist) {
- return dist / api.zoomer.scale();
- }
-
- function computeNearestNode(mouse) {
- var proximity = prox(30),
- nearest = null,
- minDist;
-
- if (network.nodes.length) {
- minDist = proximity * 2;
-
- network.nodes.forEach(function (d) {
- var dist;
-
- if (!api.showHosts() && d.class === 'host') {
- return; // skip hidden hosts
- }
-
- dist = mdist({x: d.x, y: d.y}, mouse);
- if (dist < minDist && dist < proximity) {
- minDist = dist;
- nearest = d;
- }
- });
- }
- return nearest;
- }
-
-
- function computeNearestLink(mouse) {
- var proximity = prox(30),
- nearest = null,
- minDist;
-
- function pdrop(line, mouse) {
- var x1 = line.x1,
- y1 = line.y1,
- x2 = line.x2,
- y2 = line.y2,
- x3 = mouse.x,
- y3 = mouse.y,
- k = ((y2-y1) * (x3-x1) - (x2-x1) * (y3-y1)) /
- (sq(y2-y1) + sq(x2-x1)),
- x4 = x3 - k * (y2-y1),
- y4 = y3 + k * (x2-x1);
- return {x:x4, y:y4};
- }
-
- function lineHit(line, p, m) {
- if (p.x < line.x1 && p.x < line.x2) return false;
- if (p.x > line.x1 && p.x > line.x2) return false;
- if (p.y < line.y1 && p.y < line.y2) return false;
- if (p.y > line.y1 && p.y > line.y2) return false;
- // line intersects, but are we close enough?
- return mdist(p, m) <= proximity;
- }
-
- if (network.links.length) {
- minDist = proximity * 2;
-
- network.links.forEach(function (d) {
- if (!api.showHosts() && d.type() === 'hostLink') {
- return; // skip hidden host links
- }
-
- var line = d.position,
- point = pdrop(line, mouse),
- hit = lineHit(line, point, mouse),
- dist;
-
- if (hit) {
- dist = mdist(point, mouse);
- if (dist < minDist) {
- minDist = dist;
- nearest = d;
- }
- }
- });
- }
- return nearest;
- }
-
- function enhanceLink(ldata) {
- // if the new link is same as old link, do nothing
- if (enhancedLink && ldata && enhancedLink.key === ldata.key) return;
-
- // first, unenhance the currently enhanced link
- if (enhancedLink) {
- unenhance(enhancedLink);
- }
- enhancedLink = ldata;
- if (enhancedLink) {
- enhance(enhancedLink);
- }
- }
-
- function unenhance(d) {
- // guard against link element not set
- if (d.el) {
- d.el.classed('enhanced', false);
- }
- api.portLabelG().selectAll('.portLabel').remove();
- }
-
- function enhance(d) {
- var data = [],
- point;
-
- // guard against link element not set
- if (!d.el) return;
-
- d.el.classed('enhanced', true);
-
- // Define port label data objects.
- // NOTE: src port is absent in the case of host-links.
-
- point = locatePortLabel(d);
- angular.extend(point, {
- id: 'topo-port-tgt',
- num: d.tgtPort
- });
- data.push(point);
-
- if (d.srcPort) {
- point = locatePortLabel(d, 1);
- angular.extend(point, {
- id: 'topo-port-src',
- num: d.srcPort
- });
- data.push(point);
- }
-
- td3.applyPortLabels(data, api.portLabelG());
- }
-
- function locatePortLabel(link, src) {
- var offset = 32,
- pos = link.position,
- nearX = src ? pos.x1 : pos.x2,
- nearY = src ? pos.y1 : pos.y2,
- farX = src ? pos.x2 : pos.x1,
- farY = src ? pos.y2 : pos.y1;
-
- function dist(x, y) { return Math.sqrt(x*x + y*y); }
-
- var dx = farX - nearX,
- dy = farY - nearY,
- k = offset / dist(dx, dy);
-
- return {x: k * dx + nearX, y: k * dy + nearY};
- }
-
- function selectLink(ldata) {
- // if the new link is same as old link, do nothing
- if (selectedLink && ldata && selectedLink.key === ldata.key) return;
-
- // make sure no nodes are selected
- tss.deselectAll();
-
- // first, unenhance the currently enhanced link
- if (selectedLink) {
- unselLink(selectedLink);
- }
- selectedLink = ldata;
- if (selectedLink) {
- selLink(selectedLink);
- }
- }
-
- function unselLink(d) {
- // guard against link element not set
- if (d.el) {
- d.el.classed('selected', false);
- }
- }
-
- function selLink(d) {
- // guard against link element not set
- if (!d.el) return;
-
- d.el.classed('selected', true);
-
- tps.displayLink(d);
- tps.displaySomething();
- }
-
- // ====== MOUSE EVENT HANDLERS ======
-
- function mouseMoveHandler() {
- var mp = getLogicalMousePosition(this),
- link = computeNearestLink(mp);
- enhanceLink(link);
- }
-
- function mouseClickHandler() {
- var mp, link, node;
-
- if (!tss.clickConsumed()) {
- mp = getLogicalMousePosition(this);
- node = computeNearestNode(mp);
- if (node) {
- $log.debug('found nearest node:', node.labels[1]);
- tss.selectObject(node);
- } else {
- link = computeNearestLink(mp);
- selectLink(link);
- }
- }
- }
-
-
- // ======================
-
- function togglePorts(x) {
- var kev = (x === 'keyev'),
- on = kev ? !showPorts : !!x,
- what = on ? 'Enable' : 'Disable',
- handler = on ? mouseMoveHandler : null;
-
- showPorts = on;
-
- if (!on) {
- enhanceLink(null);
- }
- svg.on('mousemove', handler);
- flash.flash(what + ' port highlighting');
- return on;
- }
-
- function deselectLink() {
- if (selectedLink) {
- unselLink(selectedLink);
- selectedLink = null;
- return true;
- }
- return false;
- }
-
- // ==========================
- // Module definition
-
- angular.module('ovTopo')
- .factory('TopoLinkService',
- ['$log', 'FnService', 'SvgUtilService', 'ThemeService', 'FlashService',
- 'TopoSelectService', 'TopoPanelService',
-
- function (_$log_, _fs_, _sus_, _ts_, _flash_, _tss_, _tps_) {
- $log = _$log_;
- fs = _fs_;
- sus = _sus_;
- ts = _ts_;
- flash = _flash_;
- tss = _tss_;
- tps = _tps_;
-
- function initLink(_api_, _td3_) {
- api = _api_;
- td3 = _td3_;
- svg = api.svg;
- network = api.network;
- if (showPorts && !fs.isMobile()) {
- svg.on('mousemove', mouseMoveHandler);
- }
- svg.on('click', mouseClickHandler);
- }
-
- function destroyLink() {
- // unconditionally remove any event handlers
- svg.on('mousemove', null);
- svg.on('click', null);
- }
-
- return {
- initLink: initLink,
- destroyLink: destroyLink,
- togglePorts: togglePorts,
- deselectLink: deselectLink
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoModel.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoModel.js
deleted file mode 100644
index fb98fc2b..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoModel.js
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Model Module.
- Auxiliary functions for the model of the topology; that is, our internal
- representations of devices, hosts, links, etc.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, fs, rnd;
-
- // api to topoForce
- var api;
- /*
- projection()
- network {...}
- restyleLinkElement( ldata )
- removeLinkElement( ldata )
- */
-
- // shorthand
- var lu, rlk, nodes, links, linksByDevice;
-
- var dim; // dimensions of layout [w,h]
-
- // configuration 'constants'
- var defaultLinkType = 'direct',
- nearDist = 15;
-
-
- function coordFromLngLat(loc) {
- var p = api.projection();
- // suspected cause of ONOS-2109
- return p ? p([loc.lng, loc.lat]) : [0, 0];
- }
-
- function lngLatFromCoord(coord) {
- var p = api.projection();
- return p ? p.invert(coord) : [0, 0];
- }
-
- function positionNode(node, forUpdate) {
- var meta = node.metaUi,
- x = meta && meta.x,
- y = meta && meta.y,
- xy;
-
- // If we have [x,y] already, use that...
- if (x && y) {
- node.fixed = true;
- node.px = node.x = x;
- node.py = node.y = y;
- return;
- }
-
- var location = node.location,
- coord;
-
- if (location && location.type === 'latlng') {
- coord = coordFromLngLat(location);
- node.fixed = true;
- node.px = node.x = coord[0];
- node.py = node.y = coord[1];
- return true;
- }
-
- // if this is a node update (not a node add).. skip randomizer
- if (forUpdate) {
- return;
- }
-
- // Note: Placing incoming unpinned nodes at exactly the same point
- // (center of the view) causes them to explode outwards when
- // the force layout kicks in. So, we spread them out a bit
- // initially, to provide a more serene layout convergence.
- // Additionally, if the node is a host, we place it near
- // the device it is connected to.
-
- function rand() {
- return {
- x: rnd.randDim(dim[0]),
- y: rnd.randDim(dim[1])
- };
- }
-
- function near(node) {
- return {
- x: node.x + nearDist + rnd.spread(nearDist),
- y: node.y + nearDist + rnd.spread(nearDist)
- };
- }
-
- function getDevice(cp) {
- var d = lu[cp.device];
- return d || rand();
- }
-
- xy = (node.class === 'host') ? near(getDevice(node.cp)) : rand();
- angular.extend(node, xy);
- }
-
- function mkSvgCls(dh, t, on) {
- var ndh = 'node ' + dh,
- ndht = t ? ndh + ' ' + t : ndh;
- return on ? ndht + ' online' : ndht;
- }
-
- function createDeviceNode(device) {
- var node = device;
-
- // Augment as needed...
- node.class = 'device';
- node.svgClass = mkSvgCls('device', device.type, device.online);
- positionNode(node);
- return node;
- }
-
- function createHostNode(host) {
- var node = host;
-
- // Augment as needed...
- node.class = 'host';
- if (!node.type) {
- node.type = 'endstation';
- }
- node.svgClass = mkSvgCls('host', node.type);
- positionNode(node);
- return node;
- }
-
- function createHostLink(host) {
- var src = host.id,
- dst = host.cp.device,
- id = host.ingress,
- lnk = linkEndPoints(src, dst);
-
- if (!lnk) {
- return null;
- }
-
- // Synthesize link ...
- angular.extend(lnk, {
- key: id,
- class: 'link',
- // NOTE: srcPort left undefined (host end of the link)
- tgtPort: host.cp.port,
-
- type: function () { return 'hostLink'; },
- online: function () {
- // hostlink target is edge switch
- return lnk.target.online;
- },
- linkWidth: function () { return 1; }
- });
- return lnk;
- }
-
- function createLink(link) {
- var lnk = linkEndPoints(link.src, link.dst);
-
- if (!lnk) {
- return null;
- }
-
- angular.extend(lnk, {
- key: link.id,
- class: 'link',
- fromSource: link,
- srcPort: link.srcPort,
- tgtPort: link.dstPort,
- position: {
- x1: 0,
- y1: 0,
- x2: 0,
- y2: 0
- },
-
- // functions to aggregate dual link state
- type: function () {
- var s = lnk.fromSource,
- t = lnk.fromTarget;
- return (s && s.type) || (t && t.type) || defaultLinkType;
- },
- online: function () {
- var s = lnk.fromSource,
- t = lnk.fromTarget,
- both = lnk.source.online && lnk.target.online;
- return both && ((s && s.online) || (t && t.online));
- },
- linkWidth: function () {
- var s = lnk.fromSource,
- t = lnk.fromTarget,
- ws = (s && s.linkWidth) || 0,
- wt = (t && t.linkWidth) || 0;
- return lnk.position.multiLink ? 5 : Math.max(ws, wt);
- }
- });
- return lnk;
- }
-
-
- function linkEndPoints(srcId, dstId) {
- var srcNode = lu[srcId],
- dstNode = lu[dstId],
- sMiss = !srcNode ? missMsg('src', srcId) : '',
- dMiss = !dstNode ? missMsg('dst', dstId) : '';
-
- if (sMiss || dMiss) {
- $log.error('Node(s) not on map for link:' + sMiss + dMiss);
- //logicError('Node(s) not on map for link:\n' + sMiss + dMiss);
- return null;
- }
- return {
- source: srcNode,
- target: dstNode
- };
- }
-
- function missMsg(what, id) {
- return '\n[' + what + '] "' + id + '" missing';
- }
-
-
- function makeNodeKey(d, what) {
- var port = what + 'Port';
- return d[what] + '/' + d[port];
- }
-
- function makeLinkKey(d, flipped) {
- var one = flipped ? makeNodeKey(d, 'dst') : makeNodeKey(d, 'src'),
- two = flipped ? makeNodeKey(d, 'src') : makeNodeKey(d, 'dst');
- return one + '-' + two;
- }
-
- function findLinkById(id) {
- // check to see if this is a reverse lookup, else default to given id
- var key = rlk[id] || id;
- return key && lu[key];
- }
-
- function findLink(linkData, op) {
- var key = makeLinkKey(linkData),
- keyrev = makeLinkKey(linkData, 1),
- link = lu[key],
- linkRev = lu[keyrev],
- result = {},
- ldata = link || linkRev,
- rawLink;
-
- if (op === 'add') {
- if (link) {
- // trying to add a link that we already know about
- result.ldata = link;
- result.badLogic = 'addLink: link already added';
-
- } else if (linkRev) {
- // we found the reverse of the link to be added
- result.ldata = linkRev;
- if (linkRev.fromTarget) {
- result.badLogic = 'addLink: link already added';
- }
- }
- } else if (op === 'update') {
- if (!ldata) {
- result.badLogic = 'updateLink: link not found';
- } else {
- rawLink = link ? ldata.fromSource : ldata.fromTarget;
- result.updateWith = function (data) {
- angular.extend(rawLink, data);
- api.restyleLinkElement(ldata);
- }
- }
- } else if (op === 'remove') {
- if (!ldata) {
- result.badLogic = 'removeLink: link not found';
- } else {
- rawLink = link ? ldata.fromSource : ldata.fromTarget;
-
- if (!rawLink) {
- result.badLogic = 'removeLink: link not found';
-
- } else {
- result.removeRawLink = function () {
- // remove link out of aggregate linksByDevice list
- var linksForDevPair = linksByDevice[ldata.devicePair],
- rmvIdx = fs.find(ldata.key, linksForDevPair, 'key');
- if (rmvIdx >= 0) {
- linksForDevPair.splice(rmvIdx, 1);
- }
- ldata.position.multilink = linksForDevPair.length >= 5;
-
- if (link) {
- // remove fromSource
- ldata.fromSource = null;
- if (ldata.fromTarget) {
- // promote target into source position
- ldata.fromSource = ldata.fromTarget;
- ldata.fromTarget = null;
- ldata.key = keyrev;
- delete lu[key];
- lu[keyrev] = ldata;
- delete rlk[keyrev];
- }
- } else {
- // remove fromTarget
- ldata.fromTarget = null;
- delete rlk[keyrev];
- }
- if (ldata.fromSource) {
- api.restyleLinkElement(ldata);
- } else {
- api.removeLinkElement(ldata);
- }
- }
- }
- }
- }
- return result;
- }
-
- function findDevices(offlineOnly) {
- var a = [];
- nodes.forEach(function (d) {
- if (d.class === 'device' && !(offlineOnly && d.online)) {
- a.push(d);
- }
- });
- return a;
- }
-
- function findAttachedHosts(devId) {
- var hosts = [];
- nodes.forEach(function (d) {
- if (d.class === 'host' && d.cp.device === devId) {
- hosts.push(d);
- }
- });
- return hosts;
- }
-
- function findAttachedLinks(devId) {
- var lnks = [];
- links.forEach(function (d) {
- if (d.source.id === devId || d.target.id === devId) {
- lnks.push(d);
- }
- });
- return lnks;
- }
-
- // returns one-way links or where the internal link types differ
- function findBadLinks() {
- var lnks = [],
- src, tgt;
- links.forEach(function (d) {
- // NOTE: skip edge links, which are synthesized
- if (d.type() !== 'hostLink') {
- delete d.bad;
- src = d.fromSource;
- tgt = d.fromTarget;
- if (src && !tgt) {
- d.bad = 'missing link';
- } else if (src.type !== tgt.type) {
- d.bad = 'type mismatch';
- }
- if (d.bad) {
- lnks.push(d);
- }
- }
- });
- return lnks;
- }
-
- // ==========================
- // Module definition
-
- angular.module('ovTopo')
- .factory('TopoModelService',
- ['$log', 'FnService', 'RandomService',
-
- function (_$log_, _fs_, _rnd_) {
- $log = _$log_;
- fs = _fs_;
- rnd = _rnd_;
-
- function initModel(_api_, _dim_) {
- api = _api_;
- dim = _dim_;
- lu = api.network.lookup;
- rlk = api.network.revLinkToKey;
- nodes = api.network.nodes;
- links = api.network.links;
- linksByDevice = api.network.linksByDevice;
- }
-
- function newDim(_dim_) {
- dim = _dim_;
- }
-
- function destroyModel() { }
-
- return {
- initModel: initModel,
- newDim: newDim,
- destroyModel: destroyModel,
-
- positionNode: positionNode,
- createDeviceNode: createDeviceNode,
- createHostNode: createHostNode,
- createHostLink: createHostLink,
- createLink: createLink,
- coordFromLngLat: coordFromLngLat,
- lngLatFromCoord: lngLatFromCoord,
- findLink: findLink,
- findLinkById: findLinkById,
- findDevices: findDevices,
- findAttachedHosts: findAttachedHosts,
- findAttachedLinks: findAttachedLinks,
- findBadLinks: findBadLinks
- }
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoOblique.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoOblique.js
deleted file mode 100644
index e84b1173..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoOblique.js
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Oblique View Module.
- Provides functionality to view the topology as two planes (packet & optical)
- from an oblique (side-on) perspective.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, fs, sus, flash;
-
- // api to topoForce
- var api;
- /*
- force() // get ref to force layout object
- zoomLayer() // get ref to zoom layer
- nodeGBBox() // get bounding box of node group layer
- node() // get ref to D3 selection of nodes
- link() // get ref to D3 selection of links
- nodes() // get ref to network nodes array
- tickStuff // ref to tick functions
- nodeLock(b) // test-and-set nodeLock state
- opacifyMap(b) // show or hide map layer
- inLayer(d, layer) // return true if d in layer {'pkt'|'opt'}
- calcLinkPos() // recomputes link pos based on node data
- */
-
- // configuration
- var xsky = -.7, // x skew y factor
- xsk = -35, // x skew angle
- ysc = .5, // y scale
- pad = 50,
- time = 1500,
- fill = {
- pkt: 'rgba(130,130,170,0.3)', // blue-ish
- opt: 'rgba(170,130,170,0.3)' // magenta-ish
- };
-
- // internal state
- var oblique = false,
- xffn = null,
- plane = {},
- oldNodeLock;
-
-
- function planeId(tag) {
- return 'topo-obview-' + tag + 'Plane';
- }
-
- function ytfn(h, dir) {
- return h * ysc * dir * 1.1;
- }
-
- function obXform(h, dir) {
- var yt = ytfn(h, dir);
- return sus.scale(1, ysc) + sus.translate(0, yt) + sus.skewX(xsk);
- }
-
- function noXform() {
- return sus.skewX(0) + sus.translate(0,0) + sus.scale(1,1);
- }
-
- function padBox(box, p) {
- box.x -= p;
- box.y -= p;
- box.width += p*2;
- box.height += p*2;
- }
-
- function toObliqueView() {
- var box = api.nodeGBBox(),
- ox, oy;
-
- padBox(box, pad);
-
- ox = box.x + box.width / 2;
- oy = box.y + box.height / 2;
-
- // remember node lock state, then lock the nodes down
- oldNodeLock = api.nodeLock(true);
- api.opacifyMap(false);
-
- insertPlanes(ox, oy);
-
- xffn = function (xy, dir) {
- var yt = ytfn(box.height, dir),
- ax = xy.x - ox,
- ay = xy.y - oy,
- x = ax + ay * xsky,
- y = (ay + yt) * ysc;
- return {x: ox + x, y: oy + y};
- };
-
- showPlane('pkt', box, -1);
- showPlane('opt', box, 1);
- obTransitionNodes();
- }
-
- function toNormalView() {
- xffn = null;
-
- hidePlane('pkt');
- hidePlane('opt');
- obTransitionNodes();
-
- removePlanes();
-
- // restore node lock state
- api.nodeLock(oldNodeLock);
- api.opacifyMap(true);
- }
-
- function obTransitionNodes() {
- // return the direction for the node
- // -1 for pkt layer, 1 for optical layer
- function dir(d) {
- return api.inLayer(d, 'pkt') ? -1 : 1;
- }
-
- if (xffn) {
- api.nodes().forEach(function (d) {
- var oldxy = {x: d.x, y: d.y},
- coords = xffn(oldxy, dir(d));
- d.oldxy = oldxy;
- d.px = d.x = coords.x;
- d.py = d.y = coords.y;
- });
- } else {
- api.nodes().forEach(function (d) {
- var old = d.oldxy || {x: d.x, y: d.y};
- d.px = d.x = old.x;
- d.py = d.y = old.y;
- delete d.oldxy;
- });
- }
-
- api.node().transition()
- .duration(time)
- .attr(api.tickStuff.nodeAttr);
- api.link().transition()
- .duration(time)
- .call(api.calcLinkPos)
- .attr(api.tickStuff.linkAttr)
- .call(api.applyNumLinkLabels);
- api.linkLabel().transition()
- .duration(time)
- .attr(api.tickStuff.linkLabelAttr);
- }
-
- function showPlane(tag, box, dir) {
- // set box origin at center..
- box.x = -box.width/2;
- box.y = -box.height/2;
-
- plane[tag].select('rect')
- .attr(box)
- .attr('opacity', 0)
- .transition()
- .duration(time)
- .attr('opacity', 1)
- .attr('transform', obXform(box.height, dir));
- }
-
- function hidePlane(tag) {
- plane[tag].select('rect')
- .transition()
- .duration(time)
- .attr('opacity', 0)
- .attr('transform', noXform());
- }
-
- function insertPlanes(ox, oy) {
- function ins(tag) {
- var id = planeId(tag),
- g = api.zoomLayer().insert('g', '#topo-G')
- .attr('id', id)
- .attr('transform', sus.translate(ox,oy));
- g.append('rect')
- .attr('fill', fill[tag])
- .attr('opacity', 0);
- plane[tag] = g;
- }
- ins('opt');
- ins('pkt');
- }
-
- function removePlanes() {
- function rem(tag) {
- var id = planeId(tag);
- api.zoomLayer().select('#'+id)
- .transition()
- .duration(time + 50)
- .remove();
- delete plane[tag];
- }
- rem('opt');
- rem('pkt');
- }
-
-
-// === -----------------------------------------------------
-// === MODULE DEFINITION ===
-
-angular.module('ovTopo')
- .factory('TopoObliqueService',
- ['$log', 'FnService', 'SvgUtilService', 'FlashService',
-
- function (_$log_, _fs_, _sus_, _flash_) {
- $log = _$log_;
- fs = _fs_;
- sus = _sus_;
- flash = _flash_;
-
- function initOblique(_api_) {
- api = _api_;
- }
-
- function destroyOblique() { }
-
- function toggleOblique() {
- oblique = !oblique;
- if (oblique) {
- api.force().stop();
- flash.flash('Oblique view');
- toObliqueView();
- } else {
- flash.flash('Normal view');
- toNormalView();
- }
- }
-
- return {
- initOblique: initOblique,
- destroyOblique: destroyOblique,
-
- isOblique: function () { return oblique; },
- toggleOblique: toggleOblique
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoOverlay.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoOverlay.js
deleted file mode 100644
index fb7921ad..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoOverlay.js
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Overlay Module.
-
- Provides overlay capabilities, allowing ONOS apps to provide additional
- custom data/behavior for the topology view.
-
- */
-
-(function () {
- 'use strict';
-
- // constants
- var tos = 'TopoOverlayService: ';
-
- // injected refs
- var $log, fs, gs, wss, ns, tss, tps, api;
-
- // internal state
- var overlays = {},
- current = null,
- reset = true;
-
- function error(fn, msg) {
- $log.error(tos + fn + '(): ' + msg);
- }
-
- function warn(fn, msg) {
- $log.warn(tos + fn + '(): ' + msg);
- }
-
- function mkGlyphId(oid, gid) {
- return (gid[0] === '*') ? oid + '-' + gid.slice(1) : gid;
- }
-
- function handleGlyphs(o) {
- var gdata = fs.isO(o.glyphs),
- oid = o.overlayId,
- gid = o.glyphId || 'unknown',
- data = {},
- note = [];
-
- o._glyphId = mkGlyphId(oid, gid);
-
- o.mkGid = function (g) {
- return mkGlyphId(oid, g);
- };
- o.mkId = function (s) {
- return oid + '-' + s;
- };
-
- // process glyphs if defined
- if (gdata) {
- angular.forEach(gdata, function (value, key) {
- var fullkey = oid + '-' + key;
- data['_' + fullkey] = value.vb;
- data[fullkey] = value.d;
- note.push('*' + key);
- });
- gs.registerGlyphs(data);
- $log.debug('registered overlay glyphs:', oid, note);
- }
- }
-
- function register(overlay) {
- var r = 'register',
- over = fs.isO(overlay),
- kb = over ? fs.isO(overlay.keyBindings) : null,
- id = over ? over.overlayId : '';
-
- if (!id) {
- return error(r, 'not a recognized overlay');
- }
- if (overlays[id]) {
- return warn(r, 'already registered: "' + id + '"');
- }
- overlays[id] = overlay;
- handleGlyphs(overlay);
-
- if (kb) {
- if (!fs.isA(kb._keyOrder)) {
- warn(r, 'no _keyOrder array defined on keyBindings');
- } else {
- kb._keyOrder.forEach(function (k) {
- if (k !== '-' && !kb[k]) {
- warn(r, 'no "' + k + '" property defined on keyBindings');
- }
- });
- }
- }
-
- $log.debug(tos + 'registered overlay: ' + id, overlay);
- }
-
- // returns the list of overlay identifiers
- function list() {
- return d3.map(overlays).keys();
- }
-
- // add a radio button for each registered overlay
- // return an overlay id to index map
- function augmentRbset(rset, switchFn) {
- var map = {},
- idx = 1;
-
- angular.forEach(overlays, function (ov) {
- rset.push({
- gid: ov._glyphId,
- tooltip: (ov.tooltip || '(no tooltip)'),
- cb: function () {
- tbSelection(ov.overlayId, switchFn);
- }
- });
- map[ov.overlayId] = idx++;
- });
- return map;
- }
-
- // an overlay was selected via toolbar radio button press from user
- function tbSelection(id, switchFn) {
- var same = current && current.overlayId === id,
- payload = {},
- actions;
-
- function doop(op) {
- var oid = current.overlayId;
- $log.debug('Overlay:', op, oid);
- current[op]();
- payload[op] = oid;
- }
-
- if (reset || !same) {
- reset = false;
- current && doop('deactivate');
- current = overlays[id];
- current && doop('activate');
- actions = current && fs.isO(current.keyBindings);
- switchFn(id, actions);
-
- wss.sendEvent('topoSelectOverlay', payload);
-
- // Ensure summary and details panels are updated immediately..
- wss.sendEvent('requestSummary');
- tss.updateDetail();
- }
- }
-
- var coreButtons = {
- showDeviceView: {
- gid: 'switch',
- tt: 'Show Device View',
- path: 'device'
- },
- showFlowView: {
- gid: 'flowTable',
- tt: 'Show Flow View for this Device',
- path: 'flow'
- },
- showPortView: {
- gid: 'portTable',
- tt: 'Show Port View for this Device',
- path: 'port'
- },
- showGroupView: {
- gid: 'groupTable',
- tt: 'Show Group View for this Device',
- path: 'group'
- }
- };
-
- // retrieves a button definition from the current overlay and generates
- // a button descriptor to be added to the panel, with the data baked in
- function _getButtonDef(id, data) {
- var btns = current && current.buttons,
- b = btns && btns[id],
- cb = fs.isF(b.cb),
- f = cb ? function () { cb(data); } : function () {};
-
- return b ? {
- id: current.mkId(id),
- gid: current.mkGid(b.gid),
- tt: b.tt,
- cb: f
- } : null;
- }
-
- // install core buttons, and include any additional from the current overlay
- function installButtons(buttons, data, devId) {
- buttons.forEach(function (id) {
- var btn = coreButtons[id],
- gid = btn && btn.gid,
- tt = btn && btn.tt,
- path = btn && btn.path;
-
- if (btn) {
- tps.addAction({
- id: 'core-' + id,
- gid: gid,
- tt: tt,
- cb: function () { ns.navTo(path, {devId: devId }); }
- });
- } else if (btn = _getButtonDef(id, data)) {
- tps.addAction(btn);
- }
- });
- }
-
- function addDetailButton(id) {
- var b = _getButtonDef(id);
- if (b) {
- tps.addAction({
- id: current.mkId(id),
- gid: current.mkGid(b.gid),
- cb: b.cb,
- tt: b.tt
- });
- }
- }
-
-
- // === -----------------------------------------------------
- // Hooks for overlays
-
- function _hook(x) {
- var h = current && current.hooks;
- return h && fs.isF(h[x]);
- }
-
- function escapeHook() {
- var eh = _hook('escape');
- return eh ? eh() : false;
- }
-
- function emptySelectHook() {
- var cb = _hook('empty');
- cb && cb();
- }
-
- function singleSelectHook(data) {
- var cb = _hook('single');
- cb && cb(data);
- }
-
- function multiSelectHook(selectOrder) {
- var cb = _hook('multi');
- cb && cb(selectOrder);
- }
-
- function mouseOverHook(what) {
- var cb = _hook('mouseover');
- cb && cb(what);
- }
-
- function mouseOutHook() {
- var cb = _hook('mouseout');
- cb && cb();
- }
-
- // === -----------------------------------------------------
- // Event (from server) Handlers
-
- function setApi(_api_, _tss_) {
- api = _api_;
- tss = _tss_;
- }
-
- function showHighlights(data) {
- var less;
-
- /*
- API to topoForce
- clearLinkTrafficStyle()
- removeLinkLabels()
- findLinkById( id )
- findNodeById( id )
- updateLinks()
- updateNodes()
- supLayers( bool, [less] )
- unsupNode( id, [less] )
- unsupLink( key, [less] )
- */
-
- api.clearNodeDeco();
- api.removeNodeBadges();
- api.clearLinkTrafficStyle();
- api.removeLinkLabels();
-
- // handle element suppression
- if (data.subdue) {
- less = data.subdue === 'min';
- api.supLayers(true, less);
-
- } else {
- api.supLayers(false);
- api.supLayers(false, true);
- }
-
- data.hosts.forEach(function (host) {
- var hdata = api.findNodeById(host.id),
- badgeData = host.badge || null;
-
- if (hdata && !hdata.el.empty()) {
- hdata.badge = badgeData;
- if (!host.subdue) {
- api.unsupNode(hdata.id, less);
- }
- // TODO: further highlighting?
- }
- });
-
- data.devices.forEach(function (device) {
- var ddata = api.findNodeById(device.id),
- badgeData = device.badge || null;
-
- if (ddata && !ddata.el.empty()) {
- ddata.badge = badgeData;
- if (!device.subdue) {
- api.unsupNode(ddata.id, less);
- }
- // TODO: further highlighting?
- }
- });
-
- data.links.forEach(function (link) {
- var ldata = api.findLinkById(link.id),
- lab = link.label,
- units, portcls, magnitude;
-
- if (ldata && !ldata.el.empty()) {
- if (!link.subdue) {
- api.unsupLink(ldata.key, less);
- }
- ldata.el.classed(link.css, true);
- ldata.label = lab;
-
- // TODO: this needs to be pulled out into traffic overlay
- // inject additional styling for port-based traffic
- if (fs.endsWith(lab, 'bps')) {
- units = lab.substring(lab.length-4);
- portcls = 'port-traffic-' + units;
-
- // for GBps
- if (units.substring(0,1) === 'G') {
- magnitude = fs.parseBitRate(lab);
- if (magnitude >= 9) {
- portcls += '-choked'
- }
- }
- ldata.el.classed(portcls, true);
- }
- }
- });
-
- api.updateNodes();
- api.updateLinks();
- }
-
- // ========================================================================
-
- angular.module('ovTopo')
- .factory('TopoOverlayService',
- ['$log', 'FnService', 'GlyphService', 'WebSocketService', 'NavService',
- 'TopoPanelService',
-
- function (_$log_, _fs_, _gs_, _wss_, _ns_, _tps_) {
- $log = _$log_;
- fs = _fs_;
- gs = _gs_;
- wss = _wss_;
- ns = _ns_;
- tps = _tps_;
-
- return {
- register: register,
- setApi: setApi,
- list: list,
- augmentRbset: augmentRbset,
- mkGlyphId: mkGlyphId,
- tbSelection: tbSelection,
- installButtons: installButtons,
- addDetailButton: addDetailButton,
- resetOnToolbarDestroy: function () { reset = true; },
- hooks: {
- escape: escapeHook,
- emptySelect: emptySelectHook,
- singleSelect: singleSelectHook,
- multiSelect: multiSelectHook,
- mouseOver: mouseOverHook,
- mouseOut: mouseOutHook
- },
-
- showHighlights: showHighlights
- }
- }]);
-
-}()); \ No newline at end of file
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoPanel.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoPanel.js
deleted file mode 100644
index 1b8c2192..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoPanel.js
+++ /dev/null
@@ -1,539 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Panel Module.
- Defines functions for manipulating the summary, detail, and instance panels.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, $window, $rootScope, fs, ps, gs, flash, wss, bns, mast, ns;
-
- // constants
- var pCls = 'topo-p',
- idSum = 'topo-p-summary',
- idDet = 'topo-p-detail',
- panelOpts = {
- width: 260
- },
- sumMax = 262,
- padTop = 20,
- devPath = 'device';
-
- // internal state
- var useDetails = true, // should we show details if we have 'em?
- haveDetails = false, // do we have details that we could show?
- sumFromTop, // summary panel distance from top of screen
- unbindWatch;
-
- // panels
- var summary, detail;
-
- // === -----------------------------------------------------
- // Panel API
- function createTopoPanel(id, opts) {
- var p = ps.createPanel(id, opts),
- pid = id,
- header, body, footer;
- p.classed(pCls, true);
-
- function panel() {
- return p;
- }
-
- function hAppend(x) {
- return header.append(x);
- }
-
- function bAppend(x) {
- return body.append(x);
- }
-
- function fAppend(x) {
- return footer.append(x);
- }
-
- function setup() {
- p.empty();
-
- p.append('div').classed('header', true);
- p.append('div').classed('body', true);
- p.append('div').classed('footer', true);
-
- header = p.el().select('.header');
- body = p.el().select('.body');
- footer = p.el().select('.footer');
- }
-
- function destroy() {
- ps.destroyPanel(pid);
- }
-
- // fromTop is how many pixels from the top of the page the panel is
- // max is the max height of the panel in pixels
- // only adjusts if the body content would be 10px or larger
- function adjustHeight(fromTop, max) {
- var totalPHeight, avSpace,
- overflow = 0,
- pdg = 30;
-
- if (!fromTop) {
- $log.warn('adjustHeight: height from top of page not given');
- return null;
- } else if (!body || !p) {
- $log.warn('adjustHeight: panel contents are not defined');
- return null;
- }
-
- p.el().style('height', null);
- body.style('height', null);
-
- totalPHeight = fromTop + p.height();
- avSpace = fs.windowSize(pdg).height;
-
- if (totalPHeight >= avSpace) {
- overflow = totalPHeight - avSpace;
- }
-
- function _adjustBody(height) {
- if (height < 10) {
- return false;
- } else {
- body.style('height', height + 'px');
- }
- return true;
- }
-
- if (!_adjustBody(fs.noPxStyle(body, 'height') - overflow)) {
- return;
- }
-
- if (max && p.height() > max) {
- _adjustBody(fs.noPxStyle(body, 'height') - (p.height() - max));
- }
- }
-
- return {
- panel: panel,
- setup: setup,
- destroy: destroy,
- appendHeader: hAppend,
- appendBody: bAppend,
- appendFooter: fAppend,
- adjustHeight: adjustHeight
- };
- }
-
- // === -----------------------------------------------------
- // Utility functions
-
- function addSep(tbody) {
- tbody.append('tr').append('td').attr('colspan', 2).append('hr');
- }
-
- function addBtnFooter() {
- detail.appendFooter('hr');
- detail.appendFooter('div').classed('actionBtns', true);
- }
-
- function addProp(tbody, label, value) {
- var tr = tbody.append('tr'),
- lab;
- if (typeof label === 'string') {
- lab = label.replace(/_/g, ' ');
- } else {
- lab = label;
- }
-
- function addCell(cls, txt) {
- tr.append('td').attr('class', cls).html(txt);
- }
- addCell('label', lab + ' :');
- addCell('value', value);
- }
-
- function listProps(tbody, data) {
- data.propOrder.forEach(function (p) {
- if (p === '-') {
- addSep(tbody);
- } else {
- addProp(tbody, p, data.props[p]);
- }
- });
- }
-
- function watchWindow() {
- unbindWatch = $rootScope.$watchCollection(
- function () {
- return {
- h: $window.innerHeight,
- w: $window.innerWidth
- };
- }, function () {
- summary.adjustHeight(sumFromTop, sumMax);
- detail.adjustHeight(detail.ypos.current);
- }
- );
- }
-
- // === -----------------------------------------------------
- // Functions for populating the summary panel
-
- function populateSummary(data) {
- summary.setup();
-
- var svg = summary.appendHeader('div')
- .classed('icon', true)
- .append('svg'),
- title = summary.appendHeader('h2'),
- table = summary.appendBody('table'),
- tbody = table.append('tbody'),
- glyphId = data.type || 'node';
-
- gs.addGlyph(svg, glyphId, 40);
-
- if (glyphId === 'node') {
- gs.addGlyph(svg, 'bird', 24, true, [8,12]);
- }
-
- title.text(data.title);
- listProps(tbody, data);
- }
-
- // === -----------------------------------------------------
- // Functions for populating the detail panel
-
- var isDevice = {
- switch: 1,
- roadm: 1
- };
-
- function displaySingle(data) {
- detail.setup();
-
- var svg = detail.appendHeader('div')
- .classed('icon clickable', true)
- .append('svg'),
- title = detail.appendHeader('h2')
- .classed('clickable', true),
- table = detail.appendBody('table'),
- tbody = table.append('tbody'),
- navFn;
-
- gs.addGlyph(svg, (data.type || 'unknown'), 40);
- title.text(data.title);
-
- // only add navigation when displaying a device
- if (isDevice[data.type]) {
- navFn = function () {
- ns.navTo(devPath, { devId: data.id });
- };
-
- svg.on('click', navFn);
- title.on('click', navFn);
- }
-
- listProps(tbody, data);
- addBtnFooter();
- }
-
- function displayMulti(ids) {
- detail.setup();
-
- var title = detail.appendHeader('h3'),
- table = detail.appendBody('table'),
- tbody = table.append('tbody');
-
- title.text('Selected Nodes');
- ids.forEach(function (d, i) {
- addProp(tbody, i+1, d);
- });
- addBtnFooter();
- }
-
- function addAction(o) {
- var btnDiv = d3.select('#' + idDet)
- .select('.actionBtns')
- .append('div')
- .classed('actionBtn', true);
- bns.button(btnDiv, idDet + '-' + o.id, o.gid, o.cb, o.tt);
- }
-
- var friendlyIndex = {
- device: 1,
- host: 0
- };
-
- function friendly(d) {
- var i = friendlyIndex[d.class] || 0;
- return (d.labels && d.labels[i]) || '';
- }
-
- function linkSummary(d) {
- var o = d && d.online ? 'online' : 'offline';
- return d ? d.type + ' / ' + o : '-';
- }
-
- // provided to change presentation of internal type name
- var linkTypePres = {
- hostLink: 'edge link'
- };
-
- function linkType(d) {
- return linkTypePres[d.type()] || d.type();
- }
-
- var coreOrder = [
- 'Type', '-',
- 'A_type', 'A_id', 'A_label', 'A_port', '-',
- 'B_type', 'B_id', 'B_label', 'B_port', '-'
- ],
- edgeOrder = [
- 'Type', '-',
- 'A_type', 'A_id', 'A_label', '-',
- 'B_type', 'B_id', 'B_label', 'B_port'
- ];
-
- function displayLink(data) {
- detail.setup();
-
- var svg = detail.appendHeader('div')
- .classed('icon', true)
- .append('svg'),
- title = detail.appendHeader('h2'),
- table = detail.appendBody('table'),
- tbody = table.append('tbody'),
- edgeLink = data.type() === 'hostLink',
- order = edgeLink ? edgeOrder : coreOrder;
-
- gs.addGlyph(svg, 'ports', 40);
- title.text('Link');
-
-
- listProps(tbody, {
- propOrder: order,
- props: {
- Type: linkType(data),
-
- A_type: data.source.class,
- A_id: data.source.id,
- A_label: friendly(data.source),
- A_port: data.srcPort,
-
- B_type: data.target.class,
- B_id: data.target.id,
- B_label: friendly(data.target),
- B_port: data.tgtPort
- }
- });
-
- if (!edgeLink) {
- addProp(tbody, 'A &rarr; B', linkSummary(data.fromSource));
- addProp(tbody, 'B &rarr; A', linkSummary(data.fromTarget));
- }
- }
-
- function displayNothing() {
- haveDetails = false;
- hideDetailPanel();
- }
-
- function displaySomething() {
- haveDetails = true;
- if (useDetails) {
- showDetailPanel();
- }
- }
-
- // === -----------------------------------------------------
- // Event Handlers
-
- function showSummary(data) {
- populateSummary(data);
- showSummaryPanel();
- }
-
- function toggleSummary(x) {
- var kev = (x === 'keyev'),
- on = kev ? !summary.panel().isVisible() : !!x,
- verb = on ? 'Show' : 'Hide';
-
- if (on) {
- // ask server to start sending summary data.
- wss.sendEvent('requestSummary');
- // note: the summary panel will appear, once data arrives
- } else {
- hideSummaryPanel();
- }
- flash.flash(verb + ' summary panel');
- return on;
- }
-
- // === -----------------------------------------------------
- // === LOGIC For showing/hiding summary and detail panels...
-
- function showSummaryPanel() {
- function _show() {
- summary.panel().show();
- summary.adjustHeight(sumFromTop, sumMax);
- }
- if (detail.panel().isVisible()) {
- detail.down(_show);
- } else {
- _show();
- }
- }
-
- function hideSummaryPanel() {
- // instruct server to stop sending summary data
- wss.sendEvent("cancelSummary");
- summary.panel().hide(detail.up);
- }
-
- function showDetailPanel() {
- if (summary.panel().isVisible()) {
- detail.down(detail.panel().show);
- } else {
- detail.up(detail.panel().show);
- }
- }
-
- function hideDetailPanel() {
- detail.panel().hide();
- }
-
- // ==========================
-
- function augmentDetailPanel() {
- var d = detail,
- downPos = sumFromTop + sumMax + 20;
- d.ypos = { up: sumFromTop, down: downPos, current: downPos};
-
- d._move = function (y, cb) {
- var yp = d.ypos,
- endCb;
-
- if (fs.isF(cb)) {
- endCb = function () {
- cb();
- d.adjustHeight(d.ypos.current);
- }
- } else {
- endCb = function () {
- d.adjustHeight(d.ypos.current);
- }
- }
- if (yp.current !== y) {
- yp.current = y;
- d.panel().el().transition().duration(300)
- .each('end', endCb)
- .style('top', yp.current + 'px');
- } else {
- endCb();
- }
- };
-
- d.down = function (cb) { d._move(d.ypos.down, cb); };
- d.up = function (cb) { d._move(d.ypos.up, cb); };
- }
-
- function toggleUseDetailsFlag(x) {
- var kev = (x === 'keyev'),
- verb;
-
- useDetails = kev ? !useDetails : !!x;
- verb = useDetails ? 'Enable' : 'Disable';
-
- if (useDetails) {
- if (haveDetails) {
- showDetailPanel();
- }
- } else {
- hideDetailPanel();
- }
- flash.flash(verb + ' details panel');
- return useDetails;
- }
-
- // ==========================
-
- function initPanels() {
- sumFromTop = mast.mastHeight() + padTop;
- summary = createTopoPanel(idSum, panelOpts);
- detail = createTopoPanel(idDet, panelOpts);
-
- augmentDetailPanel();
- watchWindow();
- }
-
- function destroyPanels() {
- summary.destroy();
- summary = null;
-
- detail.destroy();
- detail = null;
- haveDetails = false;
- unbindWatch();
- }
-
- // ==========================
-
- angular.module('ovTopo')
- .factory('TopoPanelService',
- ['$log', '$window', '$rootScope', 'FnService', 'PanelService', 'GlyphService',
- 'FlashService', 'WebSocketService', 'ButtonService', 'MastService',
- 'NavService',
-
- function (_$log_, _$window_, _$rootScope_,
- _fs_, _ps_, _gs_, _flash_, _wss_, _bns_, _mast_, _ns_) {
- $log = _$log_;
- $window = _$window_;
- $rootScope = _$rootScope_;
- fs = _fs_;
- ps = _ps_;
- gs = _gs_;
- flash = _flash_;
- wss = _wss_;
- bns = _bns_;
- mast = _mast_;
- ns = _ns_;
-
- return {
- initPanels: initPanels,
- destroyPanels: destroyPanels,
- createTopoPanel: createTopoPanel,
-
- showSummary: showSummary,
- toggleSummary: toggleSummary,
-
- toggleUseDetailsFlag: toggleUseDetailsFlag,
- displaySingle: displaySingle,
- displayMulti: displayMulti,
- displayLink: displayLink,
- displayNothing: displayNothing,
- displaySomething: displaySomething,
- addAction: addAction,
-
- hideSummaryPanel: hideSummaryPanel,
-
- detailVisible: function () { return detail.panel().isVisible(); },
- summaryVisible: function () { return summary.panel().isVisible(); }
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoSelect.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoSelect.js
deleted file mode 100644
index 4ad76903..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoSelect.js
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Selection Module.
- Defines behavior when selecting nodes.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, fs, wss, tov, tps, tts, ns;
-
- // api to topoForce
- var api;
- /*
- node() // get ref to D3 selection of nodes
- zoomingOrPanning( ev )
- updateDeviceColors( [dev] )
- deselectLink()
- */
-
- // internal state
- var hovered, // the node over which the mouse is hovering
- selections = {}, // currently selected nodes (by id)
- selectOrder = [], // the order in which we made selections
- consumeClick = false; // used to coordinate with SVG click handler
-
- // ==========================
-
- function nSel() {
- return selectOrder.length;
- }
- function getSel(idx) {
- return selections[selectOrder[idx]];
- }
- function allSelectionsClass(cls) {
- for (var i=0, n=nSel(); i<n; i++) {
- if (getSel(i).obj.class !== cls) {
- return false;
- }
- }
- return true;
- }
-
- // ==========================
-
- function nodeMouseOver(m) {
- if (!m.dragStarted) {
- if (hovered != m) {
- hovered = m;
- tov.hooks.mouseOver({
- id: m.id,
- class: m.class,
- type: m.type
- });
- }
- }
- }
-
- function nodeMouseOut(m) {
- if (!m.dragStarted) {
- if (hovered) {
- hovered = null;
- tov.hooks.mouseOut();
- }
- }
- }
-
- // ==========================
-
- function selectObject(obj) {
- var el = this,
- nodeEv = el && el.tagName === 'g',
- ev = d3.event.sourceEvent || {},
- n;
-
- if (api.zoomingOrPanning(ev)) {
- return;
- }
-
- if (nodeEv) {
- n = d3.select(el);
- } else {
- api.node().each(function (d) {
- if (d == obj) {
- n = d3.select(el = this);
- }
- });
- }
- if (!n) return;
-
- if (nodeEv) {
- consumeClick = true;
- }
- api.deselectLink();
-
- if (ev.shiftKey && n.classed('selected')) {
- deselectObject(obj.id);
- updateDetail();
- return;
- }
-
- if (!ev.shiftKey) {
- deselectAll(true);
- }
-
- selections[obj.id] = { obj: obj, el: el };
- selectOrder.push(obj.id);
-
- n.classed('selected', true);
- api.updateDeviceColors(obj);
- updateDetail();
- }
-
- function deselectObject(id) {
- var obj = selections[id];
- if (obj) {
- d3.select(obj.el).classed('selected', false);
- delete selections[id];
- fs.removeFromArray(id, selectOrder);
- api.updateDeviceColors(obj.obj);
- }
- }
-
- function deselectAll(skipUpdate) {
- var something = (selectOrder.length > 0);
-
- // deselect all nodes in the network...
- api.node().classed('selected', false);
- selections = {};
- selectOrder = [];
- api.updateDeviceColors();
- if (!skipUpdate) {
- updateDetail();
- }
-
- // return true if something was selected
- return something;
- }
-
- // === -----------------------------------------------------
-
- function requestDetails(data) {
- wss.sendEvent('requestDetails', {
- id: data.id,
- class: data.class
- });
- }
-
- // === -----------------------------------------------------
-
- function updateDetail() {
- var nSel = selectOrder.length;
- if (!nSel) {
- emptySelect();
- } else if (nSel === 1) {
- singleSelect();
- } else {
- multiSelect();
- }
- }
-
- function emptySelect() {
- tov.hooks.emptySelect();
- tps.displayNothing();
- }
-
- function singleSelect() {
- var data = getSel(0).obj;
- requestDetails(data);
- // NOTE: detail panel is shown as a response to receiving
- // a 'showDetails' event from the server. See 'showDetails'
- // callback function below...
- }
-
- function multiSelect() {
- // display the selected nodes in the detail panel
- tps.displayMulti(selectOrder);
- addHostSelectionActions();
- tov.hooks.multiSelect(selectOrder);
- tps.displaySomething();
- }
-
- function addHostSelectionActions() {
- if (allSelectionsClass('host')) {
- if (nSel() === 2) {
- tps.addAction({
- id: 'host-flow-btn',
- gid: 'endstation',
- cb: tts.addHostIntent,
- tt: 'Create Host-to-Host Flow'
- });
- } else if (nSel() >= 2) {
- tps.addAction({
- id: 'mult-src-flow-btn',
- gid: 'flows',
- cb: tts.addMultiSourceIntent,
- tt: 'Create Multi-Source Flow'
- });
- }
- }
- }
-
-
- // === -----------------------------------------------------
- // Event Handlers
-
- // display the data for the single selected node
- function showDetails(data) {
- var buttons = fs.isA(data.buttons) || [];
- tps.displaySingle(data);
- tov.installButtons(buttons, data, data.props['URI']);
- tov.hooks.singleSelect(data);
- tps.displaySomething();
- }
-
- // returns true if one or more nodes are selected.
- function somethingSelected() {
- return nSel();
- }
-
- function clickConsumed(x) {
- var cc = consumeClick;
- consumeClick = !!x;
- return cc;
- }
-
- // returns a selection context, providing info about what is selected
- function selectionContext() {
- var devices = [],
- hosts = [],
- types = {};
-
- angular.forEach(selections, function (d) {
- var o = d.obj,
- c = o.class;
-
- if (c === 'device') {
- devices.push(o.id);
- types[o.id] = o.type;
- }
- if (c === 'host') {
- hosts.push(o.id);
- types[o.id] = o.type;
- }
- });
-
- return {
- devices: devices,
- hosts: hosts,
- types: types
- };
- }
-
- // === -----------------------------------------------------
- // === MODULE DEFINITION ===
-
- angular.module('ovTopo')
- .factory('TopoSelectService',
- ['$log', 'FnService', 'WebSocketService', 'TopoOverlayService',
- 'TopoPanelService', 'TopoTrafficService', 'NavService',
-
- function (_$log_, _fs_, _wss_, _tov_, _tps_, _tts_, _ns_) {
- $log = _$log_;
- fs = _fs_;
- wss = _wss_;
- tov = _tov_;
- tps = _tps_;
- tts = _tts_;
- ns = _ns_;
-
- function initSelect(_api_) {
- api = _api_;
- }
-
- function destroySelect() { }
-
- return {
- initSelect: initSelect,
- destroySelect: destroySelect,
-
- showDetails: showDetails,
-
- nodeMouseOver: nodeMouseOver,
- nodeMouseOut: nodeMouseOut,
- selectObject: selectObject,
- deselectObject: deselectObject,
- deselectAll: deselectAll,
- updateDetail: updateDetail,
-
- hovered: function () { return hovered; },
- selectOrder: function () { return selectOrder; },
- somethingSelected: somethingSelected,
-
- clickConsumed: clickConsumed,
- selectionContext: selectionContext
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoSprite.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoSprite.js
deleted file mode 100644
index 1c957412..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoSprite.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Sprite Module.
- Defines behavior for loading sprites into the sprite layer.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, $http, fs, gs, sus, wss;
-
- // constants
- var tssid = 'TopoSpriteService: ',
- fontsize = 20; // default font size 20pt.
-
- // internal state
- var spriteLayer, defsElement;
-
-
- function registerPathsAsGlyphs(paths) {
- var custom = {},
- ids = [];
-
- function mkd(d) {
- return fs.isA(d) ? d.join('') : d;
- }
-
- paths.forEach(function (path) {
- var tag = 'spr_' + path.tag;
-
- if (path.glyph) {
- // assumption is that we are using a built-in glyph
- return;
- }
-
- custom['_' + tag] = path.viewbox || '0 0 1000 1000';
- custom[tag] = mkd(path.d);
- ids.push(tag);
- });
-
- gs.registerGlyphs(custom);
- gs.loadDefs(defsElement, ids, true);
- }
-
- function applyStrokeStyle(s, use) {
- var style;
- if (s) {
- style = {};
- angular.forEach(s, function (value, key) {
- style['stroke-' + key] = value;
- });
- use.style(style);
- }
- }
-
- function applyFillClass(f, use) {
- use.classed('fill-' + f, true);
- }
-
- function doSprite(spr, def, pathmeta) {
- var pmeta = pathmeta[def.path],
- c = spr.class || 'gray1',
- p = spr.pos || [0,0],
- lab = spr.label,
- dim = def.dim || [40,40],
- w = dim[0],
- h = dim[1],
- dy = def.labelyoff || 1,
- sc = def.scale,
- xfm = sus.translate(p),
- g, attr, use;
-
- if (sc) {
- xfm += sus.scale(sc, sc);
- }
-
- g = spriteLayer.append('g')
- .classed(c, true)
- .attr('transform', xfm);
-
- attr = {
- width: w,
- height: h,
- 'xlink:href': '#' + pmeta.u
- };
-
- use = g.append('use').attr(attr);
- applyStrokeStyle(pmeta.s, use);
- applyFillClass(def.fill, use);
-
-
- // add subpaths if they have been defined
- if (fs.isA(def.subpaths)) {
- def.subpaths.forEach(function (v) {
- pmeta = pathmeta[v.path];
- attr = {
- width: w,
- height: h,
- 'xlink:href': '#' + pmeta.u,
- transform: sus.translate(v.pos)
- };
- use = g.append('use').attr(attr);
- applyStrokeStyle(pmeta.s, use);
- applyFillClass(def.subpathfill, use);
- });
- }
-
- if (lab) {
- g.append('text')
- .text(lab)
- .attr({ x: w / 2, y: h * dy });
- }
- }
-
- function doLabel(label) {
- var c = label.class || 'gray1',
- p = label.pos || [0,0],
- sz = label.size || 1.0,
- g = spriteLayer.append('g')
- .classed(c, true)
- .attr('transform', sus.translate(p))
- .append('text')
- .text(label.text)
- .style('font-size', (fontsize * sz)+'pt');
- }
-
-
- // ==========================
- // event handlers
-
- // Handles response from 'spriteListRequest' which lists all the
- // registered sprite definitions on the server.
- // (see onos-upload-sprites)
- function inList(payload) {
- $log.debug(tssid + 'Registered sprite definitions:', payload.names);
- // Some day, we will make this list available to the user in
- // a dropdown selection box...
- }
-
- // Handles response from 'spriteDataRequest' which provides the
- // data for the requested sprite definition.
- function inData(payload) {
- var data = payload.data,
- name, desc, pfx, sprites, labels, alpha,
- paths, defn, load,
- pathmeta = {},
- defs = {},
- warn = [];
-
- if (!data) {
- $log.warn(tssid + 'No sprite data loaded.');
- return;
- }
- name = data.defn_name;
- desc = data.defn_desc;
- paths = data.paths;
- defn = data.defn;
- load = data.load;
- pfx = tssid + '[' + name + ']: ';
-
- $log.debug("Loading sprites...[" + name + "]", desc);
-
- function no(what) {
- warn.push(pfx + 'No ' + what + ' property defined');
- }
-
- if (!paths) no('paths');
- if (!defn) no('defn');
- if (!load) no('load');
-
- if (warn.length) {
- $log.error(warn.join('\n'));
- return;
- }
-
- // any custom paths need to be added to the glyph DB, and imported
- registerPathsAsGlyphs(paths);
-
- paths.forEach(function (p) {
- pathmeta[p.tag] = {
- s: p.stroke,
- u: p.glyph || 'spr_' + p.tag
- };
- });
-
- defn.forEach(function (d) {
- defs[d.id] = d;
- });
-
- // sprites, labels and alpha are each optional components of the load
- sprites = load.sprites;
- labels = load.labels;
- alpha = load.alpha;
-
- if (alpha) {
- spriteLayer.style('opacity', alpha);
- }
-
- if (sprites) {
- sprites.forEach(function (spr) {
- var def = defs[spr.id];
- doSprite(spr, def, pathmeta);
- });
- }
-
- if (labels) {
- labels.forEach(doLabel);
- }
- }
-
-
- function loadSprites(layer, defsElem, defname) {
- var name = defname || 'sprites';
- spriteLayer = layer;
- defsElement = defsElem;
-
- $log.info(tssid + 'Requesting sprite definition ['+name+']...');
-
- wss.sendEvent('spriteListRequest');
- wss.sendEvent('spriteDataRequest', {name: name});
- }
-
- // === -----------------------------------------------------
- // === MODULE DEFINITION ===
-
- angular.module('ovTopo')
- .factory('TopoSpriteService',
- ['$log', '$http', 'FnService', 'GlyphService',
- 'SvgUtilService', 'WebSocketService',
-
- function (_$log_, _$http_, _fs_, _gs_, _sus_, _wss_) {
- $log = _$log_;
- $http = _$http_;
- fs = _fs_;
- gs = _gs_;
- sus = _sus_;
- wss = _wss_;
-
- return {
- loadSprites: loadSprites,
- spriteListResponse: inList,
- spriteDataResponse: inData
- };
- }]);
-
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
deleted file mode 100644
index fbcdaf6d..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Toolbar Module.
- Functions for creating and interacting with the toolbar.
- */
-
-(function () {
- 'use strict';
-
- // injected references
- var $log, fs, tbs, ps, tov, tds, api;
-
- // API:
- // getActionEntry
- // setUpKeys
-
- // internal state
- var toolbar, keyData, cachedState, thirdRow, ovRset, ovIndex;
-
- // constants
- var name = 'topo-tbar',
- cooktag = 'topo_prefs',
- soa = 'switchOverlayActions: ',
- selOver = 'Select overlay here &#x21e7;',
- defaultOverlay = 'traffic';
-
-
- // key to button mapping data
- var k2b = {
- O: { id: 'summary-tog', gid: 'summary', isel: true},
- I: { id: 'instance-tog', gid: 'uiAttached', isel: true },
- D: { id: 'details-tog', gid: 'details', isel: true },
- H: { id: 'hosts-tog', gid: 'endstation', isel: false },
- M: { id: 'offline-tog', gid: 'switch', isel: true },
- P: { id: 'ports-tog', gid: 'ports', isel: true },
- B: { id: 'bkgrnd-tog', gid: 'map', isel: false },
- S: { id: 'sprite-tog', gid: 'cloud', isel: false },
-
- //X: { id: 'nodelock-tog', gid: 'lock', isel: false },
- Z: { id: 'oblique-tog', gid: 'oblique', isel: false },
- N: { id: 'filters-btn', gid: 'filters' },
- L: { id: 'cycleLabels-btn', gid: 'cycleLabels' },
- R: { id: 'resetZoom-btn', gid: 'resetZoom' },
-
- E: { id: 'eqMaster-btn', gid: 'eqMaster' }
- };
-
- var prohibited = [
- 'T', 'backSlash', 'slash',
- 'X' // needed until we re-instate X above.
- ];
- prohibited = prohibited.concat(d3.map(k2b).keys());
-
-
- // initial toggle state: default settings and tag to key mapping
- var defaultPrefsState = {
- summary: 1,
- insts: 1,
- detail: 1,
- hosts: 0,
- offdev: 1,
- porthl: 1,
- bg: 0,
- spr: 0,
- toolbar: 0
- },
- prefsMap = {
- summary: 'O',
- insts: 'I',
- detail: 'D',
- hosts: 'H',
- offdev: 'M',
- porthl: 'P',
- bg: 'B',
- spr: 'S'
- // NOTE: toolbar state is handled separately
- };
-
- function init(_api_) {
- api = _api_;
-
- // retrieve initial toggle button settings from user prefs
- setInitToggleState();
- }
-
- function topoDefPrefs() {
- return angular.extend({}, defaultPrefsState);
- }
-
- function setInitToggleState() {
- cachedState = ps.asNumbers(ps.getPrefs(cooktag));
- $log.debug('TOOLBAR---- read prefs state:', cachedState);
-
- if (!cachedState) {
- cachedState = topoDefPrefs();
- ps.setPrefs(cooktag, cachedState);
- $log.debug('TOOLBAR---- Set default prefs state:', cachedState);
- }
-
- angular.forEach(prefsMap, function (v, k) {
- var cfg = k2b[v];
- cfg && (cfg.isel = !!cachedState[k]);
- });
- }
-
- function initKeyData() {
- // TODO: use angular forEach instead of d3.map
- keyData = d3.map(k2b);
- keyData.forEach(function(key, value) {
- var data = api.getActionEntry(key);
- value.cb = data[0]; // on-click callback
- value.tt = data[1] + ' (' + key + ')'; // tooltip
- });
- }
-
- function addButton(key) {
- var v = keyData.get(key);
- v.btn = toolbar.addButton(v.id, v.gid, v.cb, v.tt);
- }
-
- function addToggle(key, suppressIfMobile) {
- var v = keyData.get(key);
- if (suppressIfMobile && fs.isMobile()) { return; }
- v.tog = toolbar.addToggle(v.id, v.gid, v.isel, v.cb, v.tt);
- }
-
- function addFirstRow() {
- addToggle('I');
- addToggle('O');
- addToggle('D');
- toolbar.addSeparator();
-
- addToggle('H');
- addToggle('M');
- addToggle('P', true);
- addToggle('B');
- addToggle('S', true);
- }
-
- function addSecondRow() {
- //addToggle('X');
- addToggle('Z');
- addButton('N');
- addButton('L');
- addButton('R');
- toolbar.addSeparator();
- addButton('E');
- }
-
- function addOverlays() {
- toolbar.addSeparator();
-
- // generate radio button set for overlays; start with 'none'
- var rset = [{
- gid: 'unknown',
- tooltip: 'No Overlay',
- cb: function () {
- tov.tbSelection(null, switchOverlayActions);
- }
- }];
- ovIndex = tov.augmentRbset(rset, switchOverlayActions);
- ovRset = toolbar.addRadioSet('topo-overlays', rset);
- }
-
- // invoked by overlay service to switch out old buttons and switch in new
- function switchOverlayActions(oid, keyBindings) {
- var prohibits = [],
- kb = fs.isO(keyBindings) || {},
- order = fs.isA(kb._keyOrder) || [];
-
- if (keyBindings && !keyBindings._keyOrder) {
- $log.warn(soa + 'no _keyOrder property defined');
- } else {
- // sanity removal of reserved property names
- ['esc', '_keyListener', '_helpFormat'].forEach(function (k) {
- fs.removeFromArray(k, order);
- });
- }
-
- // ensure dialog has closed (if opened by outgoing overlay)
- tds.closeDialog();
- thirdRow.clear();
-
- if (!order.length) {
- thirdRow.setText(selOver);
- thirdRow.classed('right', true);
- api.setUpKeys(); // clear previous overlay key bindings
-
- } else {
- thirdRow.classed('right', false);
- angular.forEach(order, function (key) {
- var value, bid, gid, tt;
-
- if (prohibited.indexOf(key) > -1) {
- prohibits.push(key);
-
- } else {
- value = keyBindings[key];
- bid = oid + '-' + key;
- gid = tov.mkGlyphId(oid, value.gid);
- tt = value.tt + ' (' + key + ')';
- thirdRow.addButton(bid, gid, value.cb, tt);
- }
- });
- api.setUpKeys(keyBindings); // add overlay key bindings
- }
-
- if (prohibits.length) {
- $log.warn(soa + 'Prohibited key bindings ignored:', prohibits);
- }
- }
-
- function createToolbar() {
- initKeyData();
- toolbar = tbs.createToolbar(name);
- addFirstRow();
- toolbar.addRow();
- addSecondRow();
- addOverlays();
- thirdRow = toolbar.addRow();
- thirdRow.setText(selOver);
- thirdRow.classed('right', true);
-
- if (cachedState.toolbar) {
- toolbar.show();
- } else {
- toolbar.hide();
- }
- }
-
- function destroyToolbar() {
- tbs.destroyToolbar(name);
- tov.resetOnToolbarDestroy();
- }
-
- // allows us to ensure the button states track key strokes
- function keyListener(key) {
- var v = keyData.get(key);
-
- if (v) {
- // we have a valid button mapping
- if (v.tog) {
- // it's a toggle button
- v.tog.toggleNoCb();
- }
- }
- }
-
- function toggleToolbar() {
- toolbar.toggle();
- }
-
- function setDefaultOverlay() {
- var idx = ovIndex[defaultOverlay] || 0;
- ovRset.selectedIndex(idx);
- }
-
- angular.module('ovTopo')
- .factory('TopoToolbarService',
- ['$log', 'FnService', 'ToolbarService', 'PrefsService',
- 'TopoOverlayService', 'TopoDialogService',
-
- function (_$log_, _fs_, _tbs_, _ps_, _tov_, _tds_) {
- $log = _$log_;
- fs = _fs_;
- tbs = _tbs_;
- ps = _ps_;
- tov = _tov_;
- tds = _tds_;
-
- return {
- init: init,
- createToolbar: createToolbar,
- destroyToolbar: destroyToolbar,
- keyListener: keyListener,
- toggleToolbar: toggleToolbar,
- setDefaultOverlay: setDefaultOverlay
- };
- }]);
-}()); \ No newline at end of file
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoTraffic.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
deleted file mode 100644
index ff690c49..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoTraffic.js
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Traffic Module.
- Defines behavior for viewing different traffic modes.
- */
-
-(function () {
- 'use strict';
-
- // injected refs
- var $log, fs, flash, wss, api;
-
- /*
- API to topoForce
- hovered()
- somethingSelected()
- selectOrder()
- */
-
- // internal state
- var trafficMode = null,
- hoverMode = null;
-
-
- // === -----------------------------------------------------
- // Helper functions
-
- // invoked in response to change in selection and/or mouseover/out:
- function requestTrafficForMode(mouse) {
- if (trafficMode === 'flows') {
- requestDeviceLinkFlows();
- } else if (trafficMode === 'intents') {
- if (!mouse || hoverMode === 'intents') {
- requestRelatedIntents();
- }
- } else {
- // do nothing
- }
- }
-
- function requestDeviceLinkFlows() {
- // generates payload based on current hover-state
- var hov = api.hovered();
-
- function hoverValid() {
- return hoverMode === 'flows' &&
- hov && (hov.class === 'device');
- }
-
- if (api.somethingSelected()) {
- wss.sendEvent('requestDeviceLinkFlows', {
- ids: api.selectOrder(),
- hover: hoverValid() ? hov.id : ''
- });
- }
- }
-
- function requestRelatedIntents() {
- // generates payload based on current hover-state
- var hov = api.hovered();
-
- function hoverValid() {
- return hoverMode === 'intents' &&
- hov && (hov.class === 'host' || hov.class === 'device');
- }
-
- if (api.somethingSelected()) {
- wss.sendEvent('requestRelatedIntents', {
- ids: api.selectOrder(),
- hover: hoverValid() ? hov.id : ''
- });
- }
- }
-
-
- // === -------------------------------------------------------------
- // Traffic requests invoked from keystrokes or toolbar buttons...
-
- function cancelTraffic(forced) {
- if (!trafficMode || (!forced && trafficMode === 'allFlowPort')) {
- return false;
- }
-
- trafficMode = hoverMode = null;
- wss.sendEvent('cancelTraffic');
- flash.flash('Traffic monitoring canceled');
- return true;
- }
-
- function showAllFlowTraffic() {
- trafficMode = 'allFlowPort';
- hoverMode = null;
- wss.sendEvent('requestAllFlowTraffic');
- flash.flash('All Flow Traffic');
- }
-
- function showAllPortTraffic() {
- trafficMode = 'allFlowPort';
- hoverMode = null;
- wss.sendEvent('requestAllPortTraffic');
- flash.flash('All Port Traffic');
- }
-
- function showDeviceLinkFlows () {
- trafficMode = hoverMode = 'flows';
- requestDeviceLinkFlows();
- flash.flash('Device Flows');
- }
-
- function showRelatedIntents () {
- trafficMode = hoverMode = 'intents';
- requestRelatedIntents();
- flash.flash('Related Paths');
- }
-
- function showPrevIntent() {
- if (trafficMode === 'intents') {
- hoverMode = null;
- wss.sendEvent('requestPrevRelatedIntent');
- flash.flash('Previous related intent');
- }
- }
-
- function showNextIntent() {
- if (trafficMode === 'intents') {
- hoverMode = null;
- wss.sendEvent('requestNextRelatedIntent');
- flash.flash('Next related intent');
- }
- }
-
- function showSelectedIntentTraffic() {
- if (trafficMode === 'intents') {
- hoverMode = null;
- wss.sendEvent('requestSelectedIntentTraffic');
- flash.flash('Traffic on Selected Path');
- }
- }
-
- // force the system to create a single intent selection
- function selectIntent(data) {
- trafficMode = 'intents';
- hoverMode = null;
- wss.sendEvent('selectIntent', data);
- flash.flash('Selecting Intent ' + data.key);
- }
-
-
- // === ------------------------------------------------------
- // action buttons on detail panel (multiple selection)
-
- function addHostIntent () {
- var so = api.selectOrder();
- wss.sendEvent('addHostIntent', {
- one: so[0],
- two: so[1],
- ids: so
- });
- trafficMode = 'intents';
- hoverMode = null;
- flash.flash('Host-to-Host flow added');
- }
-
- function addMultiSourceIntent () {
- var so = api.selectOrder();
- wss.sendEvent('addMultiSourceIntent', {
- src: so.slice(0, so.length - 1),
- dst: so[so.length - 1],
- ids: so
- });
- trafficMode = 'intents';
- hoverMode = null;
- flash.flash('Multi-Source flow added');
- }
-
-
- // === -----------------------------------------------------
- // === MODULE DEFINITION ===
-
- angular.module('ovTopo')
- .factory('TopoTrafficService',
- ['$log', 'FnService', 'FlashService', 'WebSocketService',
-
- function (_$log_, _fs_, _flash_, _wss_) {
- $log = _$log_;
- fs = _fs_;
- flash = _flash_;
- wss = _wss_;
-
- return {
- initTraffic: function (_api_) { api = _api_; },
- destroyTraffic: function () { },
-
- // invoked from toolbar overlay buttons or keystrokes
- cancelTraffic: cancelTraffic,
- showAllFlowTraffic: showAllFlowTraffic,
- showAllPortTraffic: showAllPortTraffic,
- showDeviceLinkFlows: showDeviceLinkFlows,
- showRelatedIntents: showRelatedIntents,
- showPrevIntent: showPrevIntent,
- showNextIntent: showNextIntent,
- showSelectedIntentTraffic: showSelectedIntentTraffic,
- selectIntent: selectIntent,
-
- // invoked from mouseover/mouseout and selection change
- requestTrafficForMode: requestTrafficForMode,
-
- // TODO: these should move to new UI demo app
- // invoked from buttons on detail (multi-select) panel
- addHostIntent: addHostIntent,
- addMultiSourceIntent: addMultiSourceIntent
- };
- }]);
-}());
diff --git a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoTrafficNew.js b/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoTrafficNew.js
deleted file mode 100644
index cb4bc49a..00000000
--- a/framework/src/onos/web/gui/src/main/webapp/app/view/topo/topoTrafficNew.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * 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 Traffic Overlay Module.
- Defines behavior for viewing different traffic modes.
- Installed as a Topology Overlay.
- */
-(function () {
- 'use strict';
-
- // injected refs
- var $log, tov, tts;
-
- // NOTE: no internal state here -- see TopoTrafficService for that
-
- // NOTE: providing button disabling requires too big a refactoring of
- // the button factory etc. Will have to be done another time.
-
-
- // traffic overlay definition
- var overlay = {
- overlayId: 'traffic',
- glyphId: 'allTraffic',
- tooltip: 'Traffic Overlay',
-
- // NOTE: Traffic glyphs already installed as part of the base ONOS set.
-
- activate: function () {
- $log.debug("Traffic overlay ACTIVATED");
- },
-
- deactivate: function () {
- tts.cancelTraffic(true);
- $log.debug("Traffic overlay DEACTIVATED");
- },
-
- // detail panel button definitions
- // (keys match button identifiers, also defined in TrafficOverlay.java)
- buttons: {
- showDeviceFlows: {
- gid: 'flows',
- tt: 'Show Device Flows',
- cb: function (data) { tts.showDeviceLinkFlows(); }
- },
-
- showRelatedTraffic: {
- gid: 'relatedIntents',
- tt: 'Show Related Traffic',
- cb: function (data) { tts.showRelatedIntents(); }
- }
- },
-
- // key bindings for traffic overlay toolbar buttons
- // NOTE: fully qual. button ID is derived from overlay-id and key-name
- keyBindings: {
- 0: {
- cb: function () { tts.cancelTraffic(true); },
- tt: 'Cancel traffic monitoring',
- gid: 'xMark'
- },
-
- A: {
- cb: function () { tts.showAllFlowTraffic(); },
- tt: 'Monitor all traffic using flow stats',
- gid: 'allTraffic'
- },
- Q: {
- cb: function () { tts.showAllPortTraffic(); },
- tt: 'Monitor all traffic using port stats',
- gid: 'allTraffic'
- },
- F: {
- cb: function () { tts.showDeviceLinkFlows(); },
- tt: 'Show device link flows',
- gid: 'flows'
- },
- V: {
- cb: function () { tts.showRelatedIntents(); },
- tt: 'Show all related intents',
- gid: 'relatedIntents'
- },
- leftArrow: {
- cb: function () { tts.showPrevIntent(); },
- tt: 'Show previous related intent',
- gid: 'prevIntent'
- },
- rightArrow: {
- cb: function () { tts.showNextIntent(); },
- tt: 'Show next related intent',
- gid: 'nextIntent'
- },
- W: {
- cb: function () { tts.showSelectedIntentTraffic(); },
- tt: 'Monitor traffic of selected intent',
- gid: 'intentTraffic'
- },
-
- _keyOrder: [
- '0', 'A', 'Q', 'F', 'V', 'leftArrow', 'rightArrow', 'W'
- ]
- },
-
- hooks: {
- // hook for handling escape key
- escape: function () {
- // Must return true to consume ESC, false otherwise.
- return tts.cancelTraffic(true);
- },
-
- // hooks for when the selection changes...
- empty: function () {
- tts.cancelTraffic();
- },
- single: function (data) {
- tts.requestTrafficForMode();
- },
- multi: function (selectOrder) {
- tts.requestTrafficForMode();
- tov.addDetailButton('showRelatedTraffic');
- },
-
- // mouse hooks
- mouseover: function (m) {
- // m has id, class, and type properties
- tts.requestTrafficForMode(true);
- },
- mouseout: function () {
- tts.requestTrafficForMode(true);
- }
- }
- };
-
- // invoke code to register with the overlay service
- angular.module('ovTopo')
- .run(['$log', 'TopoOverlayService', 'TopoTrafficService',
-
- function (_$log_, _tov_, _tts_) {
- $log = _$log_;
- tov = _tov_;
- tts = _tts_;
- tov.register(overlay);
- }]);
-
-}());