@@ -18,7 +18,10 @@ var svgTextUtils = require('../../lib/svg_text_utils');
18
18
var anchorUtils = require ( '../legend/anchor_utils' ) ;
19
19
20
20
var constants = require ( './constants' ) ;
21
- var LINE_SPACING = require ( '../../constants/alignment' ) . LINE_SPACING ;
21
+ var alignmentConstants = require ( '../../constants/alignment' ) ;
22
+ var LINE_SPACING = alignmentConstants . LINE_SPACING ;
23
+ var FROM_TL = alignmentConstants . FROM_TL ;
24
+ var FROM_BR = alignmentConstants . FROM_BR ;
22
25
23
26
24
27
module . exports = function draw ( gd ) {
@@ -98,7 +101,7 @@ function makeSliderData(fullLayout, gd) {
98
101
for ( var i = 0 ; i < contOpts . length ; i ++ ) {
99
102
var item = contOpts [ i ] ;
100
103
if ( ! item . visible || ! item . steps . length ) continue ;
101
- item . gd = gd ;
104
+ item . _gd = gd ;
102
105
sliderData . push ( item ) ;
103
106
}
104
107
@@ -136,45 +139,43 @@ function findDimensions(gd, sliderOpts) {
136
139
137
140
sliderLabels . remove ( ) ;
138
141
139
- sliderOpts . inputAreaWidth = Math . max (
142
+ var dims = sliderOpts . _dims = { } ;
143
+
144
+ dims . inputAreaWidth = Math . max (
140
145
constants . railWidth ,
141
146
constants . gripHeight
142
147
) ;
143
148
144
149
// calculate some overall dimensions - some of these are needed for
145
150
// calculating the currentValue dimensions
146
151
var graphSize = gd . _fullLayout . _size ;
147
- sliderOpts . lx = graphSize . l + graphSize . w * sliderOpts . x ;
148
- sliderOpts . ly = graphSize . t + graphSize . h * ( 1 - sliderOpts . y ) ;
152
+ dims . lx = graphSize . l + graphSize . w * sliderOpts . x ;
153
+ dims . ly = graphSize . t + graphSize . h * ( 1 - sliderOpts . y ) ;
149
154
150
155
if ( sliderOpts . lenmode === 'fraction' ) {
151
156
// fraction:
152
- sliderOpts . outerLength = Math . round ( graphSize . w * sliderOpts . len ) ;
157
+ dims . outerLength = Math . round ( graphSize . w * sliderOpts . len ) ;
153
158
} else {
154
159
// pixels:
155
- sliderOpts . outerLength = sliderOpts . len ;
160
+ dims . outerLength = sliderOpts . len ;
156
161
}
157
162
158
- // Set the length-wise padding so that the grip ends up *on* the end of
159
- // the bar when at either extreme
160
- sliderOpts . lenPad = Math . round ( constants . gripWidth * 0.5 ) ;
161
-
162
163
// The length of the rail, *excluding* padding on either end:
163
- sliderOpts . inputAreaStart = 0 ;
164
- sliderOpts . inputAreaLength = Math . round ( sliderOpts . outerLength - sliderOpts . pad . l - sliderOpts . pad . r ) ;
164
+ dims . inputAreaStart = 0 ;
165
+ dims . inputAreaLength = Math . round ( dims . outerLength - sliderOpts . pad . l - sliderOpts . pad . r ) ;
165
166
166
- var textableInputLength = sliderOpts . inputAreaLength - 2 * constants . stepInset ;
167
+ var textableInputLength = dims . inputAreaLength - 2 * constants . stepInset ;
167
168
var availableSpacePerLabel = textableInputLength / ( sliderOpts . steps . length - 1 ) ;
168
169
var computedSpacePerLabel = maxLabelWidth + constants . labelPadding ;
169
- sliderOpts . labelStride = Math . max ( 1 , Math . ceil ( computedSpacePerLabel / availableSpacePerLabel ) ) ;
170
- sliderOpts . labelHeight = labelHeight ;
170
+ dims . labelStride = Math . max ( 1 , Math . ceil ( computedSpacePerLabel / availableSpacePerLabel ) ) ;
171
+ dims . labelHeight = labelHeight ;
171
172
172
173
// loop over all possible values for currentValue to find the
173
174
// area we need for it
174
- sliderOpts . currentValueMaxWidth = 0 ;
175
- sliderOpts . currentValueHeight = 0 ;
176
- sliderOpts . currentValueTotalHeight = 0 ;
177
- sliderOpts . currentValueMaxLines = 1 ;
175
+ dims . currentValueMaxWidth = 0 ;
176
+ dims . currentValueHeight = 0 ;
177
+ dims . currentValueTotalHeight = 0 ;
178
+ dims . currentValueMaxLines = 1 ;
178
179
179
180
if ( sliderOpts . currentvalue . visible ) {
180
181
// Get the dimensions of the current value label:
@@ -184,50 +185,50 @@ function findDimensions(gd, sliderOpts) {
184
185
var curValPrefix = drawCurrentValue ( dummyGroup , sliderOpts , stepOpts . label ) ;
185
186
var curValSize = ( curValPrefix . node ( ) && Drawing . bBox ( curValPrefix . node ( ) ) ) || { width : 0 , height : 0 } ;
186
187
var lines = svgTextUtils . lineCount ( curValPrefix ) ;
187
- sliderOpts . currentValueMaxWidth = Math . max ( sliderOpts . currentValueMaxWidth , Math . ceil ( curValSize . width ) ) ;
188
- sliderOpts . currentValueHeight = Math . max ( sliderOpts . currentValueHeight , Math . ceil ( curValSize . height ) ) ;
189
- sliderOpts . currentValueMaxLines = Math . max ( sliderOpts . currentValueMaxLines , lines ) ;
188
+ dims . currentValueMaxWidth = Math . max ( dims . currentValueMaxWidth , Math . ceil ( curValSize . width ) ) ;
189
+ dims . currentValueHeight = Math . max ( dims . currentValueHeight , Math . ceil ( curValSize . height ) ) ;
190
+ dims . currentValueMaxLines = Math . max ( dims . currentValueMaxLines , lines ) ;
190
191
} ) ;
191
192
192
- sliderOpts . currentValueTotalHeight = sliderOpts . currentValueHeight + sliderOpts . currentvalue . offset ;
193
+ dims . currentValueTotalHeight = dims . currentValueHeight + sliderOpts . currentvalue . offset ;
193
194
194
195
dummyGroup . remove ( ) ;
195
196
}
196
197
197
- sliderOpts . height = sliderOpts . currentValueTotalHeight + constants . tickOffset + sliderOpts . ticklen + constants . labelOffset + sliderOpts . labelHeight + sliderOpts . pad . t + sliderOpts . pad . b ;
198
+ dims . height = dims . currentValueTotalHeight + constants . tickOffset + sliderOpts . ticklen + constants . labelOffset + dims . labelHeight + sliderOpts . pad . t + sliderOpts . pad . b ;
198
199
199
200
var xanchor = 'left' ;
200
201
if ( anchorUtils . isRightAnchor ( sliderOpts ) ) {
201
- sliderOpts . lx -= sliderOpts . outerLength ;
202
+ dims . lx -= dims . outerLength ;
202
203
xanchor = 'right' ;
203
204
}
204
205
if ( anchorUtils . isCenterAnchor ( sliderOpts ) ) {
205
- sliderOpts . lx -= sliderOpts . outerLength / 2 ;
206
+ dims . lx -= dims . outerLength / 2 ;
206
207
xanchor = 'center' ;
207
208
}
208
209
209
210
var yanchor = 'top' ;
210
211
if ( anchorUtils . isBottomAnchor ( sliderOpts ) ) {
211
- sliderOpts . ly -= sliderOpts . height ;
212
+ dims . ly -= dims . height ;
212
213
yanchor = 'bottom' ;
213
214
}
214
215
if ( anchorUtils . isMiddleAnchor ( sliderOpts ) ) {
215
- sliderOpts . ly -= sliderOpts . height / 2 ;
216
+ dims . ly -= dims . height / 2 ;
216
217
yanchor = 'middle' ;
217
218
}
218
219
219
- sliderOpts . outerLength = Math . ceil ( sliderOpts . outerLength ) ;
220
- sliderOpts . height = Math . ceil ( sliderOpts . height ) ;
221
- sliderOpts . lx = Math . round ( sliderOpts . lx ) ;
222
- sliderOpts . ly = Math . round ( sliderOpts . ly ) ;
220
+ dims . outerLength = Math . ceil ( dims . outerLength ) ;
221
+ dims . height = Math . ceil ( dims . height ) ;
222
+ dims . lx = Math . round ( dims . lx ) ;
223
+ dims . ly = Math . round ( dims . ly ) ;
223
224
224
225
Plots . autoMargin ( gd , constants . autoMarginIdRoot + sliderOpts . _index , {
225
226
x : sliderOpts . x ,
226
227
y : sliderOpts . y ,
227
- l : sliderOpts . outerLength * ( { right : 1 , center : 0.5 } [ xanchor ] || 0 ) ,
228
- r : sliderOpts . outerLength * ( { left : 1 , center : 0.5 } [ xanchor ] || 0 ) ,
229
- b : sliderOpts . height * ( { top : 1 , middle : 0.5 } [ yanchor ] || 0 ) ,
230
- t : sliderOpts . height * ( { bottom : 1 , middle : 0.5 } [ yanchor ] || 0 )
228
+ l : dims . outerLength * FROM_TL [ xanchor ] ,
229
+ r : dims . outerLength * FROM_BR [ xanchor ] ,
230
+ b : dims . height * FROM_BR [ yanchor ] ,
231
+ t : dims . height * FROM_TL [ yanchor ]
231
232
} ) ;
232
233
}
233
234
@@ -250,8 +251,10 @@ function drawSlider(gd, sliderGroup, sliderOpts) {
250
251
. call ( drawTouchRect , gd , sliderOpts )
251
252
. call ( drawGrip , gd , sliderOpts ) ;
252
253
254
+ var dims = sliderOpts . _dims ;
255
+
253
256
// Position the rectangle:
254
- Drawing . setTranslate ( sliderGroup , sliderOpts . lx + sliderOpts . pad . l , sliderOpts . ly + sliderOpts . pad . t ) ;
257
+ Drawing . setTranslate ( sliderGroup , dims . lx + sliderOpts . pad . l , dims . ly + sliderOpts . pad . t ) ;
255
258
256
259
sliderGroup . call ( setGripPosition , sliderOpts , sliderOpts . active / ( sliderOpts . steps . length - 1 ) , false ) ;
257
260
sliderGroup . call ( drawCurrentValue , sliderOpts ) ;
@@ -264,17 +267,18 @@ function drawCurrentValue(sliderGroup, sliderOpts, valueOverride) {
264
267
var x0 , textAnchor ;
265
268
var text = sliderGroup . selectAll ( 'text' )
266
269
. data ( [ 0 ] ) ;
270
+ var dims = sliderOpts . _dims ;
267
271
268
272
switch ( sliderOpts . currentvalue . xanchor ) {
269
273
case 'right' :
270
274
// This is anchored left and adjusted by the width of the longest label
271
275
// so that the prefix doesn't move. The goal of this is to emphasize
272
276
// what's actually changing and make the update less distracting.
273
- x0 = sliderOpts . inputAreaLength - constants . currentValueInset - sliderOpts . currentValueMaxWidth ;
277
+ x0 = dims . inputAreaLength - constants . currentValueInset - dims . currentValueMaxWidth ;
274
278
textAnchor = 'left' ;
275
279
break ;
276
280
case 'center' :
277
- x0 = sliderOpts . inputAreaLength * 0.5 ;
281
+ x0 = dims . inputAreaLength * 0.5 ;
278
282
textAnchor = 'middle' ;
279
283
break ;
280
284
default :
@@ -305,11 +309,11 @@ function drawCurrentValue(sliderGroup, sliderOpts, valueOverride) {
305
309
306
310
text . call ( Drawing . font , sliderOpts . currentvalue . font )
307
311
. text ( str )
308
- . call ( svgTextUtils . convertToTspans , sliderOpts . gd ) ;
312
+ . call ( svgTextUtils . convertToTspans , sliderOpts . _gd ) ;
309
313
310
314
var lines = svgTextUtils . lineCount ( text ) ;
311
315
312
- var y0 = ( sliderOpts . currentValueMaxLines + 1 - lines ) *
316
+ var y0 = ( dims . currentValueMaxLines + 1 - lines ) *
313
317
sliderOpts . currentvalue . font . size * LINE_SPACING ;
314
318
315
319
svgTextUtils . positionText ( text , x0 , y0 ) ;
@@ -351,20 +355,21 @@ function drawLabel(item, data, sliderOpts) {
351
355
352
356
text . call ( Drawing . font , sliderOpts . font )
353
357
. text ( data . step . label )
354
- . call ( svgTextUtils . convertToTspans , sliderOpts . gd ) ;
358
+ . call ( svgTextUtils . convertToTspans , sliderOpts . _gd ) ;
355
359
356
360
return text ;
357
361
}
358
362
359
363
function drawLabelGroup ( sliderGroup , sliderOpts ) {
360
364
var labels = sliderGroup . selectAll ( 'g.' + constants . labelsClass )
361
365
. data ( [ 0 ] ) ;
366
+ var dims = sliderOpts . _dims ;
362
367
363
368
labels . enter ( ) . append ( 'g' )
364
369
. classed ( constants . labelsClass , true ) ;
365
370
366
371
var labelItems = labels . selectAll ( 'g.' + constants . labelGroupClass )
367
- . data ( sliderOpts . labelSteps ) ;
372
+ . data ( dims . labelSteps ) ;
368
373
369
374
labelItems . enter ( ) . append ( 'g' )
370
375
. classed ( constants . labelGroupClass , true ) ;
@@ -384,7 +389,7 @@ function drawLabelGroup(sliderGroup, sliderOpts) {
384
389
// if the label spans multiple lines
385
390
sliderOpts . font . size * LINE_SPACING +
386
391
constants . labelOffset +
387
- sliderOpts . currentValueTotalHeight
392
+ dims . currentValueTotalHeight
388
393
) ;
389
394
} ) ;
390
395
@@ -488,6 +493,7 @@ function attachGripEvents(item, gd, sliderGroup) {
488
493
function drawTicks ( sliderGroup , sliderOpts ) {
489
494
var tick = sliderGroup . selectAll ( 'rect.' + constants . tickRectClass )
490
495
. data ( sliderOpts . steps ) ;
496
+ var dims = sliderOpts . _dims ;
491
497
492
498
tick . enter ( ) . append ( 'rect' )
493
499
. classed ( constants . tickRectClass , true ) ;
@@ -500,7 +506,7 @@ function drawTicks(sliderGroup, sliderOpts) {
500
506
} ) ;
501
507
502
508
tick . each ( function ( d , i ) {
503
- var isMajor = i % sliderOpts . labelStride === 0 ;
509
+ var isMajor = i % dims . labelStride === 0 ;
504
510
var item = d3 . select ( this ) ;
505
511
506
512
item
@@ -509,19 +515,20 @@ function drawTicks(sliderGroup, sliderOpts) {
509
515
510
516
Drawing . setTranslate ( item ,
511
517
normalizedValueToPosition ( sliderOpts , i / ( sliderOpts . steps . length - 1 ) ) - 0.5 * sliderOpts . tickwidth ,
512
- ( isMajor ? constants . tickOffset : constants . minorTickOffset ) + sliderOpts . currentValueTotalHeight
518
+ ( isMajor ? constants . tickOffset : constants . minorTickOffset ) + dims . currentValueTotalHeight
513
519
) ;
514
520
} ) ;
515
521
516
522
}
517
523
518
524
function computeLabelSteps ( sliderOpts ) {
519
- sliderOpts . labelSteps = [ ] ;
525
+ var dims = sliderOpts . _dims ;
526
+ dims . labelSteps = [ ] ;
520
527
var i0 = 0 ;
521
528
var nsteps = sliderOpts . steps . length ;
522
529
523
- for ( var i = i0 ; i < nsteps ; i += sliderOpts . labelStride ) {
524
- sliderOpts . labelSteps . push ( {
530
+ for ( var i = i0 ; i < nsteps ; i += dims . labelStride ) {
531
+ dims . labelSteps . push ( {
525
532
fraction : i / ( nsteps - 1 ) ,
526
533
step : sliderOpts . steps [ i ]
527
534
} ) ;
@@ -546,47 +553,51 @@ function setGripPosition(sliderGroup, sliderOpts, position, doTransition) {
546
553
547
554
// Drawing.setTranslate doesn't work here becasue of the transition duck-typing.
548
555
// It's also not necessary because there are no other transitions to preserve.
549
- el . attr ( 'transform' , 'translate(' + ( x - constants . gripWidth * 0.5 ) + ',' + ( sliderOpts . currentValueTotalHeight ) + ')' ) ;
556
+ el . attr ( 'transform' , 'translate(' + ( x - constants . gripWidth * 0.5 ) + ',' + ( sliderOpts . _dims . currentValueTotalHeight ) + ')' ) ;
550
557
}
551
558
552
559
// Convert a number from [0-1] to a pixel position relative to the slider group container:
553
560
function normalizedValueToPosition ( sliderOpts , normalizedPosition ) {
554
- return sliderOpts . inputAreaStart + constants . stepInset +
555
- ( sliderOpts . inputAreaLength - 2 * constants . stepInset ) * Math . min ( 1 , Math . max ( 0 , normalizedPosition ) ) ;
561
+ var dims = sliderOpts . _dims ;
562
+ return dims . inputAreaStart + constants . stepInset +
563
+ ( dims . inputAreaLength - 2 * constants . stepInset ) * Math . min ( 1 , Math . max ( 0 , normalizedPosition ) ) ;
556
564
}
557
565
558
566
// Convert a position relative to the slider group to a nubmer in [0, 1]
559
567
function positionToNormalizedValue ( sliderOpts , position ) {
560
- return Math . min ( 1 , Math . max ( 0 , ( position - constants . stepInset - sliderOpts . inputAreaStart ) / ( sliderOpts . inputAreaLength - 2 * constants . stepInset - 2 * sliderOpts . inputAreaStart ) ) ) ;
568
+ var dims = sliderOpts . _dims ;
569
+ return Math . min ( 1 , Math . max ( 0 , ( position - constants . stepInset - dims . inputAreaStart ) / ( dims . inputAreaLength - 2 * constants . stepInset - 2 * dims . inputAreaStart ) ) ) ;
561
570
}
562
571
563
572
function drawTouchRect ( sliderGroup , gd , sliderOpts ) {
564
573
var rect = sliderGroup . selectAll ( 'rect.' + constants . railTouchRectClass )
565
574
. data ( [ 0 ] ) ;
575
+ var dims = sliderOpts . _dims ;
566
576
567
577
rect . enter ( ) . append ( 'rect' )
568
578
. classed ( constants . railTouchRectClass , true )
569
579
. call ( attachGripEvents , gd , sliderGroup , sliderOpts )
570
580
. style ( 'pointer-events' , 'all' ) ;
571
581
572
582
rect . attr ( {
573
- width : sliderOpts . inputAreaLength ,
574
- height : Math . max ( sliderOpts . inputAreaWidth , constants . tickOffset + sliderOpts . ticklen + sliderOpts . labelHeight )
583
+ width : dims . inputAreaLength ,
584
+ height : Math . max ( dims . inputAreaWidth , constants . tickOffset + sliderOpts . ticklen + dims . labelHeight )
575
585
} )
576
586
. call ( Color . fill , sliderOpts . bgcolor )
577
587
. attr ( 'opacity' , 0 ) ;
578
588
579
- Drawing . setTranslate ( rect , 0 , sliderOpts . currentValueTotalHeight ) ;
589
+ Drawing . setTranslate ( rect , 0 , dims . currentValueTotalHeight ) ;
580
590
}
581
591
582
592
function drawRail ( sliderGroup , sliderOpts ) {
583
593
var rect = sliderGroup . selectAll ( 'rect.' + constants . railRectClass )
584
594
. data ( [ 0 ] ) ;
595
+ var dims = sliderOpts . _dims ;
585
596
586
597
rect . enter ( ) . append ( 'rect' )
587
598
. classed ( constants . railRectClass , true ) ;
588
599
589
- var computedLength = sliderOpts . inputAreaLength - constants . railInset * 2 ;
600
+ var computedLength = dims . inputAreaLength - constants . railInset * 2 ;
590
601
591
602
rect . attr ( {
592
603
width : computedLength ,
@@ -601,7 +612,7 @@ function drawRail(sliderGroup, sliderOpts) {
601
612
602
613
Drawing . setTranslate ( rect ,
603
614
constants . railInset ,
604
- ( sliderOpts . inputAreaWidth - constants . railWidth ) * 0.5 + sliderOpts . currentValueTotalHeight
615
+ ( dims . inputAreaWidth - constants . railWidth ) * 0.5 + dims . currentValueTotalHeight
605
616
) ;
606
617
}
607
618
0 commit comments