@@ -78,9 +78,9 @@ module.exports = function draw(gd) {
7878 'shape-rendering' : 'crispEdges'
7979 } ) ;
8080
81- bg . call ( Color . stroke , opts . bordercolor ) ;
82- bg . call ( Color . fill , opts . bgcolor ) ;
83- bg . style ( 'stroke-width' , opts . borderwidth + 'px' ) ;
81+ bg . call ( Color . stroke , opts . bordercolor )
82+ . call ( Color . fill , opts . bgcolor )
83+ . style ( 'stroke-width' , opts . borderwidth + 'px' ) ;
8484
8585 var scrollBox = legend . selectAll ( 'g.scrollbox' )
8686 . data ( [ 0 ] ) ;
@@ -94,10 +94,10 @@ module.exports = function draw(gd) {
9494 scrollBar . enter ( ) . append ( 'rect' )
9595 . attr ( {
9696 'class' : 'scrollbar' ,
97- 'rx' : 20 ,
98- 'ry' : 2 ,
99- ' width' : 0 ,
100- ' height' : 0
97+ rx : 20 ,
98+ ry : 3 ,
99+ width : 0 ,
100+ height : 0
101101 } )
102102 . call ( Color . fill , '#808BA4' ) ;
103103
@@ -207,12 +207,9 @@ 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 ;
210+ // to be safe, remove previous listeners
211+ scrollBar . on ( '.drag' , null ) ;
212+ legend . on ( 'wheel' , null ) ;
216213
217214 if ( opts . _height <= legendHeight || gd . _context . staticPlot ) {
218215 // if scrollbar should not be shown.
@@ -232,11 +229,21 @@ module.exports = function draw(gd) {
232229 y : opts . borderwidth
233230 } ) ;
234231
235- scrollBox . call ( Drawing . setClipUrl , clipId ) ;
232+ Drawing . setClipUrl ( scrollBox , clipId ) ;
233+
234+ Drawing . setRect ( scrollBar , 0 , 0 , 0 , 0 ) ;
235+ delete opts . _scrollY ;
236236 }
237237 else {
238- scrollBarY = constants . scrollBarMargin ,
239- scrollBoxY = scrollBox . attr ( 'data-scroll' ) || 0 ;
238+ var scrollBarHeight = Math . max ( constants . scrollBarMinHeight ,
239+ legendHeight * legendHeight / opts . _height ) ;
240+ var scrollBarYMax = legendHeight -
241+ scrollBarHeight -
242+ 2 * constants . scrollBarMargin ;
243+ var scrollBoxYMax = opts . _height - legendHeight ;
244+ var scrollRatio = scrollBarYMax / scrollBoxYMax ;
245+
246+ var scrollBoxY = Math . min ( opts . _scrollY || 0 , scrollBoxYMax ) ;
240247
241248 // increase the background and clip-path width
242249 // by the scrollbar width and margin
@@ -257,60 +264,58 @@ module.exports = function draw(gd) {
257264 constants . scrollBarMargin ,
258265 height : legendHeight - 2 * opts . borderwidth ,
259266 x : opts . borderwidth ,
260- y : opts . borderwidth - scrollBoxY
267+ y : opts . borderwidth + scrollBoxY
261268 } ) ;
262269
263- scrollBox . call ( Drawing . setClipUrl , clipId ) ;
270+ Drawing . setClipUrl ( scrollBox , clipId ) ;
264271
265- if ( firstRender ) scrollHandler ( scrollBarY , scrollBoxY ) ;
272+ scrollHandler ( scrollBoxY , scrollBarHeight , scrollRatio ) ;
266273
267- legend . on ( 'wheel' , null ) ; // to be safe, remove previous listeners
268274 legend . on ( 'wheel' , function ( ) {
269275 scrollBoxY = Lib . constrain (
270- scrollBox . attr ( 'data-scroll' ) -
276+ opts . _scrollY +
271277 d3 . event . deltaY / scrollBarYMax * scrollBoxYMax ,
272- - scrollBoxYMax , 0 ) ;
273- scrollBarY = constants . scrollBarMargin -
274- scrollBoxY / scrollBoxYMax * scrollBarYMax ;
275- scrollHandler ( scrollBarY , scrollBoxY ) ;
276- if ( scrollBoxY !== 0 && scrollBoxY !== - scrollBoxYMax ) {
278+ 0 , scrollBoxYMax ) ;
279+ scrollHandler ( scrollBoxY , scrollBarHeight , scrollRatio ) ;
280+ if ( scrollBoxY !== 0 && scrollBoxY !== scrollBoxYMax ) {
277281 d3 . event . preventDefault ( ) ;
278282 }
279283 } ) ;
280284
281- // to be safe, remove previous listeners
282- scrollBar . on ( '.drag' , null ) ;
283- scrollBox . on ( '.drag' , null ) ;
285+ var eventY0 , scrollBoxY0 ;
284286
285- var drag = d3 . behavior . drag ( ) . on ( 'drag' , function ( ) {
286- scrollBarY = Lib . constrain (
287- d3 . event . y - constants . scrollBarHeight / 2 ,
288- constants . scrollBarMargin ,
289- constants . scrollBarMargin + scrollBarYMax ) ;
290- scrollBoxY = - ( scrollBarY - constants . scrollBarMargin ) /
291- scrollBarYMax * scrollBoxYMax ;
292- scrollHandler ( scrollBarY , scrollBoxY ) ;
287+ var drag = d3 . behavior . drag ( )
288+ . on ( 'dragstart' , function ( ) {
289+ eventY0 = d3 . event . sourceEvent . clientY ;
290+ scrollBoxY0 = scrollBoxY ;
291+ } )
292+ . on ( 'drag' , function ( ) {
293+ var e = d3 . event . sourceEvent ;
294+ if ( e . buttons === 2 || e . ctrlKey ) return ;
295+
296+ scrollBoxY = Lib . constrain (
297+ ( e . clientY - eventY0 ) / scrollRatio + scrollBoxY0 ,
298+ 0 , scrollBoxYMax ) ;
299+ scrollHandler ( scrollBoxY , scrollBarHeight , scrollRatio ) ;
293300 } ) ;
294301
295302 scrollBar . call ( drag ) ;
296- scrollBox . call ( drag ) ;
297303 }
298304
299305
300- function scrollHandler ( scrollBarY , scrollBoxY ) {
301- scrollBox
302- . attr ( 'data-scroll' , scrollBoxY )
303- . call ( Drawing . setTranslate , 0 , scrollBoxY ) ;
306+ function scrollHandler ( scrollBoxY , scrollBarHeight , scrollRatio ) {
307+ opts . _scrollY = gd . _fullLayout . legend . _scrollY = scrollBoxY ;
308+ Drawing . setTranslate ( scrollBox , 0 , - scrollBoxY ) ;
304309
305- scrollBar . call (
306- Drawing . setRect ,
310+ Drawing . setRect (
311+ scrollBar ,
307312 legendWidth ,
308- scrollBarY ,
313+ constants . scrollBarMargin + scrollBoxY * scrollRatio ,
309314 constants . scrollBarWidth ,
310- constants . scrollBarHeight
315+ scrollBarHeight
311316 ) ;
312317 clipPath . select ( 'rect' ) . attr ( {
313- y : opts . borderwidth - scrollBoxY
318+ y : opts . borderwidth + scrollBoxY
314319 } ) ;
315320 }
316321
@@ -434,7 +439,7 @@ function drawTexts(g, gd) {
434439 return Plotly . restyle ( gd , update , traceIndex ) ;
435440 } ) ;
436441 } else {
437- text . call ( textLayout ) ;
442+ textLayout ( text ) ;
438443 }
439444}
440445
@@ -664,7 +669,7 @@ function computeLegendDimensions(gd, groups, traces) {
664669 var legendItem = d [ 0 ] ,
665670 bg = d3 . select ( this ) . select ( '.legendtoggle' ) ;
666671
667- bg . call ( Drawing . setRect ,
672+ Drawing . setRect ( bg ,
668673 0 ,
669674 - legendItem . height / 2 ,
670675 ( gd . _context . edits . legendText ? 0 : opts . _width ) + extraWidth ,
0 commit comments