Simon Hunt

GUI -- Reworking sample view to be more interesting.

......@@ -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,41 +48,140 @@
});
}
// 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',
function updateCirclePositions(view, addNew) {
var w = view.width(),
h = view.height(),
ox = w / 2,
oy = h / 2;
// 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',
ctxText = ctx ? 'Context is "' + ctx + '"' : 'No Context';
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: function (d) { return d.cx; },
cy: function (d) { return d.cy; }
})
.style({
cursor: 'default',
fill: function (d) { return d.rgb; }
});
svg.append('circle')
// operate on entering elements
circ.enter()
.append('circle')
.attr({
cx: view.width() / 2,
cy: view.height() / 2,
r: 30
cx: function (d) { return d.cx; },
cy: function (d) { return d.cy; },
r: 0
})
.style({
fill: fill,
stroke: stroke,
'stroke-width': 3.5
});
'stroke-width': 3.5,
cursor: 'pointer',
opacity: 0
})
.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({
......@@ -80,16 +194,23 @@
});
}
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));
......
......@@ -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
});
}
......