GUI -- Reworking sample view to be more interesting.
diff --git a/web/gui/src/main/webapp/sample2.js b/web/gui/src/main/webapp/sample2.js
index 7222452..6b4329f 100644
--- a/web/gui/src/main/webapp/sample2.js
+++ b/web/gui/src/main/webapp/sample2.js
@@ -15,7 +15,7 @@
*/
/*
- Alternate Sample module file to illustrate framework integration.
+ Sample module file to illustrate framework integration.
@author Simon Hunt
*/
@@ -23,9 +23,24 @@
(function (onos) {
'use strict';
- var svg;
+ var pi = Math.PI,
+ svg,
+ dotG,
+ nCircles = 12,
+ circleData = [],
+ dotId = 0,
+ angle = 360 / nCircles,
+ baseAngle = -90 - angle,
+ groupRadius = 120,
+ dotRadius = 24,
+ dotMoveMs = 800,
+ dotAppearMs = 300,
+ dotEase = 'elastic',
+ colorScale = d3.scale.linear()
+ .domain([-pi/2, 2*pi/4, 3*pi/2])
+ .range(['green', 'goldenrod', 'blue']);
-
+ // set the size of the SVG layer to match that of the view
function sizeSvg(view) {
svg.attr({
width: view.width(),
@@ -33,63 +48,169 @@
});
}
- // NOTE: view is a view-token data structure:
- // {
- // vid: 'view-id',
- // nid: 'nav-id',
- // $div: ... // d3 selection of dom view div.
- // }
-
// gets invoked only the first time the view is loaded
function preload(view, ctx) {
+ // prepare our SVG layer...
svg = view.$div.append('svg');
sizeSvg(view);
+ dotG = svg.append('g').attr('id', 'dots');
}
+ // gets invoked just before our view is loaded
function reset(view) {
- // clear our svg of all objects
- svg.html('');
+ // clear dot group and reset circle data
+ dotG.html('');
+ circleData = [];
+ // also clear text, if any
+ svg.selectAll('text').remove();
}
- function load(view, ctx) {
- var fill = 'red',
- stroke = 'black',
- ctxText = ctx ? 'Context is "' + ctx + '"' : 'No Context';
+ function updateCirclePositions(view, addNew) {
+ var w = view.width(),
+ h = view.height(),
+ ox = w / 2,
+ oy = h / 2;
- svg.append('circle')
+ // reposition existing dots
+ circleData.forEach(function (c, i) {
+ var inc = addNew ? 1 : 0,
+ theta = ((i + inc) * angle + baseAngle) * pi/180,
+ dx = Math.cos(theta) * groupRadius,
+ dy = Math.sin(theta) * groupRadius,
+ x = ox + dx,
+ y = oy + dy;
+ if (!addNew && i === 0) {
+ x = ox;
+ y = oy;
+ }
+ c.cx = x;
+ c.cy = y;
+ c.rgb = colorScale(theta);
+ });
+
+ if (addNew) {
+ // introduce a new dot
+ circleData.unshift({
+ cx: ox,
+ cy: oy,
+ id: dotId++
+ });
+ }
+
+ // +1 to account for the circle in the center..
+ if (circleData.length > nCircles + 1) {
+ circleData.splice(nCircles + 1, 1);
+ }
+ }
+
+ function doCircles(view) {
+ var ox = view.width() / 2,
+ oy = view.height() / 2,
+ stroke = 'black',
+ fill = 'red',
+ hoverFill = 'magenta';
+
+ // move existing circles, and add a new one
+ updateCirclePositions(view, true);
+
+ var circ = dotG.selectAll('circle')
+ .data(circleData, function (d) { return d.id; });
+
+ // operate on existing elements
+ circ.on('mouseover', null)
+ .on('mouseout', null)
+ .on('click', null)
+ .transition()
+ .duration(dotMoveMs)
+ .ease(dotEase)
.attr({
- cx: view.width() / 2,
- cy: view.height() / 2,
- r: 30
+ cx: function (d) { return d.cx; },
+ cy: function (d) { return d.cy; }
+ })
+ .style({
+ cursor: 'default',
+ fill: function (d) { return d.rgb; }
+ });
+
+ // operate on entering elements
+ circ.enter()
+ .append('circle')
+ .attr({
+ cx: function (d) { return d.cx; },
+ cy: function (d) { return d.cy; },
+ r: 0
})
.style({
fill: fill,
stroke: stroke,
- 'stroke-width': 3.5
- });
-
- svg.append('text')
- .text(ctxText)
- .attr({
- x: 20,
- y: '1.5em'
+ 'stroke-width': 3.5,
+ cursor: 'pointer',
+ opacity: 0
})
- .style({
- fill: 'darkgreen',
- 'font-size': '20pt'
- });
+ .on('mouseover', function (d) {
+ d3.select(this).style('fill', hoverFill);
+ })
+ .on('mouseout', function (d) {
+ d3.select(this).style('fill', fill);
+ })
+ .on('click', function (d) {
+ setTimeout(function() {
+ doCircles(view, true);
+ }, 10);
+ })
+ .transition()
+ .delay(dotMoveMs)
+ .duration(dotAppearMs)
+ .attr('r', dotRadius)
+ .style('opacity', 1);
+
+ // operate on exiting elements
+ circ.exit()
+ .transition()
+ .duration(750)
+ .style('opacity', 0)
+ .attr({
+ cx: ox,
+ cy: oy,
+ r: groupRadius - dotRadius
+ })
+ .remove();
+ }
+
+ function load(view, ctx) {
+ var ctxText = ctx ? 'Context is "' + ctx + '"' : '';
+
+ // display our view context
+ if (ctxText) {
+ svg.append('text')
+ .text(ctxText)
+ .attr({
+ x: 20,
+ y: '1.5em'
+ })
+ .style({
+ fill: 'darkgreen',
+ 'font-size': '20pt'
+ });
+ }
+
+ doCircles(view);
}
function resize(view, ctx) {
sizeSvg(view);
- svg.selectAll('circle')
- .attr({
- cx: view.width() / 2,
- cy: view.height() / 2
+ updateCirclePositions(view);
+
+ // move exiting dots into new positions, relative to view size
+ var circ = dotG.selectAll('circle')
+ .data(circleData, function (d) { return d.id; });
+ circ.attr({
+ cx: function (d) { return d.cx; },
+ cy: function (d) { return d.cy; }
});
}
- // == register views here, with links to lifecycle callbacks
+ // == register our view here, with links to lifecycle callbacks
onos.ui.addView('sample', {
preload: preload,
@@ -98,5 +219,4 @@
resize: resize
});
-
}(ONOS));
diff --git a/web/gui/src/main/webapp/sampleAlt2.js b/web/gui/src/main/webapp/sampleAlt2.js
index f0e662e..60cbe9d 100644
--- a/web/gui/src/main/webapp/sampleAlt2.js
+++ b/web/gui/src/main/webapp/sampleAlt2.js
@@ -15,7 +15,7 @@
*/
/*
- Sample module file to illustrate framework integration.
+ Alternate sample module file to illustrate framework integration.
@author Simon Hunt
*/
@@ -33,13 +33,6 @@
});
}
- // NOTE: view is a view-token data structure:
- // {
- // vid: 'view-id',
- // nid: 'nav-id',
- // $div: ... // d3 selection of dom view div.
- // }
-
// gets invoked only the first time the view is loaded
function preload(view, ctx) {
svg = view.$div.append('svg');
@@ -52,8 +45,8 @@
}
function load(view, ctx) {
- var fill = 'blue',
- stroke = 'grey';
+ var fill = 'teal',
+ stroke = 'black';
svg.append('circle')
.attr({
@@ -64,7 +57,8 @@
.style({
fill: fill,
stroke: stroke,
- 'stroke-width': 3.5
+ 'stroke-width': 1.5,
+ opacity: 0.5
});
}