8000 updatemenus: remove un/foldDropdownMenu · transforminteractive/plotly.js@3b17d1d · GitHub
[go: up one dir, main page]

Skip to content

Commit 3b17d1d

Browse files
committed
updatemenus: remove un/foldDropdownMenu
* Fixes issues caused by the relayout tests, where `updatemenus[1]` ended up without a buttons field. * A transition has been added to show and hide the scroll bars.
1 parent 4975401 commit 3b17d1d

File tree

1 file changed

+131
-98
lines changed

1 file changed

+131
-98
lines changed

src/components/updatemenus/draw.js

Lines changed: 131 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,17 @@ module.exports = function draw(gd) {
9696

9797
// remove exiting header, remove dropped buttons and reset margins
9898
if(headerGroups.enter().size()) {
99-
foldDropdownMenu(gButton, scrollBox);
99+
gButton
100+
.call(removeAllButtons)
101+
.attr(constants.menuIndexAttrName, '-1');
100102
}
101103

102104
headerGroups.exit().each(function(menuOpts) {
103105
d3.select(this).remove();
104106

105-
foldDropdownMenu(gButton, scrollBox);
107+
gButton
108+
.call(removeAllButtons)
109+
.attr(constants.menuIndexAttrName, '-1');
106110

107111
Plots.autoMargin(gd, constants.autoMarginIdRoot + menuOpts._index);
108112
});
@@ -119,12 +123,12 @@ module.exports = function draw(gd) {
119123
if(menuOpts.type === 'dropdown') {
120124
drawHeader(gd, gHeader, gButton, scrollBox, menuOpts);
121125

122-
// update dropdown buttons if this menu is active
126+
// if this menu is active, update the dropdown container
123127
if(isActive(gButton, menuOpts)) {
124-
unfoldDropdownMenu(gd, gHeader, gButton, scrollBox, menuOpts);
128+
drawButtons(gd, gHeader, gButton, scrollBox, menuOpts);
125129
}
126130
} else {
127-
drawButtons(gd, gHeader, null, scrollBox, menuOpts);
131+
drawButtons(gd, gHeader, null, null, menuOpts);
128132
}
129133

130134
});
@@ -163,86 +167,22 @@ function isActive(gButton, menuOpts) {
163167
return +gButton.attr(constants.menuIndexAttrName) === menuOpts._index;
164168
}
165169

166-
function unfoldDropdownMenu(gd, gHeader, gButton, scrollBox, menuOpts) {
167-
// enable the scrollbox
168-
var direction = menuOpts.direction,
169-
isUp = (direction === 'up'),
170-
isDown = (direction === 'down'),
171-
isLeft = (direction === 'left'),
172-
isRight = (direction === 'right'),
173-
isVertical = (isUp || isDown);
174-
175-
var x0, y0;
176-
if(isDown) {
177-
x0 = 0;
178-
y0 = menuOpts.headerHeight + constants.gapButtonHeader;
179-
}
180-
else if(isUp) {
181-
x0 = 0;
182-
y0 = menuOpts.headerHeight + constants.gapButton - menuOpts.openHeight;
183-
}
184-
else if(isRight) {
185-
x0 = menuOpts.headerWidth + constants.gapButtonHeader;
186-
y0 = 0;
187-
}
188-
else if(isLeft) {
189-
x0 = menuOpts.headerWidth + constants.gapButton - menuOpts.openWidth;
190-
y0 = 0;
191-
}
192-
193-
var position = {
194-
l: menuOpts.lx + menuOpts.borderwidth + x0 + menuOpts.pad.l,
195-
t: menuOpts.ly + menuOpts.borderwidth + y0 + menuOpts.pad.t,
196-
w: Math.max(menuOpts.openWidth, menuOpts.headerWidth),
197-
h: menuOpts.openHeight
198-
};
199-
200-
var active = menuOpts.active,
201-
translateX, translateY,
202-
i;
203-
if(isVertical) {
204-
translateY = 0;
205-
for(i = 0; i < active; i++) {
206-
translateY += menuOpts.heights[i] + constants.gapButton;
207-
}
208-
}
209-
else {
210-
translateX = 0;
211-
for(i = 0; i < active; i++) {
212-
translateX += menuOpts.widths[i] + constants.gapButton;
213-
}
214-
}
215-
216-
scrollBox.enable(position, translateX, translateY);
217-
218-
// store index of active menu (-1 means dropdown menu is folded)
219-
gButton.attr(constants.menuIndexAttrName, menuOpts._index);
220-
221-
drawButtons(gd, gHeader, gButton, scrollBox, menuOpts);
222-
}
223-
224-
function foldDropdownMenu(gButton, scrollBox) {
225-
scrollBox.disable();
226-
227-
// -1 means dropdown menu is folded
228-
gButton
229-
.attr(constants.menuIndexAttrName, '-1')
230-
.call(removeAllButtons);
231-
}
232-
233170
function setActive(gd, menuOpts, buttonOpts, gHeader, gButton, scrollBox, buttonIndex, isSilentUpdate) {
234171
// update 'active' attribute in menuOpts
235172
menuOpts._input.active = menuOpts.active = buttonIndex;
236173

237-
if(menuOpts.type === 'dropdown') {
174+
if(menuOpts.type === 'buttons') {
175+
drawButtons(gd, gHeader, null, null, menuOpts);
176+
}
177+
else if(menuOpts.type === 'dropdown') {
238178
// fold up buttons and redraw header
239179
gButton.attr(constants.menuIndexAttrName, '-1');
240180

241181
drawHeader(gd, gHeader, gButton, scrollBox, menuOpts);
242-
}
243182

244-
if(!isSilentUpdate || menuOpts.type === 'buttons') {
245-
drawButtons(gd, gHeader, gButton, scrollBox, menuOpts);
183+
if(!isSilentUpdate) {
184+
drawButtons(gd, gHeader, gButton, scrollBox, menuOpts);
185+
}
246186
}
247187
}
248188

@@ -283,18 +223,19 @@ function drawHeader(gd, gHeader, gButton, scrollBox, menuOpts) {
283223
});
284224

285225
header.on('click', function() {
286-
if(isFolded(gButton)) {
287-
unfoldDropdownMenu(gd, gHeader, gButton, scrollBox, menuOpts);
288-
}
289-
else if(isActive(gButton, menuOpts)) {
290-
foldDropdownMenu(gButton, scrollBox);
291-
}
292-
else {
293-
// the dropdown menu is unfolded,
294-
// but the clicked header is not the active header
295-
foldDropdownMenu(gButton, scrollBox);
296-
unfoldDropdownMenu(gd, gHeader, gButton, scrollBox, menuOpts);
297-
}
226+
gButton.call(removeAllButtons);
227+
228+
229+
// if this menu is active, fold the dropdown container
230+
// otherwise, make this menu active
231+
gButton.attr(
232+
constants.menuIndexAttrName,
233+
isActive(gButton, menuOpts) ?
234+
-1 :
235+
String(menuOpts._index)
236+
);
237+
238+
drawButtons(gd, gHeader, gButton, scrollBox, menuOpts);
298239
});
299240

300241
header.on('mouseover', function() {
@@ -339,20 +280,11 @@ function drawButtons(gd, gHeader, gButton, scrollBox, menuOpts) {
339280

340281
exit.transition()
341282
.attr('opacity', '0')
342-
.remove()
343-
.each('end', function() {
344-
// remove the scrollbox, if all the buttons have been removed
345-
if(gButton.selectAll('g.' + klass).size() === 0) {
346-
foldDropdownMenu(gButton, scrollBox);
347-
}
348-
});
283+
.remove();
349284
} else {
350285
exit.remove();
351286
}
352287

353-
// if folding a dropdown menu, don't draw the buttons
354-
if(!buttons.size()) return;
355-
356288
var x0 = 0;
357289
var y0 = 0;
358290

@@ -411,6 +343,107 @@ function drawButtons(gd, gHeader, gButton, scrollBox, menuOpts) {
411343
});
412344

413345
buttons.call(styleButtons, menuOpts);
346+
347+
if(scrollBox) {
348+
if(buttons.size()) {
349+
drawScrollBox(gd, gHeader, gButton, scrollBox, menuOpts);
350+
}
351+
else {
352+
hideScrollBox(scrollBox);
353+
}
354+
}
355+
}
356+
357+
function drawScrollBox(gd, gHeader, gButton, scrollBox, menuOpts) {
358+
// enable the scrollbox
359+
var direction = menuOpts.direction,
360+
isUp = (direction === 'up'),
361+
isDown = (direction === 'down'),
362+
isLeft = (direction === 'left'),
363+
isRight = (direction === 'right'),
364+
isVertical = (isUp || isDown);
365+
366+
var x0, y0;
367+
if(isDown) {
368+
x0 = 0;
369+
y0 = menuOpts.headerHeight + constants.gapButtonHeader;
370+
}
371+
else if(isUp) {
372+
x0 = 0;
373+
y0 = menuOpts.headerHeight + constants.gapButton - menuOpts.openHeight;
374+
}
375+
else if(isRight) {
376+
x0 = menuOpts.headerWidth + constants.gapButtonHeader;
377+
y0 = 0;
378+
}
379+
else if(isLeft) {
380+
x0 = menuOpts.headerWidth + constants.gapButton - menuOpts.openWidth;
381+
y0 = 0;
382+
}
383+
384+
var position = {
385+
l: menuOpts.lx + menuOpts.borderwidth + x0 + menuOpts.pad.l,
386+
t: menuOpts.ly + menuOpts.borderwidth + y0 + menuOpts.pad.t,
387+
w: Math.max(menuOpts.openWidth, menuOpts.headerWidth),
388+
h: menuOpts.openHeight
389+
};
390+
391+
var active = menuOpts.active,
392+
translateX, translateY,
393+
i;
394+
if(isVertical) {
395+
translateY = 0;
396+
for(i = 0; i < active; i++) {
397+
translateY += menuOpts.heights[i] + constants.gapButton;
398+
}
399+
}
400+
else {
401+
translateX = 0;
402+
for(i = 0; i < active; i++) {
403+
translateX += menuOpts.widths[i] + constants.gapButton;
404+
}
405+
}
406+
407+
scrollBox.enable(position, translateX, translateY);
408+
409+
if(scrollBox.hbar) {
410+
scrollBox.hbar
411+
.attr('opacity', '0')
412+
.transition()
413+
.attr('opacity', '1');
414+
}
415+
416+
if(scrollBox.vbar) {
417+
scrollBox.vbar
418+
.attr('opacity', '0')
419+
.transition()
420+
.attr('opacity', '1');
421+
}
422+
}
423+
424+
function hideScrollBox(scrollBox) {
425+
var hasHBar = !!scrollBox.hbar,
426+
hasVBar = !!scrollBox.vbar;
427+
428+
if(hasHBar) {
429+
scrollBox.hbar
430+
.transition()
431+
.attr('opacity', '0')
432+
.each('end', function() {
433+
hasHBar = false;
434+
if(!hasVBar) scrollBox.disable();
435+
});
436+
}
437+
438+
if(hasVBar) {
439+
scrollBox.vbar
440+
.transition()
441+
.attr('opacity', '0')
442+
.each('end', function() {
443+
hasVBar = false;
444+
if(!hasHBar) scrollBox.disable();
445+
});
446+
}
414447
}
415448

416449
function drawItem(item, menuOpts, itemOpts) {

0 commit comments

Comments
 (0)
0