Added basic drag and select behavior to nodes.
Changed base colors and added .pkt and .opt classes to differentiate nodes.
Showing
3 changed files
with
144 additions
and
34 deletions
... | @@ -32,20 +32,20 @@ | ... | @@ -32,20 +32,20 @@ |
32 | <div id="view"></div> | 32 | <div id="view"></div> |
33 | </div> | 33 | </div> |
34 | 34 | ||
35 | - // Initialize the UI... | 35 | + <!-- Initialize the UI...--> |
36 | <script type="text/javascript"> | 36 | <script type="text/javascript"> |
37 | var ONOS = $.onos({note: "config, if needed"}); | 37 | var ONOS = $.onos({note: "config, if needed"}); |
38 | </script> | 38 | </script> |
39 | 39 | ||
40 | - // include module files | 40 | + <!-- include module files--> |
41 | - // + mast.js | 41 | + <!-- + mast.js--> |
42 | - // + nav.js | 42 | + <!-- + nav.js--> |
43 | - // + .... application views | 43 | + <!-- + .... application views--> |
44 | 44 | ||
45 | - // for now, we are just bootstrapping the network visualization | 45 | + <!-- for now, we are just bootstrapping the network visualization--> |
46 | <script src="network.js" type="text/javascript"></script> | 46 | <script src="network.js" type="text/javascript"></script> |
47 | 47 | ||
48 | - // finally, build the UI | 48 | + <!-- finally, build the UI--> |
49 | <script type="text/javascript"> | 49 | <script type="text/javascript"> |
50 | $(ONOS.buildUi); | 50 | $(ONOS.buildUi); |
51 | </script> | 51 | </script> | ... | ... |
... | @@ -100,7 +100,7 @@ | ... | @@ -100,7 +100,7 @@ |
100 | 100 | ||
101 | network.data.nodes.forEach(function(n) { | 101 | network.data.nodes.forEach(function(n) { |
102 | var ypc = yPosConstraintForNode(n), | 102 | var ypc = yPosConstraintForNode(n), |
103 | - ix = Math.random() * 0.8 * nw + 0.1 * nw, | 103 | + ix = Math.random() * 0.6 * nw + 0.2 * nw, |
104 | iy = ypc * nh, | 104 | iy = ypc * nh, |
105 | node = { | 105 | node = { |
106 | id: n.id, | 106 | id: n.id, |
... | @@ -152,11 +152,49 @@ | ... | @@ -152,11 +152,49 @@ |
152 | .attr('width', view.width) | 152 | .attr('width', view.width) |
153 | .attr('height', view.height) | 153 | .attr('height', view.height) |
154 | .append('g') | 154 | .append('g') |
155 | - .attr('transform', config.force.translate()); | 155 | +// .attr('id', 'zoomable') |
156 | + .attr('transform', config.force.translate()) | ||
157 | +// .call(d3.behavior.zoom().on("zoom", zoomRedraw)); | ||
158 | + | ||
159 | +// function zoomRedraw() { | ||
160 | +// d3.select("#zoomable").attr("transform", | ||
161 | +// "translate(" + d3.event.translate + ")" | ||
162 | +// + " scale(" + d3.event.scale + ")"); | ||
163 | +// } | ||
164 | + | ||
165 | + // TODO: svg.append('defs') for markers? | ||
166 | + | ||
167 | + // TODO: move glow/blur stuff to util script | ||
168 | + var glow = network.svg.append('filter') | ||
169 | + .attr('x', '-50%') | ||
170 | + .attr('y', '-50%') | ||
171 | + .attr('width', '200%') | ||
172 | + .attr('height', '200%') | ||
173 | + .attr('id', 'blue-glow'); | ||
174 | + | ||
175 | + glow.append('feColorMatrix') | ||
176 | + .attr('type', 'matrix') | ||
177 | + .attr('values', '0 0 0 0 0 ' + | ||
178 | + '0 0 0 0 0 ' + | ||
179 | + '0 0 0 0 .7 ' + | ||
180 | + '0 0 0 1 0 '); | ||
181 | + | ||
182 | + glow.append('feGaussianBlur') | ||
183 | + .attr('stdDeviation', 3) | ||
184 | + .attr('result', 'coloredBlur'); | ||
185 | + | ||
186 | + glow.append('feMerge').selectAll('feMergeNode') | ||
187 | + .data(['coloredBlur', 'SourceGraphic']) | ||
188 | + .enter().append('feMergeNode') | ||
189 | + .attr('in', String); | ||
156 | 190 | ||
157 | - // TODO: svg.append('defs') | ||
158 | - // TODO: glow/blur stuff | ||
159 | // TODO: legend (and auto adjust on scroll) | 191 | // TODO: legend (and auto adjust on scroll) |
192 | +// $('#view').on('scroll', function() { | ||
193 | +// | ||
194 | +// }); | ||
195 | + | ||
196 | + | ||
197 | + | ||
160 | 198 | ||
161 | network.link = network.svg.append('g').selectAll('.link') | 199 | network.link = network.svg.append('g').selectAll('.link') |
162 | .data(network.force.links(), function(d) {return d.id}) | 200 | .data(network.force.links(), function(d) {return d.id}) |
... | @@ -164,27 +202,90 @@ | ... | @@ -164,27 +202,90 @@ |
164 | .attr('class', 'link'); | 202 | .attr('class', 'link'); |
165 | 203 | ||
166 | // TODO: drag behavior | 204 | // TODO: drag behavior |
167 | - // TODO: closest node deselect | 205 | + network.draggedThreshold = d3.scale.linear() |
206 | + .domain([0, 0.1]) | ||
207 | + .range([5, 20]) | ||
208 | + .clamp(true); | ||
209 | + | ||
210 | + function dragged(d) { | ||
211 | + var threshold = network.draggedThreshold(network.force.alpha()), | ||
212 | + dx = d.oldX - d.px, | ||
213 | + dy = d.oldY - d.py; | ||
214 | + if (Math.abs(dx) >= threshold || Math.abs(dy) >= threshold) { | ||
215 | + d.dragged = true; | ||
216 | + } | ||
217 | + return d.dragged; | ||
218 | + } | ||
219 | + | ||
220 | + network.drag = d3.behavior.drag() | ||
221 | + .origin(function(d) { return d; }) | ||
222 | + .on('dragstart', function(d) { | ||
223 | + d.oldX = d.x; | ||
224 | + d.oldY = d.y; | ||
225 | + d.dragged = false; | ||
226 | + d.fixed |= 2; | ||
227 | + }) | ||
228 | + .on('drag', function(d) { | ||
229 | + d.px = d3.event.x; | ||
230 | + d.py = d3.event.y; | ||
231 | + if (dragged(d)) { | ||
232 | + if (!network.force.alpha()) { | ||
233 | + network.force.alpha(.025); | ||
234 | + } | ||
235 | + } | ||
236 | + }) | ||
237 | + .on('dragend', function(d) { | ||
238 | + if (!dragged(d)) { | ||
239 | + selectObject(d, this); | ||
240 | + } | ||
241 | + d.fixed &= ~6; | ||
242 | + }); | ||
243 | + | ||
244 | + $('#view').on('click', function(e) { | ||
245 | + if (!$(e.target).closest('.node').length) { | ||
246 | + deselectObject(); | ||
247 | + } | ||
248 | + }); | ||
168 | 249 | ||
169 | // TODO: add drag, mouseover, mouseout behaviors | 250 | // TODO: add drag, mouseover, mouseout behaviors |
170 | network.node = network.svg.selectAll('.node') | 251 | network.node = network.svg.selectAll('.node') |
171 | .data(network.force.nodes(), function(d) {return d.id}) | 252 | .data(network.force.nodes(), function(d) {return d.id}) |
172 | .enter().append('g') | 253 | .enter().append('g') |
173 | - .attr('class', 'node') | 254 | + .attr('class', function(d) { |
255 | + return 'node ' + d.type; | ||
256 | + }) | ||
174 | .attr('transform', function(d) { | 257 | .attr('transform', function(d) { |
175 | return translate(d.x, d.y); | 258 | return translate(d.x, d.y); |
176 | }) | 259 | }) |
177 | - // .call(network.drag) | 260 | + .call(network.drag) |
178 | - .on('mouseover', function(d) {}) | 261 | + .on('mouseover', function(d) { |
179 | - .on('mouseout', function(d) {}); | 262 | + if (!selected.obj) { |
263 | + if (network.mouseoutTimeout) { | ||
264 | + clearTimeout(network.mouseoutTimeout); | ||
265 | + network.mouseoutTimeout = null; | ||
266 | + } | ||
267 | + highlightObject(d); | ||
268 | + } | ||
269 | + }) | ||
270 | + .on('mouseout', function(d) { | ||
271 | + if (!selected.obj) { | ||
272 | + if (network.mouseoutTimeout) { | ||
273 | + clearTimeout(network.mouseoutTimeout); | ||
274 | + network.mouseoutTimeout = null; | ||
275 | + } | ||
276 | + network.mouseoutTimeout = setTimeout(function() { | ||
277 | + highlightObject(null); | ||
278 | + }, 160); | ||
279 | + } | ||
280 | + }); | ||
180 | 281 | ||
181 | // TODO: augment stroke and fill functions | 282 | // TODO: augment stroke and fill functions |
182 | network.nodeRect = network.node.append('rect') | 283 | network.nodeRect = network.node.append('rect') |
183 | // TODO: css for node rects | 284 | // TODO: css for node rects |
184 | .attr('rx', 5) | 285 | .attr('rx', 5) |
185 | .attr('ry', 5) | 286 | .attr('ry', 5) |
186 | - .attr('stroke', function(d) { return '#000'}) | 287 | +// .attr('stroke', function(d) { return '#000'}) |
187 | - .attr('fill', function(d) { return '#ddf'}) | 288 | +// .attr('fill', function(d) { return '#ddf'}) |
188 | .attr('width', 60) | 289 | .attr('width', 60) |
189 | .attr('height', 24); | 290 | .attr('height', 24); |
190 | 291 | ... | ... |
... | @@ -13,7 +13,7 @@ body, html { | ... | @@ -13,7 +13,7 @@ body, html { |
13 | */ | 13 | */ |
14 | 14 | ||
15 | span.title { | 15 | span.title { |
16 | - color: red; | 16 | + color: darkblue; |
17 | font-size: 16pt; | 17 | font-size: 16pt; |
18 | font-style: italic; | 18 | font-style: italic; |
19 | } | 19 | } |
... | @@ -30,7 +30,7 @@ span.right { | ... | @@ -30,7 +30,7 @@ span.right { |
30 | * === DEBUGGING ====== | 30 | * === DEBUGGING ====== |
31 | */ | 31 | */ |
32 | svg { | 32 | svg { |
33 | - border: 1px dashed red; | 33 | + /*border: 1px dashed red;*/ |
34 | } | 34 | } |
35 | 35 | ||
36 | 36 | ||
... | @@ -64,36 +64,45 @@ marker#end { | ... | @@ -64,36 +64,45 @@ marker#end { |
64 | -moz-transition: opacity 250ms; | 64 | -moz-transition: opacity 250ms; |
65 | } | 65 | } |
66 | 66 | ||
67 | -.node text { | 67 | +/*differentiate between packet and optical nodes*/ |
68 | - fill: #000; | 68 | +svg .node.pkt rect { |
69 | + fill: #77a; | ||
70 | +} | ||
71 | + | ||
72 | +svg .node.opt rect { | ||
73 | + fill: #7a7; | ||
74 | +} | ||
75 | + | ||
76 | +svg .node text { | ||
77 | + fill: white; | ||
69 | font: 10px sans-serif; | 78 | font: 10px sans-serif; |
70 | pointer-events: none; | 79 | pointer-events: none; |
71 | } | 80 | } |
72 | 81 | ||
73 | -.node.selected rect { | 82 | +svg .node.selected rect { |
74 | filter: url(#blue-glow); | 83 | filter: url(#blue-glow); |
75 | } | 84 | } |
76 | 85 | ||
77 | -.link.inactive, | 86 | +svg .link.inactive, |
78 | -.node.inactive rect, | 87 | +svg .node.inactive rect, |
79 | -.node.inactive text { | 88 | +svg .node.inactive text { |
80 | opacity: .2; | 89 | opacity: .2; |
81 | } | 90 | } |
82 | 91 | ||
83 | -.node.inactive.selected rect, | 92 | +svg .node.inactive.selected rect, |
84 | -.node.inactive.selected text { | 93 | +svg .node.inactive.selected text { |
85 | opacity: .6; | 94 | opacity: .6; |
86 | } | 95 | } |
87 | 96 | ||
88 | -.legend { | 97 | +svg .legend { |
89 | position: fixed; | 98 | position: fixed; |
90 | } | 99 | } |
91 | 100 | ||
92 | -.legend .category rect { | 101 | +svg .legend .category rect { |
93 | stroke-width: 1px; | 102 | stroke-width: 1px; |
94 | } | 103 | } |
95 | 104 | ||
96 | -.legend .category text { | 105 | +svg .legend .category text { |
97 | fill: #000; | 106 | fill: #000; |
98 | font: 10px sans-serif; | 107 | font: 10px sans-serif; |
99 | pointer-events: none; | 108 | pointer-events: none; |
... | @@ -110,15 +119,15 @@ marker#end { | ... | @@ -110,15 +119,15 @@ marker#end { |
110 | #frame { | 119 | #frame { |
111 | width: 100%; | 120 | width: 100%; |
112 | height: 100%; | 121 | height: 100%; |
113 | - background-color: #ffd; | 122 | + background-color: #cdf; |
114 | } | 123 | } |
115 | 124 | ||
116 | #mast { | 125 | #mast { |
117 | height: 32px; | 126 | height: 32px; |
118 | - background-color: #dda; | 127 | + background-color: #abe; |
119 | vertical-align: baseline; | 128 | vertical-align: baseline; |
120 | } | 129 | } |
121 | 130 | ||
122 | #main { | 131 | #main { |
123 | - background-color: #99b; | 132 | + background-color: #99c; |
124 | } | 133 | } | ... | ... |
-
Please register or login to post a comment