blob: bbd7ef9d97bea5920385dc52acf5715167751ddc [file] [log] [blame]
Simon Hunt25248912014-11-04 11:25:48 -08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
Simon Hunte7f4bb02014-11-04 15:51:54 -080018 Sample module file to illustrate framework integration.
Simon Hunt25248912014-11-04 11:25:48 -080019 */
20
21(function (onos) {
22 'use strict';
23
Simon Hunte7f4bb02014-11-04 15:51:54 -080024 var pi = Math.PI,
25 svg,
26 dotG,
27 nCircles = 12,
28 circleData = [],
29 dotId = 0,
30 angle = 360 / nCircles,
31 baseAngle = -90 - angle,
32 groupRadius = 120,
33 dotRadius = 24,
34 dotMoveMs = 800,
35 dotAppearMs = 300,
36 dotEase = 'elastic',
37 colorScale = d3.scale.linear()
38 .domain([-pi/2, 2*pi/4, 3*pi/2])
39 .range(['green', 'goldenrod', 'blue']);
Simon Hunt25248912014-11-04 11:25:48 -080040
Simon Hunte7f4bb02014-11-04 15:51:54 -080041 // set the size of the SVG layer to match that of the view
Simon Hunt25248912014-11-04 11:25:48 -080042 function sizeSvg(view) {
43 svg.attr({
44 width: view.width(),
45 height: view.height()
46 });
47 }
48
Simon Hunt25248912014-11-04 11:25:48 -080049 // gets invoked only the first time the view is loaded
Simon Hunta2994cc2014-12-02 14:19:15 -080050 function init(view, ctx, flags) {
Simon Hunte7f4bb02014-11-04 15:51:54 -080051 // prepare our SVG layer...
Simon Hunt25248912014-11-04 11:25:48 -080052 svg = view.$div.append('svg');
53 sizeSvg(view);
Simon Hunte7f4bb02014-11-04 15:51:54 -080054 dotG = svg.append('g').attr('id', 'dots');
Simon Hunt25248912014-11-04 11:25:48 -080055 }
56
Simon Hunte7f4bb02014-11-04 15:51:54 -080057 // gets invoked just before our view is loaded
Simon Hunta2994cc2014-12-02 14:19:15 -080058 function reset(view, ctx, flags) {
Simon Hunte7f4bb02014-11-04 15:51:54 -080059 // clear dot group and reset circle data
60 dotG.html('');
61 circleData = [];
62 // also clear text, if any
63 svg.selectAll('text').remove();
Simon Hunt25248912014-11-04 11:25:48 -080064 }
65
Simon Hunte7f4bb02014-11-04 15:51:54 -080066 function updateCirclePositions(view, addNew) {
67 var w = view.width(),
68 h = view.height(),
69 ox = w / 2,
70 oy = h / 2;
Simon Hunt25248912014-11-04 11:25:48 -080071
Simon Hunte7f4bb02014-11-04 15:51:54 -080072 // reposition existing dots
73 circleData.forEach(function (c, i) {
74 var inc = addNew ? 1 : 0,
75 theta = ((i + inc) * angle + baseAngle) * pi/180,
76 dx = Math.cos(theta) * groupRadius,
77 dy = Math.sin(theta) * groupRadius,
78 x = ox + dx,
79 y = oy + dy;
80 if (!addNew && i === 0) {
81 x = ox;
82 y = oy;
83 }
84 c.cx = x;
85 c.cy = y;
86 c.rgb = colorScale(theta);
87 });
88
89 if (addNew) {
90 // introduce a new dot
91 circleData.unshift({
92 cx: ox,
93 cy: oy,
94 id: dotId++
95 });
96 }
97
98 // +1 to account for the circle in the center..
99 if (circleData.length > nCircles + 1) {
100 circleData.splice(nCircles + 1, 1);
101 }
102 }
103
104 function doCircles(view) {
105 var ox = view.width() / 2,
106 oy = view.height() / 2,
107 stroke = 'black',
108 fill = 'red',
109 hoverFill = 'magenta';
110
111 // move existing circles, and add a new one
112 updateCirclePositions(view, true);
113
114 var circ = dotG.selectAll('circle')
115 .data(circleData, function (d) { return d.id; });
116
117 // operate on existing elements
118 circ.on('mouseover', null)
119 .on('mouseout', null)
120 .on('click', null)
121 .transition()
122 .duration(dotMoveMs)
123 .ease(dotEase)
Simon Hunt25248912014-11-04 11:25:48 -0800124 .attr({
Simon Hunte7f4bb02014-11-04 15:51:54 -0800125 cx: function (d) { return d.cx; },
126 cy: function (d) { return d.cy; }
127 })
128 .style({
129 cursor: 'default',
130 fill: function (d) { return d.rgb; }
131 });
132
133 // operate on entering elements
134 circ.enter()
135 .append('circle')
136 .attr({
137 cx: function (d) { return d.cx; },
138 cy: function (d) { return d.cy; },
139 r: 0
Simon Hunt25248912014-11-04 11:25:48 -0800140 })
141 .style({
142 fill: fill,
143 stroke: stroke,
Simon Hunte7f4bb02014-11-04 15:51:54 -0800144 'stroke-width': 3.5,
145 cursor: 'pointer',
146 opacity: 0
Simon Hunt25248912014-11-04 11:25:48 -0800147 })
Simon Hunte7f4bb02014-11-04 15:51:54 -0800148 .on('mouseover', function (d) {
149 d3.select(this).style('fill', hoverFill);
150 })
151 .on('mouseout', function (d) {
152 d3.select(this).style('fill', fill);
153 })
154 .on('click', function (d) {
155 setTimeout(function() {
156 doCircles(view, true);
157 }, 10);
158 })
159 .transition()
160 .delay(dotMoveMs)
161 .duration(dotAppearMs)
162 .attr('r', dotRadius)
163 .style('opacity', 1);
164
165 // operate on exiting elements
166 circ.exit()
167 .transition()
168 .duration(750)
169 .style('opacity', 0)
170 .attr({
171 cx: ox,
172 cy: oy,
173 r: groupRadius - dotRadius
174 })
175 .remove();
176 }
177
Simon Hunta2994cc2014-12-02 14:19:15 -0800178 function load(view, ctx, flags) {
Simon Hunte7f4bb02014-11-04 15:51:54 -0800179 var ctxText = ctx ? 'Context is "' + ctx + '"' : '';
180
181 // display our view context
182 if (ctxText) {
183 svg.append('text')
184 .text(ctxText)
185 .attr({
186 x: 20,
187 y: '1.5em'
188 })
189 .style({
190 fill: 'darkgreen',
191 'font-size': '20pt'
192 });
193 }
194
195 doCircles(view);
Simon Hunt25248912014-11-04 11:25:48 -0800196 }
197
Simon Hunta2994cc2014-12-02 14:19:15 -0800198 function resize(view, ctx, flags) {
Simon Hunt25248912014-11-04 11:25:48 -0800199 sizeSvg(view);
Simon Hunte7f4bb02014-11-04 15:51:54 -0800200 updateCirclePositions(view);
201
202 // move exiting dots into new positions, relative to view size
203 var circ = dotG.selectAll('circle')
204 .data(circleData, function (d) { return d.id; });
205 circ.attr({
206 cx: function (d) { return d.cx; },
207 cy: function (d) { return d.cy; }
Simon Hunt25248912014-11-04 11:25:48 -0800208 });
209 }
210
Simon Hunte7f4bb02014-11-04 15:51:54 -0800211 // == register our view here, with links to lifecycle callbacks
Simon Hunt25248912014-11-04 11:25:48 -0800212
213 onos.ui.addView('sample', {
Simon Hunta2994cc2014-12-02 14:19:15 -0800214 init: init,
Simon Hunt25248912014-11-04 11:25:48 -0800215 reset: reset,
216 load: load,
217 resize: resize
218 });
219
Simon Hunt25248912014-11-04 11:25:48 -0800220}(ONOS));