Steven Burrows
Committed by Gerrit Code Review

Grouped injected vars and shortened findNodeById

Fixed syntax in Topo2NodeModel.js
Added SubRegions to the topo2 view

Change-Id: I04c793f3a9a98808eaa11049f31bbb166cc5b66f
......@@ -171,6 +171,15 @@
fill: #454545;
}
#ov-topo2 svg .node.sub-region rect {
fill: #ffffff;
}
#ov-topo2 svg .node.sub-region use {
/* NOTE: this gets overridden programatically */
fill: #454545;
}
#ov-topo2 svg .node.device.selected rect {
stroke-width: 2.0;
......
......@@ -111,8 +111,8 @@ Module that contains the d3.force.layout logic
}
}
function deviceEnter(device) {
device.onEnter(this, device);
function nodeEnter(node) {
node.onEnter(this, node);
}
function hostLabel(d) {
......@@ -153,7 +153,7 @@ Module that contains the d3.force.layout logic
return {
init: init,
deviceEnter: deviceEnter,
nodeEnter: nodeEnter,
hostEnter: hostEnter,
linkEntering: linkEntering
}
......
......@@ -30,7 +30,6 @@
// configuration
var devIconDim = 36,
labelPad = 10,
hostRadius = 14,
badgeConfig = {
radius: 12,
......@@ -44,8 +43,7 @@
i: 'badgeInfo',
w: 'badgeWarn',
e: 'badgeError'
},
deviceLabelIndex = 0;
};
function createDeviceCollection(data, region) {
......@@ -74,24 +72,6 @@
return remappedDeviceTypes[type] || type || 'unknown';
}
function deviceLabel(d) {
//TODO: Device Json is missing labels array
return "";
var labels = this.get('labels'),
idx = (deviceLabelIndex < labels.length) ? deviceLabelIndex : 0;
return labels[idx];
}
function trimLabel(label) {
return (label && label.trim()) || '';
}
function computeLabelWidth() {
var text = this.select('text'),
box = text.node().getBBox();
return box.width + labelPad * 2;
}
function iconBox(dim, labelWidth) {
return {
x: -dim / 2,
......@@ -104,7 +84,7 @@
function deviceGlyphColor(d) {
var o = this.node.online,
id = "127.0.0.1", // TODO: This should be from node.master
id = this.node.master, // TODO: This should be from node.master
otag = o ? 'online' : 'offline';
return o ? sus.cat7().getColor(id, 0, ts.theme())
: '#ff0000';
......@@ -134,32 +114,25 @@
this.constructor.__super__.initialize.apply(this, arguments);
},
nodeType: 'device',
deviceLabel: deviceLabel,
deviceGlyphColor: deviceGlyphColor,
mapDeviceTypeToGlyph: mapDeviceTypeToGlyph,
trimLabel: trimLabel,
setDeviceColor: setDeviceColor,
onEnter: function (el) {
var node = d3.select(el),
glyphId = mapDeviceTypeToGlyph(this.get('type')),
label = trimLabel(this.deviceLabel()),
rect, text, glyph, labelWidth;
label = this.trimLabel(this.label()),
glyph, labelWidth;
this.el = node;
rect = node.append('rect');
text = node.append('text').text(label)
.attr('text-anchor', 'left')
.attr('y', '0.3em')
.attr('x', halfDevIcon + labelPad);
// Label
var labelElements = this.addLabelElements(label);
labelWidth = label ? this.computeLabelWidth(node) : 0;
labelElements.rect.attr(iconBox(devIconDim, labelWidth));
// Icon
glyph = is.addDeviceIcon(node, glyphId, devIconDim);
labelWidth = label ? computeLabelWidth(node) : 0;
rect.attr(iconBox(devIconDim, labelWidth));
glyph.attr(iconBox(devIconDim, 0));
node.attr('transform', sus.translate(-halfDevIcon, -halfDevIcon));
......
......@@ -193,7 +193,8 @@
.transition()
.attr('opacity', 1);
entering.filter('.device').each(t2d3.deviceEnter);
entering.filter('.device').each(t2d3.nodeEnter);
entering.filter('.sub-region').each(t2d3.nodeEnter);
entering.filter('.host').each(t2d3.hostEnter);
// operate on both existing and new nodes:
......
......@@ -22,6 +22,7 @@
(function () {
'use strict';
var $log;
var Collection, Model, region, ts;
var widthRatio = 1.4,
......@@ -55,7 +56,6 @@
function createLink() {
var linkPoints = this.linkEndPoints(this.get('epA'), this.get('epB'));
console.log(this);
var attrs = angular.extend({}, linkPoints, {
key: this.get('id'),
......@@ -78,19 +78,14 @@
function linkEndPoints(srcId, dstId) {
var sourceNode = this.region.get('devices').get(srcId.substring(0, srcId.length -2));
var targetNode = this.region.get('devices').get(dstId.substring(0, dstId.length -2));
var sourceNode = this.region.findNodeById(srcId)
var targetNode = this.region.findNodeById(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;
// }
if (!sourceNode || !targetNode) {
$log.error('Node(s) not on map for link:' + srcId + ':' + dstId);
//logicError('Node(s) not on map for link:\n' + sMiss + dMiss);
return null;
}
this.source = sourceNode.toJSON();
this.target = targetNode.toJSON();
......@@ -118,31 +113,17 @@
return true;
return both && (s && s.online) && (t && t.online);
},
linkWidth: function () {
var s = this.get('fromSource'),
t = this.get('fromTarget'),
ws = (s && s.linkWidth) || 0,
wt = (t && t.linkWidth) || 0;
// console.log(s);
// TODO: Current json is missing linkWidth
return 1.2;
return this.get('position').multiLink ? 5 : Math.max(ws, wt);
},
restyleLinkElement: function (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 = this.el,
type = this.get('type'),
lw = this.linkWidth(),
online = this.online(),
modeCls = this.expected() ? 'inactive' : 'not-permitted',
lw = 1.2,
delay = immediate ? 0 : 1000;
console.log(type);
// NOTE: understand why el is sometimes undefined on addLink events...
// Investigated:
// el is undefined when it's a reverse link that is being added.
......@@ -185,10 +166,11 @@
angular.module('ovTopo2')
.factory('Topo2LinkService',
['Topo2Collection', 'Topo2Model', 'ThemeService',
['$log', 'Topo2Collection', 'Topo2Model', 'ThemeService',
function (_Collection_, _Model_, _ts_) {
function (_$log_, _Collection_, _Model_, _ts_) {
$log = _$log_;
ts = _ts_;
Collection = _Collection_;
Model = _Model_;
......
......@@ -29,6 +29,11 @@
var defaultLinkType = 'direct',
nearDist = 15;
var devIconDim = 36,
labelPad = 10,
halfDevIcon = devIconDim / 2,
nodeLabelIndex = 1;
function positionNode(node, forUpdate) {
var meta = node.metaUi,
......@@ -113,6 +118,36 @@
initialize: function () {
this.node = this.createNode();
},
label: function () {
var props = this.get('props'),
id = this.get('id'),
friendlyName = props ? props.name : id,
labels = ['', friendlyName, id],
idx = (nodeLabelIndex < labels.length) ? nodeLabelIndex : 0;
return labels[idx];
},
trimLabel: function(label) {
return (label && label.trim()) || '';
},
computeLabelWidth: function(el) {
var text = el.select('text'),
box = text.node().getBBox();
return box.width + labelPad * 2;
},
addLabelElements: function(label) {
var rect = this.el.append('rect');
var text = this.el.append('text').text(label)
.attr('text-anchor', 'left')
.attr('y', '0.3em')
.attr('x', halfDevIcon + labelPad);
return {
rect: rect,
text: text
}
},
svgClassName: function () {
return fn.classNames('node', this.nodeType, this.get('type'), {
online: this.get('online')
......
......@@ -22,14 +22,11 @@
(function () {
'use strict';
var $log,
wss,
Model,
t2sr,
t2ds,
t2hs,
t2ls;
// Injected Services
var $log, wss, t2sr, t2ds, t2hs, t2ls;
var Collection, Model;
//Internal
var region;
function init() {
......@@ -38,9 +35,13 @@
function addRegion(data) {
region = new Model({
var RegionModel = Model.extend({
findNodeById: findNodeById
})
region = new RegionModel({
id: data.id,
layerOrder: data.layerOrder
layerOrder: data.layerOrder,
});
region.set({
......@@ -50,8 +51,6 @@
links: t2ls.createLinkCollection(data.links, region),
});
region.set('test', 2);
angular.forEach(region.get('links').models, function (link) {
link.createLink();
});
......@@ -60,9 +59,23 @@
}
function regionNodes() {
return [].concat(region.get('devices').models, region.get('hosts').models);
return [].concat(
region.get('devices').models,
region.get('hosts').models,
region.get('subregions').models
);
}
function findNodeById(id) {
// Remove /{port} from id if needed
var regex = new RegExp('^[^\/]*');
id = regex.exec(id)[0];
return region.get('devices').get(id) ||
region.get('hosts').get(id) ||
region.get('subregions').get(id);
}
function regionLinks() {
return region.get('links').models;
......@@ -71,9 +84,9 @@
angular.module('ovTopo2')
.factory('Topo2RegionService',
['$log', 'WebSocketService', 'Topo2Model', 'Topo2SubRegionService', 'Topo2DeviceService',
'Topo2HostService', 'Topo2LinkService',
'Topo2HostService', 'Topo2LinkService', 'Topo2Collection',
function (_$log_, _wss_, _Model_, _t2sr_, _t2ds_, _t2hs_, _t2ls_) {
function (_$log_, _wss_, _Model_, _t2sr_, _t2ds_, _t2hs_, _t2ls_, _Collection_) {
$log = _$log_;
wss = _wss_;
......@@ -82,6 +95,7 @@
t2ds = _t2ds_;
t2hs = _t2hs_;
t2ls = _t2ls_;
Collection = _Collection_;
return {
init: init,
......
......@@ -22,7 +22,30 @@
(function () {
'use strict';
var Collection, Model;
var Collection, Model, is, sus, ts, t2vs;
var remappedDeviceTypes = {
virtual: 'cord'
};
// configuration
var devIconDim = 36,
labelPad = 10,
hostRadius = 14,
badgeConfig = {
radius: 12,
yoff: 5,
gdelta: 10
},
halfDevIcon = devIconDim / 2,
devBadgeOff = { dx: -halfDevIcon, dy: -halfDevIcon },
hostBadgeOff = { dx: -hostRadius, dy: -hostRadius },
status = {
i: 'badgeInfo',
w: 'badgeWarn',
e: 'badgeError'
},
deviceLabelIndex = 0;
function createSubRegionCollection(data, region) {
......@@ -33,14 +56,63 @@
return new SubRegionCollection(data);
}
function mapDeviceTypeToGlyph(type) {
return remappedDeviceTypes[type] || type || 'switch';
}
function iconBox(dim, labelWidth) {
return {
x: -dim / 2,
y: -dim / 2,
width: dim + labelWidth,
height: dim
}
}
angular.module('ovTopo2')
.factory('Topo2SubRegionService',
['Topo2Collection', 'Topo2Model',
['Topo2Collection', 'Topo2NodeModel', 'IconService', 'SvgUtilService',
'ThemeService', 'Topo2ViewService',
function (_Collection_, _Model_) {
function (_Collection_, _NodeModel_, _is_, _sus_, _ts_, classnames, _t2vs_) {
t2vs = _t2vs_;
is = _is_;
sus = _sus_;
ts = _ts_;
Collection = _Collection_;
Model = _Model_.extend({});
Model = _NodeModel_.extend({
initialize: function () {
this.set('weight', 0);
this.constructor.__super__.initialize.apply(this, arguments);
},
nodeType: 'sub-region',
mapDeviceTypeToGlyph: mapDeviceTypeToGlyph,
onEnter: function (el) {
var node = d3.select(el),
glyphId = mapDeviceTypeToGlyph(this.get('type')),
label = this.trimLabel(this.label()),
glyph, labelWidth;
this.el = node;
// Label
var labelElements = this.addLabelElements(label);
labelWidth = label ? this.computeLabelWidth(node) : 0;
labelElements.rect.attr(iconBox(devIconDim, labelWidth));
// Icon
glyph = is.addDeviceIcon(node, glyphId, devIconDim);
glyph.attr(iconBox(devIconDim, 0));
node.attr('transform', sus.translate(-halfDevIcon, -halfDevIcon));
this.render();
},
onExit: function () {},
render: function () {}
});
return {
createSubRegionCollection: createSubRegionCollection
......