Skip to content

Commit 246b77f

Browse files
committed
make legend scrollbar scale to the visible fraction
fixes the legend part of #1859
1 parent ec42784 commit 246b77f

File tree

3 files changed

+34
-26
lines changed

3 files changed

+34
-26
lines changed

src/components/legend/constants.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
module.exports = {
1212
scrollBarWidth: 6,
13-
scrollBarHeight: 20,
13+
scrollBarMinHeight: 20,
1414
scrollBarColor: '#808BA4',
1515
scrollBarMargin: 4
1616
};

src/components/legend/draw.js

+14-14
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,6 @@ module.exports = function draw(gd) {
207207
// legend, background and border, scroll box and scroll bar
208208
Drawing.setTranslate(legend, lx, ly);
209209

210-
var scrollBarYMax = legendHeight -
211-
constants.scrollBarHeight -
212-
2 * constants.scrollBarMargin,
213-
scrollBoxYMax = opts._height - legendHeight,
214-
scrollBarY,
215-
scrollBoxY;
216-
217210
if(opts._height <= legendHeight || gd._context.staticPlot) {
218211
// if scrollbar should not be shown.
219212
bg.attr({
@@ -235,8 +228,15 @@ module.exports = function draw(gd) {
235228
scrollBox.call(Drawing.setClipUrl, clipId);
236229
}
237230
else {
238-
scrollBarY = constants.scrollBarMargin,
239-
scrollBoxY = scrollBox.attr('data-scroll') || 0;
231+
var scrollBarHeight = Math.max(constants.scrollBarMinHeight,
232+
legendHeight * legendHeight / opts._height);
233+
var scrollBarYMax = legendHeight -
234+
scrollBarHeight -
235+
2 * constants.scrollBarMargin;
236+
var scrollBoxYMax = opts._height - legendHeight;
237+
238+
var scrollBarY = constants.scrollBarMargin;
239+
var scrollBoxY = scrollBox.attr('data-scroll') || 0;
240240

241241
// increase the background and clip-path width
242242
// by the scrollbar width and margin
@@ -262,7 +262,7 @@ module.exports = function draw(gd) {
262262

263263
scrollBox.call(Drawing.setClipUrl, clipId);
264264

265-
if(firstRender) scrollHandler(scrollBarY, scrollBoxY);
265+
if(firstRender) scrollHandler(scrollBarY, scrollBoxY, scrollBarHeight);
266266

267267
legend.on('wheel', null); // to be safe, remove previous listeners
268268
legend.on('wheel', function() {
@@ -272,7 +272,7 @@ module.exports = function draw(gd) {
272272
-scrollBoxYMax, 0);
273273
scrollBarY = constants.scrollBarMargin -
274274
scrollBoxY / scrollBoxYMax * scrollBarYMax;
275-
scrollHandler(scrollBarY, scrollBoxY);
275+
scrollHandler(scrollBarY, scrollBoxY, scrollBarHeight);
276276
if(scrollBoxY !== 0 && scrollBoxY !== -scrollBoxYMax) {
277277
d3.event.preventDefault();
278278
}
@@ -299,14 +299,14 @@ module.exports = function draw(gd) {
299299
constants.scrollBarMargin + scrollBarYMax);
300300
scrollBoxY = - (scrollBarY - constants.scrollBarMargin) /
301301
scrollBarYMax * scrollBoxYMax;
302-
scrollHandler(scrollBarY, scrollBoxY);
302+
scrollHandler(scrollBarY, scrollBoxY, scrollBarHeight);
303303
});
304304

305305
scrollBar.call(drag);
306306
}
307307

308308

309-
function scrollHandler(scrollBarY, scrollBoxY) {
309+
function scrollHandler(scrollBarY, scrollBoxY, scrollBarHeight) {
310310
scrollBox
311311
.attr('data-scroll', scrollBoxY)
312312
.call(Drawing.setTranslate, 0, scrollBoxY);
@@ -316,7 +316,7 @@ module.exports = function draw(gd) {
316316
legendWidth,
317317
scrollBarY,
318318
constants.scrollBarWidth,
319-
constants.scrollBarHeight
319+
scrollBarHeight
320320
);
321321
clipPath.select('rect').attr({
322322
y: opts.borderwidth - scrollBoxY

test/jasmine/tests/legend_scroll_test.js

+19-11
Original file line numberDiff line numberDiff line change
@@ -138,27 +138,30 @@ describe('The legend', function() {
138138
var finalDataScroll = dragScroll(getScrollBar());
139139
var scrollBox = getScrollBox();
140140

141-
expect(scrollBox.getAttribute('data-scroll')).toBe(finalDataScroll);
141+
var dataScroll = scrollBox.getAttribute('data-scroll');
142+
expect(dataScroll).toBeCloseTo(finalDataScroll, 3);
142143
expect(scrollBox.getAttribute('transform')).toBe(
143-
'translate(0, ' + finalDataScroll + ')');
144+
'translate(0, ' + dataScroll + ')');
144145
});
145146

146147
it('should not scroll on dragging the scrollbox', function() {
147148
var scrollBox = getScrollBox();
148149
var finalDataScroll = dragScroll(scrollBox);
149150

150-
expect(scrollBox.getAttribute('data-scroll')).not.toBe(finalDataScroll);
151-
expect(scrollBox.getAttribute('transform')).not.toBe(
152-
'translate(0, ' + finalDataScroll + ')');
151+
var dataScroll = scrollBox.getAttribute('data-scroll');
152+
expect(dataScroll).not.toBeCloseTo(finalDataScroll, 3);
153+
expect(scrollBox.getAttribute('transform')).toBe(
154+
'translate(0, ' + dataScroll + ')');
153155
});
154156

155157
it('should not scroll on dragging the scrollbar with a right click', function() {
156158
var finalDataScroll = dragScroll(getScrollBar(), true);
157159
var scrollBox = getScrollBox();
158160

159-
expect(scrollBox.getAttribute('data-scroll')).not.toBe(finalDataScroll);
160-
expect(scrollBox.getAttribute('transform')).not.toBe(
161-
'translate(0, ' + finalDataScroll + ')');
161+
var dataScroll = scrollBox.getAttribute('data-scroll');
162+
expect(dataScroll).not.toBeCloseTo(finalDataScroll, 3);
163+
expect(scrollBox.getAttribute('transform')).toBe(
164+
'translate(0, ' + dataScroll + ')');
162165
});
163166

164167
it('should keep the scrollbar position after a toggle event', function(done) {
@@ -237,13 +240,18 @@ describe('The legend', function() {
237240
scrollBar = getScrollBar(),
238241
legendHeight = getLegendHeight(gd);
239242

240-
// The scrollbar is 20px tall and has 4px margins
243+
// The scrollbar is >20px tall and has 4px margins
244+
var scrollBarHeight = scrollBar.getBoundingClientRect().height;
245+
// in this mock there are 22 traces, and 13 are visible in the legend
246+
// at any given time
247+
expect(scrollBarHeight).toBeCloseTo(legendHeight * 13 / 22, -1);
241248

242249
legend.dispatchEvent(scrollTo(-1000));
243-
expect(+scrollBar.getAttribute('y')).toBe(4);
250+
expect(+scrollBar.getAttribute('y')).toBeCloseTo(4, 3);
244251

245252
legend.dispatchEvent(scrollTo(10000));
246-
expect(+scrollBar.getAttribute('y')).toBe(legendHeight - 4 - 20);
253+
expect(+scrollBar.getAttribute('y'))
254+
.toBeCloseTo(legendHeight - 4 - scrollBarHeight, 3);
247255
});
248256

249257
it('should be removed from DOM when \'showlegend\' is relayout\'ed to false', function(done) {

0 commit comments

Comments
 (0)