Simon Hunt

GUI -- Topology - PortStats traffic: enhanced to change link style based on valu…

…es (KBps, MBps, GBps).

Change-Id: I67a62ef85a292db431f3d32eefefd81d4e564794
...@@ -120,6 +120,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -120,6 +120,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
120 private static final double MB = 1024 * KB; 120 private static final double MB = 1024 * KB;
121 private static final double GB = 1024 * MB; 121 private static final double GB = 1024 * MB;
122 122
123 + // TODO: change GB to Gb (when we compute bits/second)
123 private static final String GB_UNIT = "GB"; 124 private static final String GB_UNIT = "GB";
124 private static final String MB_UNIT = "MB"; 125 private static final String MB_UNIT = "MB";
125 private static final String KB_UNIT = "KB"; 126 private static final String KB_UNIT = "KB";
...@@ -763,6 +764,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { ...@@ -763,6 +764,7 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler {
763 764
764 // Poor-mans formatting to get the labels with byte counts looking nice. 765 // Poor-mans formatting to get the labels with byte counts looking nice.
765 private String formatBytes(long bytes) { 766 private String formatBytes(long bytes) {
767 + // TODO: multiply everything by 8 to compute bits/second
766 String unit; 768 String unit;
767 double value; 769 double value;
768 if (bytes > GB) { 770 if (bytes > GB) {
......
...@@ -176,6 +176,17 @@ ...@@ -176,6 +176,17 @@
176 return Number(elem.style(prop).replace(/px$/, '')); 176 return Number(elem.style(prop).replace(/px$/, ''));
177 } 177 }
178 178
179 + function endsWith(str, suffix) {
180 + return str.indexOf(suffix, str.length - suffix.length) !== -1;
181 + }
182 +
183 + function parseBitRate(str) {
184 + return Number(str.replace(/,/, '')
185 + .replace(/\s+.bps/i, '')
186 + .replace(/\.\d*/, ''));
187 + }
188 +
189 +
179 angular.module('onosUtil') 190 angular.module('onosUtil')
180 .factory('FnService', ['$window', function (_$window_) { 191 .factory('FnService', ['$window', function (_$window_) {
181 $window = _$window_; 192 $window = _$window_;
...@@ -196,7 +207,9 @@ ...@@ -196,7 +207,9 @@
196 isEmptyObject: isEmptyObject, 207 isEmptyObject: isEmptyObject,
197 cap: cap, 208 cap: cap,
198 noPx: noPx, 209 noPx: noPx,
199 - noPxStyle: noPxStyle 210 + noPxStyle: noPxStyle,
211 + endsWith: endsWith,
212 + parseBitRate: parseBitRate
200 }; 213 };
201 }]); 214 }]);
202 215
......
...@@ -458,6 +458,45 @@ html[data-platform='iPad'] #topo-p-detail { ...@@ -458,6 +458,45 @@ html[data-platform='iPad'] #topo-p-detail {
458 stroke: rgba(121,231,158,0.5); 458 stroke: rgba(121,231,158,0.5);
459 } 459 }
460 460
461 +/* Port traffic color visualization for KBps, MBps, and GBps */
462 +
463 +.light #ov-topo svg .link.secondary.port-traffic-KBps {
464 + stroke: rgb(0,153,51);
465 + stroke-width: 5.0;
466 +}
467 +.dark #ov-topo svg .link.secondary.port-traffic-KBps {
468 + stroke: rgb(98, 153, 118);
469 + stroke-width: 5.0;
470 +}
471 +
472 +.light #ov-topo svg .link.secondary.port-traffic-MBps {
473 + stroke: rgb(128,145,27);
474 + stroke-width: 6.5;
475 +}
476 +.dark #ov-topo svg .link.secondary.port-traffic-MBps {
477 + stroke: rgb(91, 109, 54);
478 + stroke-width: 6.5;
479 +}
480 +
481 +.light #ov-topo svg .link.secondary.port-traffic-GBps {
482 + stroke: rgb(255, 137, 3);
483 + stroke-width: 8.0;
484 +}
485 +.dark #ov-topo svg .link.secondary.port-traffic-GBps {
486 + stroke: rgb(174, 119, 55);
487 + stroke-width: 8.0;
488 +}
489 +
490 +.light #ov-topo svg .link.secondary.port-traffic-GBps-choked {
491 + stroke: rgb(183, 30, 21);
492 + stroke-width: 8.0;
493 +}
494 +.dark #ov-topo svg .link.secondary.port-traffic-GBps-choked {
495 + stroke: rgb(127, 40, 39);
496 + stroke-width: 8.0;
497 +}
498 +
499 +
461 #ov-topo svg .link.primary { 500 #ov-topo svg .link.primary {
462 stroke-width: 4px; 501 stroke-width: 4px;
463 } 502 }
......
...@@ -59,13 +59,31 @@ ...@@ -59,13 +59,31 @@
59 // labels to them, if they are defined. 59 // labels to them, if they are defined.
60 paths.forEach(function (p) { 60 paths.forEach(function (p) {
61 var n = p.links.length, 61 var n = p.links.length,
62 - i, ldata; 62 + i, ldata, lab, units, magnitude, portcls;
63 63
64 for (i=0; i<n; i++) { 64 for (i=0; i<n; i++) {
65 ldata = api.findLinkById(p.links[i]); 65 ldata = api.findLinkById(p.links[i]);
66 - if (ldata && ldata.el) { 66 + lab = p.labels[i];
67 +
68 + if (ldata && !ldata.el.empty()) {
67 ldata.el.classed(p.class, true); 69 ldata.el.classed(p.class, true);
68 - ldata.label = p.labels[i]; 70 + ldata.label = lab;
71 +
72 + // TODO: change this to 'bps' when we measure bits/sec
73 + if (fs.endsWith(lab, 'Bps')) {
74 + // inject additional styling for port-based traffic
75 + units = lab.substring(lab.length-4);
76 + portcls = 'port-traffic-' + units;
77 +
78 + // for GBps
79 + if (units.substring(0,1) === 'G') {
80 + magnitude = fs.parseBitRate(lab);
81 + if (magnitude >= 9) {
82 + portcls += '-choked'
83 + }
84 + }
85 + ldata.el.classed(portcls, true);
86 + }
69 } 87 }
70 } 88 }
71 }); 89 });
......
...@@ -214,7 +214,7 @@ describe('factory: fw/util/fn.js', function() { ...@@ -214,7 +214,7 @@ describe('factory: fw/util/fn.js', function() {
214 'isF', 'isA', 'isS', 'isO', 'contains', 214 'isF', 'isA', 'isS', 'isO', 'contains',
215 'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'isMobile', 215 'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'isMobile',
216 'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'cap', 216 'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'cap',
217 - 'noPx', 'noPxStyle' 217 + 'noPx', 'noPxStyle', 'endsWith', 'parseBitRate'
218 ])).toBeTruthy(); 218 ])).toBeTruthy();
219 }); 219 });
220 220
...@@ -413,4 +413,34 @@ describe('factory: fw/util/fn.js', function() { ...@@ -413,4 +413,34 @@ describe('factory: fw/util/fn.js', function() {
413 d3.select('#fooElem').remove(); 413 d3.select('#fooElem').remove();
414 }); 414 });
415 415
416 + // === Tests for endsWith()
417 + it('should return true if string ends with foo', function () {
418 + expect(fs.endsWith("barfoo", "foo")).toBe(true);
419 + });
420 +
421 + it('should return false if string doesnt end with foo', function () {
422 + expect(fs.endsWith("barfood", "foo")).toBe(false);
423 + });
424 +
425 + // === Tests for parseBitRate()
426 + it('should return 5 - a', function () {
427 + expect(fs.parseBitRate('5.47 KBps')).toBe(5);
428 + });
429 +
430 + it('should return 5 - b', function () {
431 + expect(fs.parseBitRate('5. KBps')).toBe(5);
432 + });
433 +
434 + it('should return 5 - c', function () {
435 + expect(fs.parseBitRate('5 KBps')).toBe(5);
436 + });
437 +
438 + it('should return 5 - d', function () {
439 + expect(fs.parseBitRate('5 Kbps')).toBe(5);
440 + });
441 +
442 + it('should return 2001', function () {
443 + expect(fs.parseBitRate('2,001.59 Gbps')).toBe(2001);
444 + });
416 }); 445 });
446 +
......