Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/rangeslider/draw.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -448,8 +448,8 @@ function drawRangePlot(rangeSlider, gd, axisOpts, opts) {

Plots.supplyDefaults(mockFigure);

var xa = mockFigure._fullLayout.xaxis,
ya = mockFigure._fullLayout[oppAxisName];
var xa = mockFigure._fullLayout.xaxis;
var ya = mockFigure._fullLayout[oppAxisName];

var plotinfo = {
id: id,
Expand Down
38 changes: 5 additions & 33 deletions src/plot_api/subroutines.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,6 @@ var Titles = require('../components/titles');
var ModeBar = require('../components/modebar');

var Axes = require('../plots/cartesian/axes');
var cartesianConstants = require('../plots/cartesian/constants');
var alignmentConstants = require('../constants/alignment');
var axisConstraints = require('../plots/cartesian/constraints');
var enforceAxisConstraints = axisConstraints.enforce;
Expand DownExpand Up@@ -199,15 +198,9 @@ exports.lsInner = function(gd) {

Drawing.setClipUrl(plotinfo.plot, plotClipId);

for(i = 0; i < cartesianConstants.traceLayerClasses.length; i++) {
var layer = cartesianConstants.traceLayerClasses[i];
if(layer !== 'scatterlayer' && layer !== 'barlayer') {
plotinfo.plot.selectAll('g.' + layer).call(Drawing.setClipUrl, layerClipId);
}
}

// stash layer clipId value (null or same as clipId)
// to DRY up Drawing.setClipUrl calls downstream
// to DRY up Drawing.setClipUrl calls on trace-module and trace layers
// downstream
plotinfo.layerClipId = layerClipId;

// figure out extra axis line and tick positions as needed
Expand DownExpand Up@@ -495,34 +488,13 @@ exports.doCamera = function(gd) {
exports.drawData = function(gd) {
var fullLayout = gd._fullLayout;
var calcdata = gd.calcdata;
var rangesliderContainers = fullLayout._infolayer.selectAll('g.rangeslider-container');
var i;

// in case of traces that were heatmaps or contour maps
// previously, remove them and their colorbars explicitly
// remove old colorbars explicitly
for(i = 0; i < calcdata.length; i++) {
var trace = calcdata[i][0].trace;
var isVisible = (trace.visible === true);
var uid = trace.uid;

if(!isVisible || !Registry.traceIs(trace, '2dMap')) {
var query = (
'.hm' + uid +
',.contour' + uid +
',#clip' + uid
);

fullLayout._paper
.selectAll(query)
.remove();

rangesliderContainers
.selectAll(query)
.remove();
}

if(!isVisible || !trace._module.colorbar) {
fullLayout._infolayer.selectAll('.cb' + uid).remove();
if(trace.visible !== true || !trace._module.colorbar) {
fullLayout._infolayer.select('.cb' + trace.uid).remove();
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/plots/cartesian/constants.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -61,15 +61,16 @@ module.exports = {
DFLTRANGEY: [-1, 4],

// Layers to keep trace types in the right order
// N.B. each 'unique' plot method must have its own layer
traceLayerClasses: [
'imagelayer',
'maplayer',
'heatmaplayer',
'contourcarpetlayer', 'contourlayer',
'barlayer',
'carpetlayer',
'violinlayer',
'boxlayer',
'ohlclayer',
'scatterlayer'
'scattercarpetlayer', 'scatterlayer'
],

layerValue2layerClass: {
Expand Down
186 changes: 87 additions & 99 deletions src/plots/cartesian/index.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,10 +10,13 @@
'use strict';

var d3 = require('d3');

var Registry = require('../../registry');
var Lib = require('../../lib');
var Plots = require('../plots');
var getModuleCalcData = require('../get_data').getModuleCalcData;
var Drawing = require('../../components/drawing');

var getModuleCalcData = require('../get_data').getModuleCalcData;
var axisIds = require('./axis_ids');
var constants = require('./constants');
var xmlnsNamespaces = require('../../constants/xmlns_namespaces');
Expand DownExpand Up@@ -129,23 +132,20 @@ exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
// traces are removed
if(!Array.isArray(traces)) {
traces = [];

for(i = 0; i < calcdata.length; i++) {
traces.push(i);
}
for(i = 0; i < calcdata.length; i++) traces.push(i);
}

for(i = 0; i < subplots.length; i++) {
var subplot = subplots[i],
subplotInfo = fullLayout._plots[subplot];
var subplot = subplots[i];
var subplotInfo = fullLayout._plots[subplot];

// Get all calcdata for this subplot:
var cdSubplot = [];
var pcd;

for(var j = 0; j < calcdata.length; j++) {
var cd = calcdata[j],
trace = cd[0].trace;
var cd = calcdata[j];
var trace = cd[0].trace;

// Skip trace if whitelist provided and it's not whitelisted:
// if (Array.isArray(traces) && traces.indexOf(i) === -1) continue;
Expand DownExpand Up@@ -182,115 +182,110 @@ exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
};

function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback) {
var fullLayout = gd._fullLayout,
modules = fullLayout._modules;

// remove old traces, then redraw everything
//
// TODO: scatterlayer is manually excluded from this since it knows how
// to update instead of fully removing and redrawing every time. The
// remaining plot traces should also be able to do this. Once implemented,
// we won't need this - which should sometimes be a big speedup.
if(plotinfo.plot) {
plotinfo.plot.selectAll('g:not(.scatterlayer):not(.ohlclayer)').selectAll('g.trace').remove();
var traceLayerClasses = constants.traceLayerClasses;
var fullLayout = gd._fullLayout;
var modules = fullLayout._modules;
var _module, cdModuleAndOthers, cdModule;

var layerData = [];

for(var i = 0; i < modules.length; i++) {
_module = modules[i];
var name = _module.name;

if(Registry.modules[name].categories.svg) {
var className = (_module.layerName || name + 'layer');
var plotMethod = _module.plot;

// plot all traces of this type on this subplot at once
cdModuleAndOthers = getModuleCalcData(cdSubplot, plotMethod);
cdModule = cdModuleAndOthers[0];
// don't need to search the found traces again - in fact we need to NOT
// so that if two modules share the same plotter we don't double-plot
cdSubplot = cdModuleAndOthers[1];

if(cdModule.length) {
layerData.push({
i: traceLayerClasses.indexOf(className),
className: className,
plotMethod: plotMethod,
cdModule: cdModule
});
}
}
}

// plot all traces for each module at once
for(var j = 0; j < modules.length; j++) {
var _module = modules[j];
layerData.sort(function(a, b) { return a.i - b.i; });

var layers = plotinfo.plot.selectAll('g.mlayer')
.data(layerData, function(d) { return d.className; });

// skip over non-cartesian trace modules
if(!_module.plot || _module.basePlotModule.name !== 'cartesian') continue;
layers.enter().append('g')
.attr('class', function(d) { return d.className; })
.classed('mlayer', true);

// plot all traces of this type on this subplot at once
var cdModuleAndOthers = getModuleCalcData(cdSubplot, _module);
var cdModule = cdModuleAndOthers[0];
// don't need to search the found traces again - in fact we need to NOT
// so that if two modules share the same plotter we don't double-plot
cdSubplot = cdModuleAndOthers[1];
layers.exit().remove();

_module.plot(gd, plotinfo, cdModule, transitionOpts, makeOnCompleteCallback);
layers.order();

layers.each(function(d) {
var sel = d3.select(this);
var className = d.className;

d.plotMethod(
gd, plotinfo, d.cdModule, sel,
transitionOpts, makeOnCompleteCallback
);

// layers that allow `cliponaxis: false`
if(className !== 'scatterlayer' && className !== 'barlayer') {
Drawing.setClipUrl(sel, plotinfo.layerClipId);
}
});

// call Scattergl.plot separately
if(fullLayout._has('scattergl')) {
_module = Registry.getModule('scattergl');
cdModule = getModuleCalcData(cdSubplot, _module)[0];
_module.plot(gd, plotinfo, cdModule);
}
}

exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) {
var oldModules = oldFullLayout._modules || [];
var newModules = newFullLayout._modules || [];
var oldPlots = oldFullLayout._plots || {};

var hadScatter, hasScatter;
var hadOHLC, hasOHLC;
var hadGl, hasGl;
var i, k, subplotInfo, moduleName;
var newPlots = newFullLayout._plots || {};
var oldSubplotList = oldFullLayout._subplots || {};
var plotinfo;
var i, k;

// when going from a large splom graph to something else,
// we need to clear <g subplot> so that the new cartesian subplot
// can have the correct layer ordering
if(oldFullLayout._hasOnlyLargeSploms && !newFullLayout._hasOnlyLargeSploms) {
for(k in oldPlots) {
subplotInfo = oldPlots[k];
if(subplotInfo.plotgroup) subplotInfo.plotgroup.remove();
plotinfo = oldPlots[k];
if(plotinfo.plotgroup) plotinfo.plotgroup.remove();
}
}

for(i = 0; i < oldModules.length; i++) {
moduleName = oldModules[i].name;
if(moduleName === 'scatter') hadScatter = true;
else if(moduleName === 'scattergl') hadGl = true;
else if(moduleName === 'ohlc') hadOHLC = true;
}

for(i = 0; i < newModules.length; i++) {
moduleName = newModules[i].name;
if(moduleName === 'scatter') hasScatter = true;
else if(moduleName === 'scattergl') hasGl = true;
else if(moduleName === 'ohlc') hasOHLC = true;
}

var layersToEmpty = [];
if(hadScatter && !hasScatter) layersToEmpty.push('g.scatterlayer');
if(hadOHLC && !hasOHLC) layersToEmpty.push('g.ohlclayer');

if(layersToEmpty.length) {
for(var layeri = 0; layeri < layersToEmpty.length; layeri++) {
for(k in oldPlots) {
subplotInfo = oldPlots[k];
if(subplotInfo.plot) {
subplotInfo.plot.select(layersToEmpty[layeri])
.selectAll('g.trace')
.remove();
}
}

oldFullLayout._infolayer.selectAll('g.rangeslider-container')
.select(layersToEmpty[layeri])
.selectAll('g.trace')
.remove();
}
}
var hadGl = (oldFullLayout._has && oldFullLayout._has('gl'));
var hasGl = (newFullLayout._has && newFullLayout._has('gl'));

if(hadGl && !hasGl) {
for(k in oldPlots) {
subplotInfo = oldPlots[k];

if(subplotInfo._scene) {
subplotInfo._scene.destroy();
}
plotinfo = oldPlots[k];
if(plotinfo._scene) plotinfo._scene.destroy();
}
}

var oldSubplotList = oldFullLayout._subplots || {};
var newSubplotList = newFullLayout._subplots || {xaxis: [], yaxis: []};

// delete any titles we don't need anymore
// check if axis list has changed, and if so clear old titles
if(oldSubplotList.xaxis && oldSubplotList.yaxis) {
var oldAxIDs = oldSubplotList.xaxis.concat(oldSubplotList.yaxis);
var newAxIDs = newSubplotList.xaxis.concat(newSubplotList.yaxis);

var oldAxIDs = axisIds.listIds({_fullLayout: oldFullLayout});
for(i = 0; i < oldAxIDs.length; i++) {
if(newAxIDs.indexOf(oldAxIDs[i]) === -1) {
oldFullLayout._infolayer.selectAll('.g-' + oldAxIDs[i] + 'title').remove();
var oldAxId = oldAxIDs[i];
if(!newFullLayout[axisIds.id2name(oldAxId)]) {
oldFullLayout._infolayer.selectAll('.g-' + oldAxId + 'title').remove();
}
}
}
Expand All@@ -308,7 +303,7 @@ exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout)
else if(oldSubplotList.cartesian) {
for(i = 0; i < oldSubplotList.cartesian.length; i++) {
var oldSubplotId = oldSubplotList.cartesian[i];
if(newSubplotList.cartesian.indexOf(oldSubplotId) === -1) {
if(!newPlots[oldSubplotId]) {
var selector = '.' + oldSubplotId + ',.' + oldSubplotId + '-x,.' + oldSubplotId + '-y';
oldFullLayout._cartesianlayer.selectAll(selector).remove();
removeSubplotExtras(oldSubplotId, oldFullLayout);
Expand DownExpand Up@@ -482,10 +477,6 @@ function makeSubplotLayer(gd, plotinfo) {
ensureSingleAndAddDatum(plotinfo.gridlayer, 'g', plotinfo.xaxis._id);
ensureSingleAndAddDatum(plotinfo.gridlayer, 'g', plotinfo.yaxis._id);
plotinfo.gridlayer.selectAll('g').sort(axisIds.idSort);

for(var i = 0; i < constants.traceLayerClasses.length; i++) {
ensureSingle(plotinfo.plot, 'g', constants.traceLayerClasses[i]);
}
}

plotinfo.xlines
Expand DownExpand Up@@ -516,11 +507,8 @@ function purgeSubplotLayers(layers, fullLayout) {

// must remove overlaid subplot trace layers 'manually'

var subplots = fullLayout._plots;
var subplotIds = Object.keys(subplots);

for(var i = 0; i < subplotIds.length; i++) {
var subplotInfo = subplots[subplotIds[i]];
for(var k in fullLayout._plots) {
var subplotInfo = fullLayout._plots[k];
var overlays = subplotInfo.overlays || [];

for(var j = 0; j < overlays.length; j++) {
Expand Down
Loading