Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8fbe06e

Browse files
committed
store slider & updatemenu dimensions in _private attrs
1 parent 5814642 commit 8fbe06e

File tree

2 files changed

+139
-122
lines changed

2 files changed

+139
-122
lines changed

src/components/sliders/draw.js

Lines changed: 70 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ var svgTextUtils = require('../../lib/svg_text_utils');
1818
var anchorUtils = require('../legend/anchor_utils');
1919

2020
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;
2225

2326

2427
module.exports = function draw(gd) {
@@ -98,7 +101,7 @@ function makeSliderData(fullLayout, gd) {
98101
for(var i = 0; i < contOpts.length; i++) {
99102
var item = contOpts[i];
100103
if(!item.visible || !item.steps.length) continue;
101-
item.gd = gd;
104+
item._gd = gd;
102105
sliderData.push(item);
103106
}
104107

@@ -136,45 +139,43 @@ function findDimensions(gd, sliderOpts) {
136139

137140
sliderLabels.remove();
138141

139-
sliderOpts.inputAreaWidth = Math.max(
142+
var dims = sliderOpts._dims = {};
143+
144+
dims.inputAreaWidth = Math.max(
140145
constants.railWidth,
141146
constants.gripHeight
142147
);
143148

144149
// calculate some overall dimensions - some of these are needed for
145150
// calculating the currentValue dimensions
146151
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);
149154

150155
if(sliderOpts.lenmode === 'fraction') {
151156
// fraction:
152-
sliderOpts.outerLength = Math.round(graphSize.w * sliderOpts.len);
157+
dims.outerLength = Math.round(graphSize.w * sliderOpts.len);
153158
} else {
154159
// pixels:
155-
sliderOpts.outerLength = sliderOpts.len;
160+
dims.outerLength = sliderOpts.len;
156161
}
157162

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-
162163
// 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);
165166

166-
var textableInputLength = sliderOpts.inputAreaLength - 2 * constants.stepInset;
167+
var textableInputLength = dims.inputAreaLength - 2 * constants.stepInset;
167168
var availableSpacePerLabel = textableInputLength / (sliderOpts.steps.length - 1);
168169
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;
171172

172173
// loop over all possible values for currentValue to find the
173174
// 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;
178179

179180
if(sliderOpts.currentvalue.visible) {
180181
// Get the dimensions of the current value label:
@@ -184,50 +185,50 @@ function findDimensions(gd, sliderOpts) {
184185
var curValPrefix = drawCurrentValue(dummyGroup, sliderOpts, stepOpts.label);
185186
var curValSize = (curValPrefix.node() && Drawing.bBox(curValPrefix.node())) || {width: 0, height: 0};
186187
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);
190191
});
191192

192-
sliderOpts.currentValueTotalHeight = sliderOpts.currentValueHeight + sliderOpts.currentvalue.offset;
193+
dims.currentValueTotalHeight = dims.currentValueHeight + sliderOpts.currentvalue.offset;
193194

194195
dummyGroup.remove();
195196
}
196197

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;
198199

199200
var xanchor = 'left';
200201
if(anchorUtils.isRightAnchor(sliderOpts)) {
201-
sliderOpts.lx -= sliderOpts.outerLength;
202+
dims.lx -= dims.outerLength;
202203
xanchor = 'right';
203204
}
204205
if(anchorUtils.isCenterAnchor(sliderOpts)) {
205-
sliderOpts.lx -= sliderOpts.outerLength / 2;
206+
dims.lx -= dims.outerLength / 2;
206207
xanchor = 'center';
207208
}
208209

209210
var yanchor = 'top';
210211
if(anchorUtils.isBottomAnchor(sliderOpts)) {
211-
sliderOpts.ly -= sliderOpts.height;
212+
dims.ly -= dims.height;
212213
yanchor = 'bottom';
213214
}
214215
if(anchorUtils.isMiddleAnchor(sliderOpts)) {
215-
sliderOpts.ly -= sliderOpts.height / 2;
216+
dims.ly -= dims.height / 2;
216217
yanchor = 'middle';
217218
}
218219

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);
223224

224225
Plots.autoMargin(gd, constants.autoMarginIdRoot + sliderOpts._index, {
225226
x: sliderOpts.x,
226227
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]
231232
});
232233
}
233234

@@ -250,8 +251,10 @@ function drawSlider(gd, sliderGroup, sliderOpts) {
250251
.call(drawTouchRect, gd, sliderOpts)
251252
.call(drawGrip, gd, sliderOpts);
252253

254+
var dims = sliderOpts._dims;
255+
253256
// 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);
255258

256259
sliderGroup.call(setGripPosition, sliderOpts, sliderOpts.active / (sliderOpts.steps.length - 1), false);
257260
sliderGroup.call(drawCurrentValue, sliderOpts);
@@ -264,17 +267,18 @@ function drawCurrentValue(sliderGroup, sliderOpts, valueOverride) {
264267
var x0, textAnchor;
265268
var text = sliderGroup.selectAll('text')
266269
.data([0]);
270+
var dims = sliderOpts._dims;
267271

268272
switch(sliderOpts.currentvalue.xanchor) {
269273
case 'right':
270274
// This is anchored left and adjusted by the width of the longest label
271275
// so that the prefix doesn't move. The goal of this is to emphasize
272276
// 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;
274278
textAnchor = 'left';
275279
break;
276280
case 'center':
277-
x0 = sliderOpts.inputAreaLength * 0.5;
281+
x0 = dims.inputAreaLength * 0.5;
278282
textAnchor = 'middle';
279283
break;
280284
default:
@@ -305,11 +309,11 @@ function drawCurrentValue(sliderGroup, sliderOpts, valueOverride) {
305309

306310
text.call(Drawing.font, sliderOpts.currentvalue.font)
307311
.text(str)
308-
.call(svgTextUtils.convertToTspans, sliderOpts.gd);
312+
.call(svgTextUtils.convertToTspans, sliderOpts._gd);
309313

310314
var lines = svgTextUtils.lineCount(text);
311315

312-
var y0 = (sliderOpts.currentValueMaxLines + 1 - lines) *
316+
var y0 = (dims.currentValueMaxLines + 1 - lines) *
313317
sliderOpts.currentvalue.font.size * LINE_SPACING;
314318

315319
svgTextUtils.positionText(text, x0, y0);
@@ -351,20 +355,21 @@ function drawLabel(item, data, sliderOpts) {
351355

352356
text.call(Drawing.font, sliderOpts.font)
353357
.text(data.step.label)
354-
.call(svgTextUtils.convertToTspans, sliderOpts.gd);
358+
.call(svgTextUtils.convertToTspans, sliderOpts._gd);
355359

356360
return text;
357361
}
358362

359363
function drawLabelGroup(sliderGroup, sliderOpts) {
360364
var labels = sliderGroup.selectAll('g.' + constants.labelsClass)
361365
.data([0]);
366+
var dims = sliderOpts._dims;
362367

363368
labels.enter().append('g')
364369
.classed(constants.labelsClass, true);
365370

366371
var labelItems = labels.selectAll('g.' + constants.labelGroupClass)
367-
.data(sliderOpts.labelSteps);
372+
.data(dims.labelSteps);
368373

369374
labelItems.enter().append('g')
370375
.classed(constants.labelGroupClass, true);
@@ -384,7 +389,7 @@ function drawLabelGroup(sliderGroup, sliderOpts) {
384389
// if the label spans multiple lines
385390
sliderOpts.font.size * LINE_SPACING +
386391
constants.labelOffset +
387-
sliderOpts.currentValueTotalHeight
392+
dims.currentValueTotalHeight
388393
);
389394
});
390395

@@ -488,6 +493,7 @@ function attachGripEvents(item, gd, sliderGroup) {
488493
function drawTicks(sliderGroup, sliderOpts) {
489494
var tick = sliderGroup.selectAll('rect.' + constants.tickRectClass)
490495
.data(sliderOpts.steps);
496+
var dims = sliderOpts._dims;
491497

492498
tick.enter().append('rect')
493499
.classed(constants.tickRectClass, true);
@@ -500,7 +506,7 @@ function drawTicks(sliderGroup, sliderOpts) {
500506
});
501507

502508
tick.each(function(d, i) {
503-
var isMajor = i % sliderOpts.labelStride === 0;
509+
var isMajor = i % dims.labelStride === 0;
504510
var item = d3.select(this);
505511

506512
item
@@ -509,19 +515,20 @@ function drawTicks(sliderGroup, sliderOpts) {
509515

510516
Drawing.setTranslate(item,
511517
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
513519
);
514520
});
515521

516522
}
517523

518524
function computeLabelSteps(sliderOpts) {
519-
sliderOpts.labelSteps = [];
525+
var dims = sliderOpts._dims;
526+
dims.labelSteps = [];
520527
var i0 = 0;
521528
var nsteps = sliderOpts.steps.length;
522529

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({
525532
fraction: i / (nsteps - 1),
526533
step: sliderOpts.steps[i]
527534
});
@@ -546,47 +553,51 @@ function setGripPosition(sliderGroup, sliderOpts, position, doTransition) {
546553

547554
// Drawing.setTranslate doesn't work here becasue of the transition duck-typing.
548555
// 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) + ')');
550557
}
551558

552559
// Convert a number from [0-1] to a pixel position relative to the slider group container:
553560
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));
556564
}
557565

558566
// Convert a position relative to the slider group to a nubmer in [0, 1]
559567
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)));
561570
}
562571

563572
function drawTouchRect(sliderGroup, gd, sliderOpts) {
564573
var rect = sliderGroup.selectAll('rect.' + constants.railTouchRectClass)
565574
.data([0]);
575+
var dims = sliderOpts._dims;
566576

567577
rect.enter().append('rect')
568578
.classed(constants.railTouchRectClass, true)
569579
.call(attachGripEvents, gd, sliderGroup, sliderOpts)
570580
.style('pointer-events', 'all');
571581

572582
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)
575585
})
576586
.call(Color.fill, sliderOpts.bgcolor)
577587
.attr('opacity', 0);
578588

579-
Drawing.setTranslate(rect, 0, sliderOpts.currentValueTotalHeight);
589+
Drawing.setTranslate(rect, 0, dims.currentValueTotalHeight);
580590
}
581591

582592
function drawRail(sliderGroup, sliderOpts) {
583593
var rect = sliderGroup.selectAll('rect.' + constants.railRectClass)
584594
.data([0]);
595+
var dims = sliderOpts._dims;
585596

586597
rect.enter().append('rect')
587598
.classed(constants.railRectClass, true);
588599

589-
var computedLength = sliderOpts.inputAreaLength - constants.railInset * 2;
600+
var computedLength = dims.inputAreaLength - constants.railInset * 2;
590601

591602
rect.attr({
592603
width: computedLength,
@@ -601,7 +612,7 @@ function drawRail(sliderGroup, sliderOpts) {
601612

602613
Drawing.setTranslate(rect,
603614
constants.railInset,
604-
(sliderOpts.inputAreaWidth - constants.railWidth) * 0.5 + sliderOpts.currentValueTotalHeight
615+
(dims.inputAreaWidth - constants.railWidth) * 0.5 + dims.currentValueTotalHeight
605616
);
606617
}
607618

0 commit comments

Comments
 (0)