Skip to content

Commit 63af430

Browse files
committed
Make parcoords use shared canvases
1 parent 6290a83 commit 63af430

File tree

3 files changed

+62
-46
lines changed

3 files changed

+62
-46
lines changed

src/plot_api/plot_api.js

+35-3
Original file line numberDiff line numberDiff line change
@@ -3027,9 +3027,41 @@ function makePlotFramework(gd) {
30273027
// TODO: sort out all the ordering so we don't have to
30283028
// explicitly delete anything
30293029
fullLayout._glcontainer = fullLayout._paperdiv.selectAll('.gl-container')
3030-
.data([0]);
3031-
fullLayout._glcontainer.enter().append('div')
3032-
.classed('gl-container', true);
3030+
.data([{}]);
3031+
3032+
// FIXME: bring this constant to some plotly constants module
3033+
// it is taken from parcoords lineLayerModel
3034+
fullLayout._glcanvas = fullLayout._glcontainer.enter().append('div')
3035+
.classed('gl-container', true)
3036+
.selectAll('.gl-canvas')
3037+
.data([{
3038+
key: 'contextLayer'
3039+
}, {
3040+
key: 'focusLayer'
3041+
}, {
3042+
key: 'pickLayer'
3043+
}]);
3044+
3045+
// create canvases only in case if there is at least one regl component
3046+
// FIXME: probably there is a better d3 way of doing so
3047+
for(var i = 0; i < fullLayout._modules.length; i++) {
3048+
var module = fullLayout._modules[i];
3049+
if(module.categories && module.categories.indexOf('gl') >= 0) {
3050+
fullLayout._glcanvas.enter().append('canvas')
3051+
.attr('class', function(d) {
3052+
return 'gl-canvas gl-canvas-' + d.key.replace('Layer', '');
3053+
})
3054+
.attr('width', fullLayout.width)
3055+
.attr('height', fullLayout.height)
3056+
.style('position', 'absolute')
3057+
.style('top', 0)
3058+
.style('left', 0)
3059+
.style('pointer-events', 'none')
3060+
.style('overflow', 'visible');
3061+
3062+
break;
3063+
}
3064+
}
30333065

30343066
fullLayout._paperdiv.selectAll('.main-svg').remove();
30353067

src/traces/parcoords/parcoords.js

+25-43
Original file line numberDiff line numberDiff line change
@@ -233,18 +233,6 @@ function viewModel(model) {
233233
return viewModel;
234234
}
235235

236-
function lineLayerModel(vm) {
237-
return c.layers.map(function(key) {
238-
return {
239-
key: key,
240-
context: key === 'contextLineLayer',
241-
pick: key === 'pickLineLayer',
242-
viewModel: vm,
243-
model: vm.model
244-
};
245-
});
246-
}
247-
248236
function styleExtentTexts(selection) {
249237
selection
250238
.classed('axisExtentText', true)
@@ -253,7 +241,7 @@ function styleExtentTexts(selection) {
253241
.style('user-select', 'none');
254242
}
255243

256-
module.exports = function(root, svg, styledData, layout, callbacks) {
244+
module.exports = function(root, svg, parcoordsLineLayers, styledData, layout, callbacks) {
257245
var domainBrushing = false;
258246
var linePickActive = true;
259247

@@ -300,37 +288,31 @@ module.exports = function(root, svg, styledData, layout, callbacks) {
300288
.map(model.bind(0, layout))
301289
.map(viewModel);
302290

303-
root.selectAll('.parcoords-line-layers').remove();
304-
305-
var parcoordsLineLayers = root.selectAll('.parcoords-line-layers')
306-
.data(vm, keyFun);
307-
308-
parcoordsLineLayers.enter()
309-
.insert('div', '.' + svg.attr('class').split(' ').join(' .')) // not hardcoding .main-svg
310-
.classed('parcoords-line-layers', true)
311-
.style('box-sizing', 'content-box');
291+
parcoordsLineLayers.each(function(d, i) {
292+
return Lib.extendFlat(d, vm[i]);
293+
});
312294

313295
parcoordsLineLayers
314296
.style('transform', function(d) {
315297
return 'translate(' + (d.model.translateX - c.overdrag) + 'px,' + d.model.translateY + 'px)';
316298
});
317299

318-
var parcoordsLineLayer = parcoordsLineLayers.selectAll('.parcoords-lines')
319-
.data(lineLayerModel, keyFun);
300+
var parcoordsLineLayer = parcoordsLineLayers.selectAll('.gl-canvas')
301+
.each(function(d) {
302+
var key = d.key;
303+
d.context = key === 'contextLayer';
304+
d.pick = key === 'pickLayer';
305+
306+
// FIXME: figure out how to handle multiple instances
307+
d.viewModel = vm[0];
308+
d.model = vm[0].model;
309+
});
320310

321311
var tweakables = {renderers: [], dimensions: []};
322312

323313
var lastHovered = null;
324314

325-
parcoordsLineLayer.enter()
326-
.append('canvas')
327-
.attr('class', function(d) {return 'parcoords-lines ' + (d.context ? 'context' : d.pick ? 'pick' : 'focus');})
328-
.style('box-sizing', 'content-box')
329-
.style('float', 'left')
330-
.style('clear', 'both')
331-
.style('left', 0)
332-
.style('overflow', 'visible')
333-
.style('position', function(d, i) {return i > 0 ? 'absolute' : 'absolute';})
315+
parcoordsLineLayer
334316
.filter(function(d) {return d.pick;})
335317
.on('mousemove', function(d) {
336318
if(linePickActive && d.lineLayer && callbacks && callbacks.hover) {
@@ -512,8 +494,8 @@ module.exports = function(root, svg, styledData, layout, callbacks) {
512494
.attr('transform', function(d) {return 'translate(' + d.xScale(d.xIndex) + ', 0)';});
513495
d3.select(this).attr('transform', 'translate(' + d.x + ', 0)');
514496
yAxis.each(function(dd, i, ii) {if(ii === d.parent.key) p.dimensions[i] = dd;});
515-
p.contextLineLayer && p.contextLineLayer.render(p.panels, false, !someFiltersActive(p));
516-
p.focusLineLayer.render && p.focusLineLayer.render(p.panels);
497+
p.contextLayer && p.contextLayer.render(p.panels, false, !someFiltersActive(p));
498+
p.focusLayer.render && p.focusLayer.render(p.panels);
517499
})
518500
.on('dragend', function(d) {
519501
var p = d.parent;
@@ -528,9 +510,9 @@ module.exports = function(root, svg, styledData, layout, callbacks) {
528510
updatePanelLayout(yAxis, p);
529511
d3.select(this)
530512
.attr('transform', function(d) {return 'translate(' + d.x + ', 0)';});
531-
p.contextLineLayer && p.contextLineLayer.render(p.panels, false, !someFiltersActive(p));
532-
p.focusLineLayer && p.focusLineLayer.render(p.panels);
533-
p.pickLineLayer && p.pickLineLayer.render(p.panels, true);
513+
p.contextLayer && p.contextLayer.render(p.panels, false, !someFiltersActive(p));
514+
p.focusLayer && p.focusLayer.render(p.panels);
515+
p.pickLayer && p.pickLayer.render(p.panels, true);
534516
linePickActive = true;
535517

536518
if(callbacks && callbacks.axesMoved) {
@@ -742,13 +724,13 @@ module.exports = function(root, svg, styledData, layout, callbacks) {
742724
var newExtent = reset ? [0, 1] : extent.slice();
743725
if(newExtent[0] !== filter[0] || newExtent[1] !== filter[1]) {
744726
dimensions[dimension.xIndex].filter = newExtent;
745-
p.focusLineLayer && p.focusLineLayer.render(p.panels, true);
727+
p.focusLayer && p.focusLayer.render(p.panels, true);
746728
var filtersActive = someFiltersActive(p);
747729
if(!contextShown && filtersActive) {
748-
p.contextLineLayer && p.contextLineLayer.render(p.panels, true);
730+
p.contextLayer && p.contextLayer.render(p.panels, true);
749731
contextShown = true;
750732
} else if(contextShown && !filtersActive) {
751-
p.contextLineLayer && p.contextLineLayer.render(p.panels, true, true);
733+
p.contextLayer && p.contextLayer.render(p.panels, true, true);
752734
contextShown = false;
753735
}
754736
}
@@ -769,9 +751,9 @@ module.exports = function(root, svg, styledData, layout, callbacks) {
769751
f[1] = Math.min(1, f[1] + 0.05);
770752
}
771753
d3.select(this).transition().duration(150).call(dimension.brush.extent(f));
772-
p.focusLineLayer.render(p.panels, true);
754+
p.focusLayer.render(p.panels, true);
773755
}
774-
p.pickLineLayer && p.pickLineLayer.render(p.panels, true);
756+
p.pickLayer && p.pickLayer.render(p.panels, true);
775757
linePickActive = true;
776758
domainBrushing = 'ending';
777759
if(callbacks && callbacks.filterChanged) {

src/traces/parcoords/plot.js

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = function plot(gd, cdparcoords) {
1515
var fullLayout = gd._fullLayout;
1616
var svg = fullLayout._paper;
1717
var root = fullLayout._paperdiv;
18+
var container = fullLayout._glcontainer;
1819

1920
var gdDimensions = {};
2021
var gdDimensionsOriginalOrder = {};
@@ -98,6 +99,7 @@ module.exports = function plot(gd, cdparcoords) {
9899
parcoords(
99100
root,
100101
svg,
102+
container,
101103
cdparcoords,
102104
{
103105
width: size.w,

0 commit comments

Comments
 (0)