Skip to content

Commit 91cac2e

Browse files
committed
DRY up scattergl
- use same convert routine for x and y errors, - use same reset options object when initializing and resetting scene options.
1 parent 187ac23 commit 91cac2e

File tree

1 file changed

+62
-112
lines changed

1 file changed

+62
-112
lines changed

src/traces/scattergl/index.js

Lines changed: 62 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,9 @@ function sceneOptions(gd, subplot, trace, positions) {
165165
var fullLayout = gd._fullLayout;
166166
var count = positions.length / 2;
167167
var markerOpts = trace.marker;
168-
var xaxis = Axes.getFromId(gd, trace.xaxis);
169-
var yaxis = Axes.getFromId(gd, trace.yaxis);
170-
var ptrX = 0;
171-
var ptrY = 0;
172168
var i;
173169

174-
var hasLines, hasErrorX, hasErrorY, hasError, hasMarkers, hasFill;
170+
var hasLines, hasErrorX, hasErrorY, hasMarkers, hasFill;
175171

176172
if(trace.visible !== true) {
177173
hasLines = false;
@@ -183,7 +179,6 @@ function sceneOptions(gd, subplot, trace, positions) {
183179
hasLines = subTypes.hasLines(trace) && positions.length > 1;
184180
hasErrorX = trace.error_x && trace.error_x.visible === true;
185181
hasErrorY = trace.error_y && trace.error_y.visible === true;
186-
hasError = hasErrorX || hasErrorY;
187182
hasMarkers = subTypes.hasMarkers(trace);
188183
hasFill = !!trace.fill && trace.fill !== 'none';
189184
}
@@ -193,67 +188,16 @@ function sceneOptions(gd, subplot, trace, positions) {
193188
var selectedOptions, unselectedOptions;
194189
var linePositions;
195190

196-
// get error values
197-
var errorVals = hasError ?
198-
Registry.getComponentMethod('errorbars', 'calcFromTrace')(trace, fullLayout) :
199-
null;
200-
201-
if(hasErrorX) {
202-
errorXOptions = {};
203-
errorXOptions.positions = positions;
204-
var errorsX = new Float64Array(4 * count);
205-
206-
if(xaxis.type === 'log') {
207-
for(i = 0; i < count; ++i) {
208-
errorsX[ptrX++] = positions[i * 2] - xaxis.d2l(errorVals[i].xs) || 0;
209-
errorsX[ptrX++] = xaxis.d2l(errorVals[i].xh) - positions[i * 2] || 0;
210-
errorsX[ptrX++] = 0;
211-
errorsX[ptrX++] = 0;
212-
}
213-
} else {
214-
for(i = 0; i < count; ++i) {
215-
errorsX[ptrX++] = positions[i * 2] - errorVals[i].xs || 0;
216-
errorsX[ptrX++] = errorVals[i].xh - positions[i * 2] || 0;
217-
errorsX[ptrX++] = 0;
218-
errorsX[ptrX++] = 0;
219-
}
220-
}
191+
if(hasErrorX || hasErrorY) {
192+
var calcFromTrace = Registry.getComponentMethod('errorbars', 'calcFromTrace');
193+
var errorVals = calcFromTrace(trace, fullLayout);
221194

222-
if(trace.error_x.copy_ystyle) {
223-
trace.error_x = trace.error_y;
195+
if(hasErrorX) {
196+
errorXOptions = makeErrorOptions('x', trace.error_x, errorVals);
224197
}
225-
226-
errorXOptions.errors = errorsX;
227-
errorXOptions.capSize = trace.error_x.width * 2;
228-
errorXOptions.lineWidth = trace.error_x.thickness;
229-
errorXOptions.color = trace.error_x.color;
230-
}
231-
232-
if(hasErrorY) {
233-
errorYOptions = {};
234-
errorYOptions.positions = positions;
235-
var errorsY = new Float64Array(4 * count);
236-
237-
if(yaxis.type === 'log') {
238-
for(i = 0; i < count; ++i) {
239-
errorsY[ptrY++] = 0;
240-
errorsY[ptrY++] = 0;
241-
errorsY[ptrY++] = positions[i * 2 + 1] - yaxis.d2l(errorVals[i].ys) || 0;
242-
errorsY[ptrY++] = yaxis.d2l(errorVals[i].yh) - positions[i * 2 + 1] || 0;
243-
}
244-
} else {
245-
for(i = 0; i < count; ++i) {
246-
errorsY[ptrY++] = 0;
247-
errorsY[ptrY++] = 0;
248-
errorsY[ptrY++] = positions[i * 2 + 1] - errorVals[i].ys || 0;
249-
errorsY[ptrY++] = errorVals[i].yh - positions[i * 2 + 1] || 0;
250-
}
198+
if(hasErrorY) {
199+
errorYOptions = makeErrorOptions('y', trace.error_y, errorVals);
251200
}
252-
253-
errorYOptions.errors = errorsY;
254-
errorYOptions.capSize = trace.error_y.width * 2;
255-
errorYOptions.lineWidth = trace.error_y.thickness;
256-
errorYOptions.color = trace.error_y.color;
257201
}
258202

259203
if(hasLines) {
@@ -354,6 +298,33 @@ function sceneOptions(gd, subplot, trace, positions) {
354298
markerOptions.positions = positions;
355299
}
356300

301+
function makeErrorOptions(axLetter, errorOpts, vals) {
302+
var options = {};
303+
options.positions = positions;
304+
305+
var ax = Axes.getFromId(gd, trace[axLetter + 'axis']);
306+
var errors = options.errors = new Float64Array(4 * count);
307+
var pOffset = {x: 0, y: 1}[axLetter];
308+
var eOffset = {x: [0, 1, 2, 3], y: [2, 3, 0, 1]}[axLetter];
309+
310+
for(var i = 0, p = 0; i < count; i++, p += 4) {
311+
errors[p + eOffset[0]] = positions[i * 2 + pOffset] - ax.d2l(vals[i][axLetter + 's']) || 0;
312+
errors[p + eOffset[1]] = ax.d2l(vals[i][axLetter + 'h']) - positions[i * 2 + pOffset] || 0;
313+
errors[p + eOffset[2]] = 0;
314+
errors[p + eOffset[3]] = 0;
315+
}
316+
317+
if(errorOpts.copy_ystyle) {
318+
errorOpts = trace.error_y;
319+
}
320+
321+
options.capSize = errorOpts.width * 2;
322+
options.lineWidth = errorOpts.thickness;
323+
options.color = errorOpts.color;
324+
325+
return options;
326+
}
327+
357328
function makeSelectedOptions(selected, markerOpts) {
358329
var options = {};
359330

@@ -510,47 +481,34 @@ function sceneUpdate(gd, subplot) {
510481
var scene = subplot._scene;
511482
var fullLayout = gd._fullLayout;
512483

513-
if(!subplot._scene) {
514-
scene = subplot._scene = {
515-
// number of traces in subplot, since scene:subplot → 1:1
516-
count: 0,
517-
518-
// whether scene requires init hook in plot call (dirty plot call)
519-
dirty: true,
520-
521-
// last used options
522-
lineOptions: [],
523-
fillOptions: [],
524-
markerOptions: [],
525-
selectedOptions: [],
526-
unselectedOptions: [],
527-
errorXOptions: [],
528-
errorYOptions: [],
529-
selectBatch: null,
530-
unselectBatch: null,
531-
532-
// regl- component stubs, initialized in dirty plot call
533-
fill2d: false,
534-
scatter2d: false,
535-
error2d: false,
536-
line2d: false,
537-
select2d: null
538-
};
484+
var reset = {
485+
// number of traces in subplot, since scene:subplot → 1:1
486+
count: 0,
487+
// whether scene requires init hook in plot call (dirty plot call)
488+
dirty: true,
489+
// last used options
490+
lineOptions: [],
491+
fillOptions: [],
492+
markerOptions: [],
493+
selectedOptions: [],
494+
unselectedOptions: [],
495+
errorXOptions: [],
496+
errorYOptions: []
497+
};
539498

540-
// apply new option to all regl components
541-
scene.update = function update(opt) {
542-
var opts = Array(scene.count);
543-
for(var i = 0; i < scene.count; i++) {
544-
opts[i] = opt;
545-
}
546-
if(scene.fill2d) scene.fill2d.update(opts);
547-
if(scene.scatter2d) scene.scatter2d.update(opts);
548-
if(scene.line2d) scene.line2d.update(opts);
549-
if(scene.error2d) scene.error2d.update(opts.concat(opts));
550-
if(scene.select2d) scene.select2d.update(opts);
499+
var first = {
500+
selectBatch: null,
501+
unselectBatch: null,
502+
// regl- component stubs, initialized in dirty plot call
503+
fill2d: false,
504+
scatter2d: false,
505+
error2d: false,
506+
line2d: false,
507+
select2d: null
508+
};
551509

552-
scene.draw();
553-
};
510+
if(!subplot._scene) {
511+
scene = subplot._scene = Lib.extendFlat({}, reset, first);
554512

555513
// draw traces in proper order
556514
scene.draw = function draw() {
@@ -666,15 +624,7 @@ function sceneUpdate(gd, subplot) {
666624

667625
// In case if we have scene from the last calc - reset data
668626
if(!scene.dirty) {
669-
scene.dirty = true;
670-
scene.count = 0;
671-
scene.lineOptions = [];
672-
scene.fillOptions = [];
673-
scene.markerOptions = [];
674-
scene.selectedOptions = [];
675-
scene.unselectedOptions = [];
676-
scene.errorXOptions = [];
677-
scene.errorYOptions = [];
627+
Lib.extendFlat(scene, reset);
678628
}
679629

680630
return scene;

0 commit comments

Comments
 (0)