GUI -- Starting to migrate the 'force layout' functionality from the old GUI.
Change-Id: I38c5e5cd45a3bdc9cf6f0ec68736f3b5fbcb289f
diff --git a/web/gui/src/main/webapp/app/fw/svg/svgUtil.js b/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
new file mode 100644
index 0000000..ef6049c
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/svg/svgUtil.js
@@ -0,0 +1,55 @@
+/*
+ * 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 -- SVG -- Util Service
+ */
+
+/*
+ The SVG Util Service provides a miscellany of utility functions.
+ */
+
+(function () {
+ 'use strict';
+
+ // injected references
+ var $log, fs;
+
+ angular.module('onosSvg')
+ .factory('SvgUtilService', ['$log', 'FnService',
+ function (_$log_, _fs_) {
+ $log = _$log_;
+ fs = _fs_;
+
+ function createDragBehavior() {
+ $log.warn('SvgUtilService: createDragBehavior -- To Be Implemented');
+ }
+
+ function loadGlow() {
+ $log.warn('SvgUtilService: loadGlow -- To Be Implemented');
+ }
+
+ function cat7() {
+ $log.warn('SvgUtilService: cat7 -- To Be Implemented');
+ }
+
+ return {
+ createDragBehavior: createDragBehavior,
+ loadGlow: loadGlow,
+ cat7: cat7
+ };
+ }]);
+}());
diff --git a/web/gui/src/main/webapp/app/index.html b/web/gui/src/main/webapp/app/index.html
index bad7a6c..853db93 100644
--- a/web/gui/src/main/webapp/app/index.html
+++ b/web/gui/src/main/webapp/app/index.html
@@ -47,6 +47,7 @@
<script src="fw/svg/geodata.js"></script>
<script src="fw/svg/map.js"></script>
<script src="fw/svg/zoom.js"></script>
+ <script src="fw/svg/svgUtil.js"></script>
<script src="fw/remote/remote.js"></script>
<script src="fw/remote/urlfn.js"></script>
@@ -74,6 +75,7 @@
<script src="view/sample/sample.js"></script>
<script src="view/topo/topo.js"></script>
<script src="view/topo/topoEvent.js"></script>
+ <script src="view/topo/topoForce.js"></script>
<script src="view/device/device.js"></script>
<!-- TODO: inject javascript refs server-side -->
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index 66386f9..8bff419 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -28,10 +28,10 @@
];
// references to injected services etc.
- var $log, ks, zs, gs, ms, ps, tes;
+ var $log, ks, zs, gs, ms, ps, tes, tfs;
// DOM elements
- var ovtopo, svg, defs, zoomLayer, map;
+ var ovtopo, svg, defs, zoomLayer, mapG, forceG;
// Internal state
var zoomer, evDispatcher;
@@ -86,7 +86,7 @@
$log.log('ZOOM: translate = ' + tr + ', scale = ' + sc);
// keep the map lines constant width while zooming
- map.style('stroke-width', (2.0 / sc) + 'px');
+ mapG.style('stroke-width', (2.0 / sc) + 'px');
}
function setUpZoom() {
@@ -112,7 +112,7 @@
var points = [
[0, 0], [0, 1000], [1000, 0], [1000, 1000]
];
- map.selectAll('circle')
+ mapG.selectAll('circle')
.data(points)
.enter()
.append('circle')
@@ -123,12 +123,19 @@
}
function setUpMap() {
- map = zoomLayer.append('g').attr('id', 'topo-map');
+ mapG = zoomLayer.append('g').attr('id', 'topo-map');
//ms.loadMapInto(map, '*continental_us', {mapFillScale:0.5});
- ms.loadMapInto(map, '*continental_us');
+ ms.loadMapInto(mapG, '*continental_us');
//showCallibrationPoints();
}
+ // --- Force Layout --------------------------------------------------
+
+ function setUpForce() {
+ forceG = zoomLayer.append('g').attr('id', 'topo-force');
+ tfs.initForce(forceG);
+ }
+
// --- Controller Definition -----------------------------------------
@@ -137,10 +144,10 @@
.controller('OvTopoCtrl', [
'$scope', '$log', '$location', '$timeout',
'KeyService', 'ZoomService', 'GlyphService', 'MapService',
- 'PanelService', 'TopoEventService',
+ 'PanelService', 'TopoEventService', 'TopoForceService',
function ($scope, _$log_, $loc, $timeout,
- _ks_, _zs_, _gs_, _ms_, _ps_, _tes_) {
+ _ks_, _zs_, _gs_, _ms_, _ps_, _tes_, _tfs_) {
var self = this;
$log = _$log_;
ks = _ks_;
@@ -149,6 +156,7 @@
ms = _ms_;
ps = _ps_;
tes = _tes_;
+ tfs = _tfs_;
self.notifyResize = function () {
svgResized(svg.style('width'), svg.style('height'));
@@ -172,6 +180,7 @@
setUpDefs();
setUpZoom();
setUpMap();
+ setUpForce();
// open up a connection to the server...
tes.openSock();
diff --git a/web/gui/src/main/webapp/app/view/topo/topoEvent.js b/web/gui/src/main/webapp/app/view/topo/topoEvent.js
index 73bcc25..5533e16 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoEvent.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoEvent.js
@@ -124,6 +124,6 @@
bindDispatcher: bindDispatcher,
openSock: openSock,
closeSock: closeSock
- }
+ };
}]);
}());
diff --git a/web/gui/src/main/webapp/app/view/topo/topoForce.js b/web/gui/src/main/webapp/app/view/topo/topoForce.js
new file mode 100644
index 0000000..6c3d501
--- /dev/null
+++ b/web/gui/src/main/webapp/app/view/topo/topoForce.js
@@ -0,0 +1,136 @@
+/*
+ * 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 event handling for events received from the server.
+ */
+
+(function () {
+ 'use strict';
+
+ // injected refs
+ var $log, sus;
+
+ // internal state
+ var settings,
+ force, // force layout object
+ drag, // drag behavior handler
+ network = {
+ nodes: [],
+ links: [],
+ lookup: {},
+ revLinkToKey: {}
+ };
+
+
+ // SVG elements;
+ var linkG, linkLabelG, 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
+ }
+ };
+
+
+ // force layout tick function
+ function tick() {
+
+ }
+
+
+ function selectCb() { }
+ function atDragEnd() {}
+ function dragEnabled() {}
+ function clickEnabled() {}
+
+
+ // ==========================
+
+ angular.module('ovTopo')
+ .factory('TopoForceService',
+ ['$log', 'SvgUtilService',
+
+ function (_$log_, _sus_) {
+ $log = _$log_;
+ sus = _sus_;
+
+ // forceG is the SVG group to display the force layout in
+ // w, h are the initial dimensions of the SVG
+ // opts are, well, optional :)
+ function initForce (forceG, w, h, opts) {
+ // TODO: create the force layout and initialize
+ settings = angular.extend({}, defaultSettings, opts);
+
+ linkG = forceG.append('g').attr('id', 'topo-links');
+ linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels');
+ nodeG = forceG.append('g').attr('id', 'topo-nodes');
+
+ link = linkG.selectAll('.link');
+ linkLabel = linkLabelG.selectAll('.linkLabel');
+ node = nodeG.selectAll('.node');
+
+ force = d3.layout.force()
+ .size(w, h)
+ .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,
+ selectCb, atDragEnd, dragEnabled, clickEnabled);
+ }
+
+ function resize(w, h) {
+ force.size(w, h);
+ // Review -- do we need to nudge the layout ?
+ }
+
+ return {
+ initForce: initForce,
+ resize: resize
+ };
+ }]);
+}());
diff --git a/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js b/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
new file mode 100644
index 0000000..7caa83e
--- /dev/null
+++ b/web/gui/src/main/webapp/tests/app/fw/svg/svgUtil-spec.js
@@ -0,0 +1,46 @@
+/*
+ * 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 -- SVG -- SVG Util Service - Unit Tests
+ */
+describe('factory: fw/svg/svgUtil.js', function() {
+ var $log, fs, sus, d3Elem;
+
+ beforeEach(module('onosUtil', 'onosSvg'));
+
+ beforeEach(inject(function (_$log_, FnService, SvgUtilService) {
+ $log = _$log_;
+ fs = FnService;
+ sus = SvgUtilService;
+ d3Elem = d3.select('body').append('svg').append('defs').attr('id', 'myDefs');
+ }));
+
+ afterEach(function () {
+ d3.select('svg').remove();
+ });
+
+ it('should define SvgUtilService', function () {
+ expect(sus).toBeDefined();
+ });
+
+ it('should define api functions', function () {
+ expect(fs.areFunctions(sus, [
+ 'createDragBehavior', 'loadGlow', 'cat7'
+ ])).toBeTruthy();
+ });
+
+});
diff --git a/web/gui/src/main/webapp/tests/app/view/topo/topoEvent-spec.js b/web/gui/src/main/webapp/tests/app/view/topo/topoEvent-spec.js
new file mode 100644
index 0000000..1fd1572
--- /dev/null
+++ b/web/gui/src/main/webapp/tests/app/view/topo/topoEvent-spec.js
@@ -0,0 +1,42 @@
+/*
+ * 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 -- Topo View -- Topo Event Service - Unit Tests
+ */
+describe('factory: view/topo/topoEvent.js', function() {
+ var $log, fs, tes;
+
+ beforeEach(module('ovTopo', 'onosUtil'));
+
+ beforeEach(inject(function (_$log_, FnService, TopoEventService) {
+ $log = _$log_;
+ fs = FnService;
+ tes = TopoEventService;
+ }));
+
+ it('should define TopoEventService', function () {
+ expect(tes).toBeDefined();
+ });
+
+ it('should define api functions', function () {
+ expect(fs.areFunctions(tes, [
+ 'bindDispatcher', 'openSock', 'closeSock'
+ ])).toBeTruthy();
+ });
+
+ // TODO: more tests...
+});
diff --git a/web/gui/src/main/webapp/tests/app/view/topo/topoForce-spec.js b/web/gui/src/main/webapp/tests/app/view/topo/topoForce-spec.js
new file mode 100644
index 0000000..e5f0073
--- /dev/null
+++ b/web/gui/src/main/webapp/tests/app/view/topo/topoForce-spec.js
@@ -0,0 +1,42 @@
+/*
+ * 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 -- Topo View -- Topo Force Service - Unit Tests
+ */
+describe('factory: view/topo/topoForce.js', function() {
+ var $log, fs, tfs;
+
+ beforeEach(module('ovTopo', 'onosUtil'));
+
+ beforeEach(inject(function (_$log_, FnService, TopoForceService) {
+ $log = _$log_;
+ fs = FnService;
+ tfs = TopoForceService;
+ }));
+
+ it('should define TopoForceService', function () {
+ expect(tfs).toBeDefined();
+ });
+
+ it('should define api functions', function () {
+ expect(fs.areFunctions(tfs, [
+ 'initForce'
+ ])).toBeTruthy();
+ });
+
+ // TODO: more tests...
+});
diff --git a/web/gui/src/main/webapp/tests/karma.conf.js b/web/gui/src/main/webapp/tests/karma.conf.js
index 3f08b15..784868e 100644
--- a/web/gui/src/main/webapp/tests/karma.conf.js
+++ b/web/gui/src/main/webapp/tests/karma.conf.js
@@ -25,12 +25,15 @@
// production code...
// make sure modules are defined first...
'../app/onos.js',
- '../app/directives.js',
+
'../app/fw/util/util.js',
'../app/fw/svg/svg.js',
'../app/fw/remote/remote.js',
'../app/fw/widget/widget.js',
'../app/fw/layer/layer.js',
+
+ '../app/view/topo/topo.js',
+
// now load services etc. that augment the modules
'../app/**/*.js',