GUI -- Topo Panels now dynamically adjust their height to fit in the whole windo…
…w. Topo panel structure changed to have api for dynamic content to be added later. Change-Id: I70b272ca740efdf5392d8896271baef4a7cf97b5
Showing
2 changed files
with
164 additions
and
62 deletions
... | @@ -82,7 +82,7 @@ | ... | @@ -82,7 +82,7 @@ |
82 | 82 | ||
83 | #topo-p-detail { | 83 | #topo-p-detail { |
84 | /* Base css from panel.css */ | 84 | /* Base css from panel.css */ |
85 | - top: 320px; | 85 | + top: 310px; |
86 | } | 86 | } |
87 | 87 | ||
88 | #topo-p-detail .actionBtns .actionBtn { | 88 | #topo-p-detail .actionBtns .actionBtn { |
... | @@ -95,6 +95,10 @@ | ... | @@ -95,6 +95,10 @@ |
95 | 95 | ||
96 | /* --- general topo-panel styling --- */ | 96 | /* --- general topo-panel styling --- */ |
97 | 97 | ||
98 | +.topo-p div.body { | ||
99 | + overflow-y: scroll; | ||
100 | +} | ||
101 | + | ||
98 | .topo-p svg { | 102 | .topo-p svg { |
99 | display: inline-block; | 103 | display: inline-block; |
100 | width: 42px; | 104 | width: 42px; |
... | @@ -119,7 +123,9 @@ | ... | @@ -119,7 +123,9 @@ |
119 | 123 | ||
120 | .topo-p h2 { | 124 | .topo-p h2 { |
121 | position: absolute; | 125 | position: absolute; |
122 | - margin: 0 4px; | 126 | + padding: 0 4px; |
127 | + margin: 0; | ||
128 | + word-wrap: break-word; | ||
123 | top: 20px; | 129 | top: 20px; |
124 | left: 50px; | 130 | left: 50px; |
125 | } | 131 | } |
... | @@ -131,7 +137,9 @@ | ... | @@ -131,7 +137,9 @@ |
131 | } | 137 | } |
132 | 138 | ||
133 | .topo-p h3 { | 139 | .topo-p h3 { |
134 | - margin: 0 4px; | 140 | + padding: 0 4px; |
141 | + margin: 0; | ||
142 | + word-wrap: break-word; | ||
135 | top: 20px; | 143 | top: 20px; |
136 | left: 50px; | 144 | left: 50px; |
137 | } | 145 | } |
... | @@ -143,16 +151,19 @@ | ... | @@ -143,16 +151,19 @@ |
143 | } | 151 | } |
144 | 152 | ||
145 | .topo-p p, table { | 153 | .topo-p p, table { |
146 | - margin: 4px 4px; | 154 | + padding: 4px; |
155 | + margin: 0; | ||
147 | } | 156 | } |
148 | 157 | ||
158 | +.topo-p td { | ||
159 | + word-wrap: break-word; | ||
160 | +} | ||
149 | .topo-p td.label { | 161 | .topo-p td.label { |
150 | font-style: italic; | 162 | font-style: italic; |
151 | padding-right: 12px; | 163 | padding-right: 12px; |
152 | /* works for both light and dark themes ... */ | 164 | /* works for both light and dark themes ... */ |
153 | color: #777; | 165 | color: #777; |
154 | } | 166 | } |
155 | - | ||
156 | .topo-p td.value { | 167 | .topo-p td.value { |
157 | } | 168 | } |
158 | 169 | ... | ... |
... | @@ -33,14 +33,101 @@ | ... | @@ -33,14 +33,101 @@ |
33 | width: 260 | 33 | width: 260 |
34 | }; | 34 | }; |
35 | 35 | ||
36 | - // panels | ||
37 | - var summaryPanel, | ||
38 | - detailPanel; | ||
39 | - | ||
40 | // internal state | 36 | // internal state |
41 | var useDetails = true, // should we show details if we have 'em? | 37 | var useDetails = true, // should we show details if we have 'em? |
42 | haveDetails = false; // do we have details that we could show? | 38 | haveDetails = false; // do we have details that we could show? |
43 | 39 | ||
40 | + // panels | ||
41 | + var summary, detail; | ||
42 | + | ||
43 | + // === ----------------------------------------------------- | ||
44 | + // Panel API | ||
45 | + function createTopoPanel(id, opts) { | ||
46 | + var p = ps.createPanel(id, opts), | ||
47 | + header, body, footer; | ||
48 | + p.classed(pCls, true); | ||
49 | + | ||
50 | + function hAppend(x) { | ||
51 | + return header.append(x); | ||
52 | + } | ||
53 | + | ||
54 | + function bAppend(x) { | ||
55 | + return body.append(x); | ||
56 | + } | ||
57 | + | ||
58 | + function fAppend(x) { | ||
59 | + return footer.append(x); | ||
60 | + } | ||
61 | + | ||
62 | + function setup() { | ||
63 | + p.empty(); | ||
64 | + | ||
65 | + p.append('div').classed('header', true); | ||
66 | + p.append('div').classed('body', true); | ||
67 | + p.append('div').classed('footer', true); | ||
68 | + | ||
69 | + header = p.el().select('.header'); | ||
70 | + body = p.el().select('.body'); | ||
71 | + footer = p.el().select('.footer'); | ||
72 | + } | ||
73 | + | ||
74 | + // fromTop is how many pixels from the top of the page the panel is | ||
75 | + // max is the max height of the panel in pixels | ||
76 | + // only adjusts if the body content would be 10px or larger | ||
77 | + function adjustHeight(fromTop, max) { | ||
78 | + var totalPHeight, avSpace, | ||
79 | + overflow = 0, | ||
80 | + pdg = 30; | ||
81 | + | ||
82 | + if (!fromTop) { | ||
83 | + $log.warn('adjustHeight: height from top of page not given'); | ||
84 | + return null; | ||
85 | + } else if (!body || !p) { | ||
86 | + // if we have reached this function without setting a panel | ||
87 | + // sometimes the d3 tick function calls detail panel's 'up' | ||
88 | + // on reload when body isn't defined yet. | ||
89 | + $log.warn('adjustHeight: panel is not defined'); | ||
90 | + return null; | ||
91 | + } | ||
92 | + | ||
93 | + p.el().style('height', null); | ||
94 | + body.style('height', null); | ||
95 | + | ||
96 | + totalPHeight = fromTop + p.height(); | ||
97 | + avSpace = fs.windowSize(pdg).height; | ||
98 | + | ||
99 | + if (totalPHeight >= avSpace) { | ||
100 | + overflow = totalPHeight - avSpace; | ||
101 | + } | ||
102 | + | ||
103 | + function _adjustBody(height) { | ||
104 | + if (height < 10) { | ||
105 | + return false; | ||
106 | + } else { | ||
107 | + body.style('height', height + 'px'); | ||
108 | + } | ||
109 | + return true; | ||
110 | + } | ||
111 | + | ||
112 | + if (!_adjustBody(fs.noPxStyle(body, 'height') - overflow)) { | ||
113 | + return; | ||
114 | + } | ||
115 | + | ||
116 | + if (max && p.height() > max) { | ||
117 | + _adjustBody(fs.noPxStyle(body, 'height') - (p.height() - max)); | ||
118 | + } | ||
119 | + } | ||
120 | + | ||
121 | + return { | ||
122 | + panel: p, | ||
123 | + setup: setup, | ||
124 | + appendHeader: hAppend, | ||
125 | + appendBody: bAppend, | ||
126 | + appendFooter: fAppend, | ||
127 | + adjustHeight: adjustHeight | ||
128 | + }; | ||
129 | + } | ||
130 | + | ||
44 | // === ----------------------------------------------------- | 131 | // === ----------------------------------------------------- |
45 | // Utility functions | 132 | // Utility functions |
46 | 133 | ||
... | @@ -48,6 +135,11 @@ | ... | @@ -48,6 +135,11 @@ |
48 | tbody.append('tr').append('td').attr('colspan', 2).append('hr'); | 135 | tbody.append('tr').append('td').attr('colspan', 2).append('hr'); |
49 | } | 136 | } |
50 | 137 | ||
138 | + function addBtnFooter() { | ||
139 | + detail.appendFooter('hr'); | ||
140 | + detail.appendFooter('div').classed('actionBtns', true); | ||
141 | + } | ||
142 | + | ||
51 | function addProp(tbody, label, value) { | 143 | function addProp(tbody, label, value) { |
52 | var tr = tbody.append('tr'), | 144 | var tr = tbody.append('tr'), |
53 | lab; | 145 | lab; |
... | @@ -65,7 +157,7 @@ | ... | @@ -65,7 +157,7 @@ |
65 | } | 157 | } |
66 | 158 | ||
67 | function listProps(tbody, data) { | 159 | function listProps(tbody, data) { |
68 | - data.propOrder.forEach(function(p) { | 160 | + data.propOrder.forEach(function (p) { |
69 | if (p === '-') { | 161 | if (p === '-') { |
70 | addSep(tbody); | 162 | addSep(tbody); |
71 | } else { | 163 | } else { |
... | @@ -74,23 +166,15 @@ | ... | @@ -74,23 +166,15 @@ |
74 | }); | 166 | }); |
75 | } | 167 | } |
76 | 168 | ||
77 | - function dpa(x) { | ||
78 | - return detailPanel.append(x); | ||
79 | - } | ||
80 | - | ||
81 | - function spa(x) { | ||
82 | - return summaryPanel.append(x); | ||
83 | - } | ||
84 | - | ||
85 | // === ----------------------------------------------------- | 169 | // === ----------------------------------------------------- |
86 | // Functions for populating the summary panel | 170 | // Functions for populating the summary panel |
87 | 171 | ||
88 | function populateSummary(data) { | 172 | function populateSummary(data) { |
89 | - summaryPanel.empty(); | 173 | + summary.setup(); |
90 | 174 | ||
91 | - var svg = spa('svg'), | 175 | + var svg = summary.appendHeader('svg'), |
92 | - title = spa('h2'), | 176 | + title = summary.appendHeader('h2'), |
93 | - table = spa('table'), | 177 | + table = summary.appendBody('table'), |
94 | tbody = table.append('tbody'); | 178 | tbody = table.append('tbody'); |
95 | 179 | ||
96 | gs.addGlyph(svg, 'node', 40); | 180 | gs.addGlyph(svg, 'node', 40); |
... | @@ -104,33 +188,31 @@ | ... | @@ -104,33 +188,31 @@ |
104 | // Functions for populating the detail panel | 188 | // Functions for populating the detail panel |
105 | 189 | ||
106 | function displaySingle(data) { | 190 | function displaySingle(data) { |
107 | - detailPanel.empty(); | 191 | + detail.setup(); |
108 | 192 | ||
109 | - var svg = dpa('svg'), | 193 | + var svg = detail.appendHeader('svg'), |
110 | - title = dpa('h2'), | 194 | + title = detail.appendHeader('h2'), |
111 | - table = dpa('table'), | 195 | + table = detail.appendBody('table'), |
112 | tbody = table.append('tbody'); | 196 | tbody = table.append('tbody'); |
113 | 197 | ||
114 | gs.addGlyph(svg, (data.type || 'unknown'), 40); | 198 | gs.addGlyph(svg, (data.type || 'unknown'), 40); |
115 | title.text(data.id); | 199 | title.text(data.id); |
116 | listProps(tbody, data); | 200 | listProps(tbody, data); |
117 | - dpa('hr'); | 201 | + addBtnFooter(); |
118 | - dpa('div').classed('actionBtns', true); | ||
119 | } | 202 | } |
120 | 203 | ||
121 | function displayMulti(ids) { | 204 | function displayMulti(ids) { |
122 | - detailPanel.empty(); | 205 | + detail.setup(); |
123 | 206 | ||
124 | - var title = dpa('h3'), | 207 | + var title = detail.appendHeader('h3'), |
125 | - table = dpa('table'), | 208 | + table = detail.appendBody('table'), |
126 | tbody = table.append('tbody'); | 209 | tbody = table.append('tbody'); |
127 | 210 | ||
128 | title.text('Selected Nodes'); | 211 | title.text('Selected Nodes'); |
129 | ids.forEach(function (d, i) { | 212 | ids.forEach(function (d, i) { |
130 | addProp(tbody, i+1, d); | 213 | addProp(tbody, i+1, d); |
131 | }); | 214 | }); |
132 | - dpa('hr'); | 215 | + addBtnFooter(); |
133 | - dpa('div').classed('actionBtns', true); | ||
134 | } | 216 | } |
135 | 217 | ||
136 | function addAction(o) { | 218 | function addAction(o) { |
... | @@ -177,11 +259,11 @@ | ... | @@ -177,11 +259,11 @@ |
177 | ]; | 259 | ]; |
178 | 260 | ||
179 | function displayLink(data) { | 261 | function displayLink(data) { |
180 | - detailPanel.empty(); | 262 | + detail.setup(); |
181 | 263 | ||
182 | - var svg = dpa('svg'), | 264 | + var svg = detail.appendHeader('svg'), |
183 | - title = dpa('h2'), | 265 | + title = detail.appendHeader('h2'), |
184 | - table = dpa('table'), | 266 | + table = detail.appendBody('table'), |
185 | tbody = table.append('tbody'), | 267 | tbody = table.append('tbody'), |
186 | edgeLink = data.type() === 'hostLink', | 268 | edgeLink = data.type() === 'hostLink', |
187 | order = edgeLink ? edgeOrder : coreOrder; | 269 | order = edgeLink ? edgeOrder : coreOrder; |
... | @@ -235,7 +317,7 @@ | ... | @@ -235,7 +317,7 @@ |
235 | 317 | ||
236 | function toggleSummary(x) { | 318 | function toggleSummary(x) { |
237 | var kev = (x === 'keyev'), | 319 | var kev = (x === 'keyev'), |
238 | - on = kev ? !summaryPanel.isVisible() : !!x, | 320 | + on = kev ? !summary.panel.isVisible() : !!x, |
239 | verb = on ? 'Show' : 'Hide'; | 321 | verb = on ? 'Show' : 'Hide'; |
240 | 322 | ||
241 | if (on) { | 323 | if (on) { |
... | @@ -253,29 +335,33 @@ | ... | @@ -253,29 +335,33 @@ |
253 | // === LOGIC For showing/hiding summary and detail panels... | 335 | // === LOGIC For showing/hiding summary and detail panels... |
254 | 336 | ||
255 | function showSummaryPanel() { | 337 | function showSummaryPanel() { |
256 | - if (detailPanel.isVisible()) { | 338 | + function _show() { |
257 | - detailPanel.down(summaryPanel.show); | 339 | + summary.panel.show(); |
340 | + summary.adjustHeight(64, 226); | ||
341 | + } | ||
342 | + if (detail.panel.isVisible()) { | ||
343 | + detail.down(_show); | ||
258 | } else { | 344 | } else { |
259 | - summaryPanel.show(); | 345 | + _show(); |
260 | } | 346 | } |
261 | } | 347 | } |
262 | 348 | ||
263 | function hideSummaryPanel() { | 349 | function hideSummaryPanel() { |
264 | // instruct server to stop sending summary data | 350 | // instruct server to stop sending summary data |
265 | wss.sendEvent("cancelSummary"); | 351 | wss.sendEvent("cancelSummary"); |
266 | - summaryPanel.hide(detailPanel.up); | 352 | + summary.panel.hide(detail.up); |
267 | } | 353 | } |
268 | 354 | ||
269 | function showDetailPanel() { | 355 | function showDetailPanel() { |
270 | - if (summaryPanel.isVisible()) { | 356 | + if (summary.panel.isVisible()) { |
271 | - detailPanel.down(detailPanel.show); | 357 | + detail.down(detail.panel.show); |
272 | } else { | 358 | } else { |
273 | - detailPanel.up(detailPanel.show); | 359 | + detail.up(detail.panel.show); |
274 | } | 360 | } |
275 | } | 361 | } |
276 | 362 | ||
277 | function hideDetailPanel() { | 363 | function hideDetailPanel() { |
278 | - detailPanel.hide(); | 364 | + detail.panel.hide(); |
279 | } | 365 | } |
280 | 366 | ||
281 | // ========================== | 367 | // ========================== |
... | @@ -283,15 +369,15 @@ | ... | @@ -283,15 +369,15 @@ |
283 | function noop () {} | 369 | function noop () {} |
284 | 370 | ||
285 | function augmentDetailPanel() { | 371 | function augmentDetailPanel() { |
286 | - var dp = detailPanel; | 372 | + var d = detail; |
287 | - dp.ypos = { up: 64, down: 320, current: 320}; | 373 | + d.ypos = { up: 64, down: 310, current: 310}; |
288 | 374 | ||
289 | - dp._move = function (y, cb) { | 375 | + d._move = function (y, cb) { |
290 | var endCb = fs.isF(cb) || noop, | 376 | var endCb = fs.isF(cb) || noop, |
291 | - yp = dp.ypos; | 377 | + yp = d.ypos; |
292 | if (yp.current !== y) { | 378 | if (yp.current !== y) { |
293 | yp.current = y; | 379 | yp.current = y; |
294 | - dp.el().transition().duration(300) | 380 | + d.panel.el().transition().duration(300) |
295 | .each('end', endCb) | 381 | .each('end', endCb) |
296 | .style('top', yp.current + 'px'); | 382 | .style('top', yp.current + 'px'); |
297 | } else { | 383 | } else { |
... | @@ -299,8 +385,15 @@ | ... | @@ -299,8 +385,15 @@ |
299 | } | 385 | } |
300 | }; | 386 | }; |
301 | 387 | ||
302 | - dp.down = function (cb) { dp._move(dp.ypos.down, cb); }; | 388 | + // d.up is being called on the tick function for some reason |
303 | - dp.up = function (cb) { dp._move(dp.ypos.up, cb); }; | 389 | + d.down = function (cb) { |
390 | + d._move(d.ypos.down, cb); | ||
391 | + detail.adjustHeight(d.ypos.current); | ||
392 | + }; | ||
393 | + d.up = function (cb) { | ||
394 | + d._move(d.ypos.up, cb); | ||
395 | + detail.adjustHeight(d.ypos.current); | ||
396 | + }; | ||
304 | } | 397 | } |
305 | 398 | ||
306 | function toggleUseDetailsFlag(x) { | 399 | function toggleUseDetailsFlag(x) { |
... | @@ -324,11 +417,8 @@ | ... | @@ -324,11 +417,8 @@ |
324 | // ========================== | 417 | // ========================== |
325 | 418 | ||
326 | function initPanels() { | 419 | function initPanels() { |
327 | - summaryPanel = ps.createPanel(idSum, panelOpts); | 420 | + summary = createTopoPanel(idSum, panelOpts); |
328 | - detailPanel = ps.createPanel(idDet, panelOpts); | 421 | + detail = createTopoPanel(idDet, panelOpts); |
329 | - | ||
330 | - summaryPanel.classed(pCls, true); | ||
331 | - detailPanel.classed(pCls, true); | ||
332 | 422 | ||
333 | augmentDetailPanel(); | 423 | augmentDetailPanel(); |
334 | } | 424 | } |
... | @@ -336,7 +426,7 @@ | ... | @@ -336,7 +426,7 @@ |
336 | function destroyPanels() { | 426 | function destroyPanels() { |
337 | ps.destroyPanel(idSum); | 427 | ps.destroyPanel(idSum); |
338 | ps.destroyPanel(idDet); | 428 | ps.destroyPanel(idDet); |
339 | - summaryPanel = detailPanel = null; | 429 | + summary.panel = detail.panel = null; |
340 | haveDetails = false; | 430 | haveDetails = false; |
341 | } | 431 | } |
342 | 432 | ||
... | @@ -359,6 +449,7 @@ | ... | @@ -359,6 +449,7 @@ |
359 | return { | 449 | return { |
360 | initPanels: initPanels, | 450 | initPanels: initPanels, |
361 | destroyPanels: destroyPanels, | 451 | destroyPanels: destroyPanels, |
452 | + createTopoPanel: createTopoPanel, | ||
362 | 453 | ||
363 | showSummary: showSummary, | 454 | showSummary: showSummary, |
364 | toggleSummary: toggleSummary, | 455 | toggleSummary: toggleSummary, |
... | @@ -366,15 +457,15 @@ | ... | @@ -366,15 +457,15 @@ |
366 | toggleUseDetailsFlag: toggleUseDetailsFlag, | 457 | toggleUseDetailsFlag: toggleUseDetailsFlag, |
367 | displaySingle: displaySingle, | 458 | displaySingle: displaySingle, |
368 | displayMulti: displayMulti, | 459 | displayMulti: displayMulti, |
369 | - addAction: addAction, | ||
370 | displayLink: displayLink, | 460 | displayLink: displayLink, |
371 | displayNothing: displayNothing, | 461 | displayNothing: displayNothing, |
372 | displaySomething: displaySomething, | 462 | displaySomething: displaySomething, |
463 | + addAction: addAction, | ||
373 | 464 | ||
374 | hideSummaryPanel: hideSummaryPanel, | 465 | hideSummaryPanel: hideSummaryPanel, |
375 | 466 | ||
376 | - detailVisible: function () { return detailPanel.isVisible(); }, | 467 | + detailVisible: function () { return detail.panel.isVisible(); }, |
377 | - summaryVisible: function () { return summaryPanel.isVisible(); } | 468 | + summaryVisible: function () { return summary.panel.isVisible(); } |
378 | }; | 469 | }; |
379 | }]); | 470 | }]); |
380 | }()); | 471 | }()); | ... | ... |
-
Please register or login to post a comment