Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit accae1a

Browse filesBrowse files
authored
Merge pull request #2159 from plotly/global-context
Introduce global contexts
2 parents 629f7a0 + de9b1aa commit accae1a
Copy full SHA for accae1a

File tree

Expand file treeCollapse file tree

20 files changed

+247
-117
lines changed
Filter options
Expand file treeCollapse file tree

20 files changed

+247
-117
lines changed

‎src/plot_api/helpers.js

Copy file name to clipboardExpand all lines: src/plot_api/helpers.js
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ exports.cleanLayout = function(layout) {
154154

155155
// clean old Camera coords
156156
var cameraposition = scene.cameraposition;
157+
157158
if(Array.isArray(cameraposition) && cameraposition[0].length === 4) {
158159
var rotation = cameraposition[0],
159160
center = cameraposition[1],

‎src/plot_api/plot_api.js

Copy file name to clipboardExpand all lines: src/plot_api/plot_api.js
+43-2Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,43 @@ Plotly.plot = function(gd, data, layout, config) {
195195
}
196196
}
197197

198+
if(!fullLayout._glcanvas && fullLayout._has('gl')) {
199+
fullLayout._glcanvas = fullLayout._glcontainer.selectAll('.gl-canvas').data([{
200+
key: 'contextLayer',
201+
context: true,
202+
pick: false
203+
}, {
204+
key: 'focusLayer',
205+
context: false,
206+
pick: false
207+
}, {
208+
key: 'pickLayer',
209+
context: false,
210+
pick: true
211+
}], function(d) { return d.key; });
212+
213+
fullLayout._glcanvas.enter().append('canvas')
214+
.attr('class', function(d) {
215+
return 'gl-canvas gl-canvas-' + d.key.replace('Layer', '');
216+
})
217+
.style({
218+
'position': 'absolute',
219+
'top': 0,
220+
'left': 0,
221+
'width': '100%',
222+
'height': '100%',
223+
'overflow': 'visible'
224+
})
225+
.attr('width', fullLayout.width)
226+
.attr('height', fullLayout.height);
227+
228+
fullLayout._glcanvas.filter(function(d) {
229+
return !d.pick;
230+
}).style({
231+
'pointer-events': 'none'
232+
});
233+
}
234+
198235
return Lib.syncOrAsync([
199236
subroutines.layoutStyles
200237
], gd);
@@ -1993,7 +2030,7 @@ function _relayout(gd, aobj) {
19932030
else flags.plot = true;
19942031
}
19952032
else {
1996-
if(fullLayout._has('gl2d') &&
2033+
if((fullLayout._has('gl2d') || fullLayout._has('regl')) &&
19972034
(ai === 'dragmode' &&
19982035
(vi === 'lasso' || vi === 'select') &&
19992036
!(vOld === 'lasso' || vOld === 'select'))
@@ -2764,11 +2801,15 @@ function makePlotFramework(gd) {
27642801
// right, rather than enter/exit which can muck up the order
27652802
// TODO: sort out all the ordering so we don't have to
27662803
// explicitly delete anything
2804+
// FIXME: parcoords reuses this object, not the best pattern
27672805
fullLayout._glcontainer = fullLayout._paperdiv.selectAll('.gl-container')
2768-
.data([0]);
2806+
.data([{}]);
27692807
fullLayout._glcontainer.enter().append('div')
27702808
.classed('gl-container', true);
27712809

2810+
// That is initialized in drawFramework if there are `gl` traces
2811+
fullLayout._glcanvas = null;
2812+
27722813
fullLayout._paperdiv.selectAll('.main-svg').remove();
27732814

27742815
fullLayout._paper = fullLayout._paperdiv.insert('svg', ':first-child')

‎src/plots/cartesian/dragbox.js

Copy file name to clipboardExpand all lines: src/plots/cartesian/dragbox.js
+22-1Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,14 +711,35 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) {
711711
return ax._length * (1 - scaleFactor) * FROM_TL[ax.constraintoward || 'middle'];
712712
}
713713

714-
for(i = 0; i < subplots.length; i++) {
714+
// clear gl frame, if any, since we preserve drawing buffer
715+
// FIXME: code duplication with cartesian.plot
716+
if(fullLayout._glcanvas && fullLayout._glcanvas.size()) {
717+
fullLayout._glcanvas.each(function(d) {
718+
if(d.regl) {
719+
d.regl.clear({
720+
color: true
721+
});
722+
}
723+
});
724+
}
715725

726+
for(i = 0; i < subplots.length; i++) {
716727
var subplot = plotinfos[subplots[i]],
717728
xa2 = subplot.xaxis,
718729
ya2 = subplot.yaxis,
719730
editX2 = editX && !xa2.fixedrange && (xa.indexOf(xa2) !== -1),
720731
editY2 = editY && !ya2.fixedrange && (ya.indexOf(ya2) !== -1);
721732

733+
// scattergl translate
734+
if(subplot._scene && subplot._scene.update) {
735+
// FIXME: possibly we could update axis internal _r and _rl here
736+
var xaRange = Lib.simpleMap(xa2.range, xa2.r2l),
737+
yaRange = Lib.simpleMap(ya2.range, ya2.r2l);
738+
subplot._scene.update(
739+
{range: [xaRange[0], yaRange[0], xaRange[1], yaRange[1]]}
740+
);
741+
}
742+
722743
if(editX2) {
723744
xScaleFactor2 = xScaleFactor;
724745
clipDx = ew ? viewBox[0] : getShift(xa2, xScaleFactor2);

‎src/plots/cartesian/index.js

Copy file name to clipboardExpand all lines: src/plots/cartesian/index.js
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
4848
}
4949
}
5050

51+
// clear gl frame, if any, since we preserve drawing buffer
52+
if(fullLayout._glcanvas && fullLayout._glcanvas.size()) {
53+
fullLayout._glcanvas.each(function(d) {
54+
if(d.regl) {
55+
d.regl.clear({
56+
color: true
57+
});
58+
}
59+
});
60+
}
61+
5162
for(i = 0; i < subplots.length; i++) {
5263
var subplot = subplots[i],
5364
subplotInfo = fullLayout._plots[subplot];

‎src/plots/cartesian/select.js

Copy file name to clipboardExpand all lines: src/plots/cartesian/select.js
-1Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,6 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) {
262262

263263
throttle.done(throttleID).then(function() {
264264
throttle.clear(throttleID);
265-
266265
if(!dragged && numclicks === 2) {
267266
// clear selection on doubleclick
268267
outlines.remove();

‎src/plots/gl2d/scene2d.js

Copy file name to clipboardExpand all lines: src/plots/gl2d/scene2d.js
+7-4Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ proto.makeFramework = function() {
112112
this.gl = STATIC_CONTEXT;
113113
}
114114
else {
115-
var liveCanvas = document.createElement('canvas');
115+
var liveCanvas = this.container.querySelector('.gl-canvas-focus');
116116

117117
var gl = getContext({
118118
canvas: liveCanvas,
@@ -140,7 +140,7 @@ proto.makeFramework = function() {
140140
// disabling user select on the canvas
141141
// sanitizes double-clicks interactions
142142
// ref: https://github.com/plotly/plotly.js/issues/744
143-
canvas.className += 'user-select-none';
143+
canvas.className += ' user-select-none';
144144

145145
// create SVG container for hover text
146146
var svgContainer = this.svgContainer = document.createElementNS(
@@ -157,9 +157,11 @@ proto.makeFramework = function() {
157157
mouseContainer.style.position = 'absolute';
158158
mouseContainer.style['pointer-events'] = 'auto';
159159

160+
this.pickCanvas = this.container.querySelector('.gl-canvas-pick');
161+
162+
160163
// append canvas, hover svg and mouse div to container
161164
var container = this.container;
162-
container.appendChild(canvas);
163165
container.appendChild(svgContainer);
164166
container.appendChild(mouseContainer);
165167

@@ -370,7 +372,6 @@ proto.destroy = function() {
370372

371373
this.glplot.dispose();
372374

373-
if(!this.staticPlot) this.container.removeChild(this.canvas);
374375
this.container.removeChild(this.svgContainer);
375376
this.container.removeChild(this.mouseContainer);
376377

@@ -533,8 +534,10 @@ proto.updateTraces = function(fullData, calcData) {
533534
proto.updateFx = function(dragmode) {
534535
// switch to svg interactions in lasso/select mode
535536
if(dragmode === 'lasso' || dragmode === 'select') {
537+
this.pickCanvas.style['pointer-events'] = 'none';
536538
this.mouseContainer.style['pointer-events'] = 'none';
537539
} else {
540+
this.pickCanvas.style['pointer-events'] = 'auto';
538541
this.mouseContainer.style['pointer-events'] = 'auto';
539542
}
540543

‎src/plots/plots.js

Copy file name to clipboardExpand all lines: src/plots/plots.js
+32-2Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,15 +569,29 @@ plots.createTransitionData = function(gd) {
569569

570570
// helper function to be bound to fullLayout to check
571571
// whether a certain plot type is present on plot
572+
// or trace has a category
572573
plots._hasPlotType = function(category) {
574+
// check plot
575+
573576
var basePlotModules = this._basePlotModules || [];
577+
var i;
574578

575-
for(var i = 0; i < basePlotModules.length; i++) {
579+
for(i = 0; i < basePlotModules.length; i++) {
576580
var _module = basePlotModules[i];
577581

578582
if(_module.name === category) return true;
579583
}
580584

585+
// check trace
586+
var modules = this._modules || [];
587+
588+
for(i = 0; i < modules.length; i++) {
589+
var _ = modules[i];
590+
if(_.categories && _.categories.indexOf(category) >= 0) {
591+
return true;
592+
}
593+
}
594+
581595
return false;
582596
};
583597

@@ -595,6 +609,15 @@ plots.cleanPlot = function(newFullData, newFullLayout, oldFullData, oldFullLayou
595609

596610
var hasPaper = !!oldFullLayout._paper;
597611
var hasInfoLayer = !!oldFullLayout._infolayer;
612+
var hadGl = oldFullLayout._has && oldFullLayout._has('gl');
613+
var hasGl = newFullLayout._has && newFullLayout._has('gl');
614+
615+
if(hadGl && !hasGl) {
616+
if(oldFullLayout._glcontainer !== undefined) {
617+
oldFullLayout._glcontainer.selectAll('.gl-canvas').remove();
618+
oldFullLayout._glcanvas = null;
619+
}
620+
}
598621

599622
oldLoop:
600623
for(i = 0; i < oldFullData.length; i++) {
@@ -1308,7 +1331,11 @@ plots.purge = function(gd) {
13081331
// a new plot, and may have been set outside of our scope.
13091332

13101333
var fullLayout = gd._fullLayout || {};
1311-
if(fullLayout._glcontainer !== undefined) fullLayout._glcontainer.remove();
1334+
if(fullLayout._glcontainer !== undefined) {
1335+
fullLayout._glcontainer.selectAll('.gl-canvas').remove();
1336+
fullLayout._glcontainer.remove();
1337+
fullLayout._glcanvas = null;
1338+
}
13121339
if(fullLayout._geocontainer !== undefined) fullLayout._geocontainer.remove();
13131340

13141341
// remove modebar
@@ -1326,6 +1353,9 @@ plots.purge = function(gd) {
13261353
}
13271354
}
13281355

1356+
// remove any planned throttles
1357+
Lib.clearThrottle();
1358+
13291359
// data and layout
13301360
delete gd.data;
13311361
delete gd.layout;

‎src/traces/contourgl/index.js

Copy file name to clipboardExpand all lines: src/traces/contourgl/index.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ ContourGl.plot = require('./convert');
2323
ContourGl.moduleType = 'trace';
2424
ContourGl.name = 'contourgl';
2525
ContourGl.basePlotModule = require('../../plots/gl2d');
26-
ContourGl.categories = ['gl2d', '2dMap'];
26+
ContourGl.categories = ['gl', 'gl2d', '2dMap'];
2727
ContourGl.meta = {
2828
description: [
2929
'WebGL contour (beta)'

‎src/traces/heatmapgl/index.js

Copy file name to clipboardExpand all lines: src/traces/heatmapgl/index.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ HeatmapGl.plot = require('./convert');
2121
HeatmapGl.moduleType = 'trace';
2222
HeatmapGl.name = 'heatmapgl';
2323
HeatmapGl.basePlotModule = require('../../plots/gl2d');
24-
HeatmapGl.categories = ['gl2d', '2dMap'];
24+
HeatmapGl.categories = ['gl', 'gl2d', '2dMap'];
2525
HeatmapGl.meta = {
2626
description: [
2727
'WebGL version of the heatmap trace type.'

‎src/traces/parcoords/base_plot.js

Copy file name to clipboardExpand all lines: src/traces/parcoords/base_plot.js
+6-12Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ var d3 = require('d3');
1212
var Plots = require('../../plots/plots');
1313
var parcoordsPlot = require('./plot');
1414
var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
15-
var c = require('./constants');
1615

1716
exports.name = 'parcoords';
1817

@@ -28,9 +27,6 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout)
2827
var hasParcoords = (newFullLayout._has && newFullLayout._has('parcoords'));
2928

3029
if(hadParcoords && !hasParcoords) {
31-
oldFullLayout._paperdiv.selectAll('.parcoords-line-layers').remove();
32-
oldFullLayout._paperdiv.selectAll('.parcoords-line-layers').remove();
33-
oldFullLayout._paperdiv.selectAll('.parcoords').remove();
3430
oldFullLayout._paperdiv.selectAll('.parcoords').remove();
3531
oldFullLayout._glimages.selectAll('*').remove();
3632
}
@@ -41,22 +37,20 @@ exports.toSVG = function(gd) {
4137
var imageRoot = gd._fullLayout._glimages;
4238
var root = d3.select(gd).selectAll('.svg-container');
4339
var canvases = root.filter(function(d, i) {return i === root.size() - 1;})
44-
.selectAll('.parcoords-lines.context, .parcoords-lines.focus');
40+
.selectAll('.gl-canvas-context, .gl-canvas-focus');
4541

46-
function canvasToImage(d) {
42+
function canvasToImage() {
4743
var canvas = this;
4844
var imageData = canvas.toDataURL('image/png');
4945
var image = imageRoot.append('svg:image');
50-
var size = gd._fullLayout._size;
51-
var domain = gd._fullData[d.model.key].domain;
5246

5347
image.attr({
5448
xmlns: xmlnsNamespaces.svg,
5549
'xlink:href': imageData,
56-
x: size.l + size.w * domain.x[0] - c.overdrag,
57-
y: size.t + size.h * (1 - domain.y[1]),
58-
width: (domain.x[1] - domain.x[0]) * size.w + 2 * c.overdrag,
59-
height: (domain.y[1] - domain.y[0]) * size.h,
50+
x: 0,
51+
y: 0,
52+
width: canvas.width,
53+
height: canvas.height,
6054
preserveAspectRatio: 'none'
6155
});
6256
}

‎src/traces/parcoords/index.js

Copy file name to clipboardExpand all lines: src/traces/parcoords/index.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Parcoords.colorbar = require('./colorbar');
1919
Parcoords.moduleType = 'trace';
2020
Parcoords.name = 'parcoords';
2121
Parcoords.basePlotModule = require('./base_plot');
22-
Parcoords.categories = ['gl', 'noOpacity'];
22+
Parcoords.categories = ['gl', 'regl', 'noOpacity'];
2323
Parcoords.meta = {
2424
description: [
2525
'Parallel coordinates for multidimensional exploratory data analysis.',

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.