Skip to content

Commit cd8d8ab

Browse files
authored
Merge pull request #3067 from plotly/redraw-regl-traces-subroutine
Add redrawReglTraces subroutine
2 parents 478c669 + f179c2f commit cd8d8ab

File tree

14 files changed

+177
-201
lines changed

14 files changed

+177
-201
lines changed

src/plot_api/subroutines.js

+68-14
Original file line numberDiff line numberDiff line change
@@ -462,21 +462,21 @@ exports.drawMainTitle = function(gd) {
462462
});
463463
};
464464

465-
// First, see if we need to do arraysToCalcdata
466-
// call it regardless of what change we made, in case
467-
// supplyDefaults brought in an array that was already
468-
// in gd.data but not in gd._fullData previously
469465
exports.doTraceStyle = function(gd) {
470-
var fullLayout = gd._fullLayout;
466+
var calcdata = gd.calcdata;
471467
var editStyleCalls = [];
472468
var i;
473469

474-
for(i = 0; i < gd.calcdata.length; i++) {
475-
var cd = gd.calcdata[i];
470+
for(i = 0; i < calcdata.length; i++) {
471+
var cd = calcdata[i];
476472
var cd0 = cd[0] || {};
477473
var trace = cd0.trace || {};
478474
var _module = trace._module || {};
479475

476+
// See if we need to do arraysToCalcdata
477+
// call it regardless of what change we made, in case
478+
// supplyDefaults brought in an array that was already
479+
// in gd.data but not in gd._fullData previously
480480
var arraysToCalcdata = _module.arraysToCalcdata;
481481
if(arraysToCalcdata) arraysToCalcdata(cd, trace);
482482

@@ -485,16 +485,12 @@ exports.doTraceStyle = function(gd) {
485485
}
486486

487487
if(editStyleCalls.length) {
488-
clearGlCanvases(gd);
489-
490-
if(fullLayout._hasOnlyLargeSploms) {
491-
fullLayout._splomGrid.draw();
492-
}
493-
494488
for(i = 0; i < editStyleCalls.length; i++) {
495489
var edit = editStyleCalls[i];
496490
edit.fn(gd, edit.cd0);
497491
}
492+
clearGlCanvases(gd);
493+
exports.redrawReglTraces(gd);
498494
}
499495

500496
Plots.style(gd);
@@ -546,8 +542,9 @@ exports.doTicksRelayout = function(gd) {
546542
Axes.doTicks(gd, 'redraw');
547543

548544
if(gd._fullLayout._hasOnlyLargeSploms) {
545+
Registry.subplotsRegistry.splom.updateGrid(gd);
549546
clearGlCanvases(gd);
550-
Registry.subplotsRegistry.splom.plot(gd);
547+
exports.redrawReglTraces(gd);
551548
}
552549

553550
exports.drawMainTitle(gd);
@@ -600,6 +597,8 @@ exports.drawData = function(gd) {
600597
basePlotModules[i].plot(gd);
601598
}
602599

600+
exports.redrawReglTraces(gd);
601+
603602
// styling separate from drawing
604603
Plots.style(gd);
605604

@@ -613,6 +612,61 @@ exports.drawData = function(gd) {
613612
return Plots.previousPromises(gd);
614613
};
615614

615+
// Draw (or redraw) all traces in one go,
616+
// useful during drag and selection where buffers of targeted traces are updated,
617+
// but all traces need to be redrawn following clearGlCanvases.
618+
//
619+
// Note that _module.plot for regl trace does NOT draw things
620+
// on the canvas, they only update the buffers.
621+
// Drawing is perform here.
622+
//
623+
// TODO try adding per-subplot option using gl.SCISSOR_TEST for
624+
// non-overlaying, disjoint subplots.
625+
//
626+
// TODO try to include parcoords in here.
627+
exports.redrawReglTraces = function(gd) {
628+
var fullLayout = gd._fullLayout;
629+
630+
if(fullLayout._has('regl')) {
631+
var fullData = gd._fullData;
632+
var cartesianIds = [];
633+
var polarIds = [];
634+
var i, sp;
635+
636+
if(fullLayout._hasOnlyLargeSploms) {
637+
fullLayout._splomGrid.draw();
638+
}
639+
640+
// N.B.
641+
// - Loop over fullData (not _splomScenes) to preserve splom trace-to-trace ordering
642+
// - Fill list if subplot ids (instead of fullLayout._subplots) to handle cases where all traces
643+
// of a given module are `visible !== true`
644+
for(i = 0; i < fullData.length; i++) {
645+
var trace = fullData[i];
646+
647+
if(trace.visible === true) {
648+
if(trace.type === 'splom') {
649+
fullLayout._splomScenes[trace.uid].draw();
650+
} else if(trace.type === 'scattergl') {
651+
Lib.pushUnique(cartesianIds, trace.xaxis + trace.yaxis);
652+
} else if(trace.type === 'scatterpolargl') {
653+
Lib.pushUnique(polarIds, trace.subplot);
654+
}
655+
}
656+
}
657+
658+
for(i = 0; i < cartesianIds.length; i++) {
659+
sp = fullLayout._plots[cartesianIds[i]];
660+
if(sp._scene) sp._scene.draw();
661+
}
662+
663+
for(i = 0; i < polarIds.length; i++) {
664+
sp = fullLayout[polarIds[i]]._subplot;
665+
if(sp._scene) sp._scene.draw();
666+
}
667+
}
668+
};
669+
616670
exports.doAutoRangeAndConstraints = function(gd) {
617671
var axList = Axes.list(gd, '', true);
618672

src/plots/cartesian/dragbox.js

+11-15
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ var supportsPassive = require('has-passive-events');
1616
var Registry = require('../../registry');
1717
var Lib = require('../../lib');
1818
var svgTextUtils = require('../../lib/svg_text_utils');
19-
var clearGlCanvases = require('../../lib/clear_gl_canvases');
2019
var Color = require('../../components/color');
2120
var Drawing = require('../../components/drawing');
2221
var Fx = require('../../components/fx');
2322
var setCursor = require('../../lib/setcursor');
2423
var dragElement = require('../../components/dragelement');
2524
var FROM_TL = require('../../constants/alignment').FROM_TL;
25+
var clearGlCanvases = require('../../lib/clear_gl_canvases');
26+
var redrawReglTraces = require('../../plot_api/subroutines').redrawReglTraces;
2627

2728
var Plots = require('../plots');
2829

@@ -84,7 +85,7 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
8485
// do we need to edit x/y ranges?
8586
var editX, editY;
8687
// graph-wide optimization flags
87-
var hasScatterGl, hasOnlyLargeSploms, hasSplom, hasSVG;
88+
var hasScatterGl, hasSplom, hasSVG;
8889
// collected changes to be made to the plot by relayout at the end
8990
var updates;
9091

@@ -125,8 +126,7 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
125126

126127
var fullLayout = gd._fullLayout;
127128
hasScatterGl = fullLayout._has('scattergl');
128-
hasOnlyLargeSploms = fullLayout._hasOnlyLargeSploms;
129-
hasSplom = hasOnlyLargeSploms || fullLayout._has('splom');
129+
hasSplom = fullLayout._has('splom');
130130
hasSVG = fullLayout._has('svg');
131131
}
132132

@@ -744,33 +744,29 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) {
744744
var subplots = fullLayout._subplots.cartesian;
745745
var i, sp, xa, ya;
746746

747-
if(hasSplom || hasScatterGl) {
748-
clearGlCanvases(gd);
749-
}
750-
751747
if(hasSplom) {
752748
Registry.subplotsRegistry.splom.drag(gd);
753-
if(hasOnlyLargeSploms) return;
754749
}
755750

756751
if(hasScatterGl) {
757-
// loop over all subplots (w/o exceptions) here,
758-
// as we cleared the gl canvases above
759752
for(i = 0; i < subplots.length; i++) {
760753
sp = plotinfos[subplots[i]];
761754
xa = sp.xaxis;
762755
ya = sp.yaxis;
763756

764-
var scene = sp._scene;
765-
if(scene) {
766-
// FIXME: possibly we could update axis internal _r and _rl here
757+
if(sp._scene) {
767758
var xrng = Lib.simpleMap(xa.range, xa.r2l);
768759
var yrng = Lib.simpleMap(ya.range, ya.r2l);
769-
scene.update({range: [xrng[0], yrng[0], xrng[1], yrng[1]]});
760+
sp._scene.update({range: [xrng[0], yrng[0], xrng[1], yrng[1]]});
770761
}
771762
}
772763
}
773764

765+
if(hasSplom || hasScatterGl) {
766+
clearGlCanvases(gd);
767+
redrawReglTraces(gd);
768+
}
769+
774770
if(hasSVG) {
775771
var xScaleFactor = viewBox[2] / xa0._length;
776772
var yScaleFactor = viewBox[3] / ya0._length;

src/plots/cartesian/select.js

+15-32
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ var polygon = require('../../lib/polygon');
1919
var throttle = require('../../lib/throttle');
2020
var makeEventData = require('../../components/fx/helpers').makeEventData;
2121
var getFromId = require('./axis_ids').getFromId;
22-
var sortModules = require('../sort_modules').sortModules;
22+
var clearGlCanvases = require('../../lib/clear_gl_canvases');
23+
var redrawReglTraces = require('../../plot_api/subroutines').redrawReglTraces;
2324

2425
var constants = require('./constants');
2526
var MINSELECT = constants.MINSELECT;
@@ -663,7 +664,7 @@ function isOnlyOnePointSelected(searchTraces) {
663664
}
664665

665666
function updateSelectedState(gd, searchTraces, eventData) {
666-
var i, j, searchInfo, trace;
667+
var i, searchInfo, cd, trace;
667668

668669
if(eventData) {
669670
var pts = eventData.points || [];
@@ -696,43 +697,25 @@ function updateSelectedState(gd, searchTraces, eventData) {
696697
}
697698
}
698699

699-
// group searchInfo traces by trace modules
700-
var lookup = {};
700+
var hasRegl = false;
701701

702702
for(i = 0; i < searchTraces.length; i++) {
703703
searchInfo = searchTraces[i];
704+
cd = searchInfo.cd;
705+
trace = cd[0].trace;
704706

705-
var name = searchInfo._module.name;
706-
if(lookup[name]) {
707-
lookup[name].push(searchInfo);
708-
} else {
709-
lookup[name] = [searchInfo];
707+
if(Registry.traceIs(trace, 'regl')) {
708+
hasRegl = true;
710709
}
710+
711+
var _module = searchInfo._module;
712+
var fn = _module.styleOnSelect || _module.style;
713+
if(fn) fn(gd, cd);
711714
}
712715

713-
var keys = Object.keys(lookup).sort(sortModules);
714-
715-
for(i = 0; i < keys.length; i++) {
716-
var items = lookup[keys[i]];
717-
var len = items.length;
718-
var item0 = items[0];
719-
var trace0 = item0.cd[0].trace;
720-
var _module = item0._module;
721-
var styleSelection = _module.styleOnSelect || _module.style;
722-
723-
if(Registry.traceIs(trace0, 'regl')) {
724-
// plot regl traces per module
725-
var cds = new Array(len);
726-
for(j = 0; j < len; j++) {
727-
cds[j] = items[j].cd;
728-
}
729-
styleSelection(gd, cds);
730-
} else {
731-
// plot svg trace per trace
732-
for(j = 0; j < len; j++) {
733-
styleSelection(gd, items[j].cd);
734-
}
735-
}
716+
if(hasRegl) {
717+
clearGlCanvases(gd);
718+
redrawReglTraces(gd);
736719
}
737720
}
738721

src/plots/plots.js

-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ var Color = require('../components/color');
2020
var BADNUM = require('../constants/numerical').BADNUM;
2121

2222
var axisIDs = require('../plots/cartesian/axis_ids');
23-
var sortBasePlotModules = require('./sort_modules').sortBasePlotModules;
2423

2524
var animationAttrs = require('./animation_attributes');
2625
var frameAttrs = require('./frame_attributes');
@@ -487,9 +486,6 @@ plots.supplyDefaults = function(gd, opts) {
487486
if(!skipUpdateCalc && oldCalcdata.length === newFullData.length) {
488487
plots.supplyDefaultsUpdateCalc(oldCalcdata, newFullData);
489488
}
490-
491-
// sort base plot modules for consistent ordering
492-
newFullLayout._basePlotModules.sort(sortBasePlotModules);
493489
};
494490

495491
plots.supplyDefaultsUpdateCalc = function(oldCalcdata, newFullData) {

src/plots/polar/polar.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ var prepSelect = require('../cartesian/select').prepSelect;
2828
var selectOnClick = require('../cartesian/select').selectOnClick;
2929
var clearSelect = require('../cartesian/select').clearSelect;
3030
var setCursor = require('../../lib/setcursor');
31+
var clearGlCanvases = require('../../lib/clear_gl_canvases');
32+
var redrawReglTraces = require('../../plot_api/subroutines').redrawReglTraces;
3133

3234
var MID_SHIFT = require('../../constants/alignment').MID_SHIFT;
3335
var constants = require('./constants');
@@ -1058,14 +1060,20 @@ proto.updateRadialDrag = function(fullLayout, polarLayout, rngIndex) {
10581060
.attr('transform', strTranslate(cx, cy))
10591061
.selectAll('path').attr('transform', null);
10601062

1061-
if(_this._scene) _this._scene.clear();
1063+
var hasRegl = false;
10621064

10631065
for(var traceType in _this.traceHash) {
10641066
var moduleCalcData = _this.traceHash[traceType];
10651067
var moduleCalcDataVisible = Lib.filterVisible(moduleCalcData);
10661068
var _module = moduleCalcData[0][0].trace._module;
10671069
var polarLayoutNow = gd._fullLayout[_this.id];
10681070
_module.plot(gd, _this, moduleCalcDataVisible, polarLayoutNow);
1071+
if(Registry.traceIs(traceType, 'gl') && moduleCalcDataVisible.length) hasRegl = true;
1072+
}
1073+
1074+
if(hasRegl) {
1075+
clearGlCanvases(gd);
1076+
redrawReglTraces(gd);
10691077
}
10701078
}
10711079

@@ -1185,16 +1193,22 @@ proto.updateAngularDrag = function(fullLayout) {
11851193
scatterTraces.call(Drawing.hideOutsideRangePoints, _this);
11861194
}
11871195

1188-
if(_this._scene) _this._scene.clear();
1196+
var hasRegl = false;
11891197

11901198
for(var traceType in _this.traceHash) {
11911199
if(Registry.traceIs(traceType, 'gl')) {
11921200
var moduleCalcData = _this.traceHash[traceType];
11931201
var moduleCalcDataVisible = Lib.filterVisible(moduleCalcData);
11941202
var _module = moduleCalcData[0][0].trace._module;
11951203
_module.plot(gd, _this, moduleCalcDataVisible, polarLayoutNow);
1204+
if(moduleCalcDataVisible.length) hasRegl = true;
11961205
}
11971206
}
1207+
1208+
if(hasRegl) {
1209+
clearGlCanvases(gd);
1210+
redrawReglTraces(gd);
1211+
}
11981212
}
11991213

12001214
function doneFn() {

src/plots/sort_modules.js

-25
This file was deleted.

0 commit comments

Comments
 (0)