Skip to content

Reuse SVG DOM elements for scatter traces #675

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 13 additions & 4 deletions src/components/errorbars/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,24 @@ module.exports = function plot(traces, plotinfo) {
trace.marker.maxdisplayed > 0
);

var keyFunc;

if(trace.key) {
keyFunc = function(d) { return d.key; };
}

if(!yObj.visible && !xObj.visible) return;

var errorbars = d3.select(this).selectAll('g.errorbar')
.data(Lib.identity);
var selection = d3.select(this).selectAll('g.errorbar');

errorbars.enter().append('g')
var join = selection.data(Lib.identity, keyFunc);

join.enter().append('g')
.classed('errorbar', true);

errorbars.each(function(d) {
join.exit().remove();

join.each(function(d) {
var errorbar = d3.select(this);
var coords = errorCoords(d, xa, ya);

Expand Down
81 changes: 47 additions & 34 deletions src/plots/cartesian/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,61 +25,74 @@ exports.attrRegex = constants.attrRegex;

exports.attributes = require('./attributes');

exports.plot = function(gd) {
exports.plot = function(gd, traces) {
var cdSubplot, cd, trace, i, j, k, isFullReplot;

var fullLayout = gd._fullLayout,
subplots = Plots.getSubplotIds(fullLayout, 'cartesian'),
calcdata = gd.calcdata,
modules = fullLayout._modules;

function getCdSubplot(calcdata, subplot) {
var cdSubplot = [];

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

if(trace.xaxis + trace.yaxis === subplot) {
cdSubplot.push(cd);
}
}

return cdSubplot;
if (!Array.isArray(traces)) {
// If traces is not provided, then it's a complete replot and missing
// traces are removed
isFullReplot = true;
traces = [];
for (i = 0; i < calcdata.length; i++) {
traces.push(i);
}
} else {
// If traces are explicitly specified, then it's a partial replot and
// traces are not removed.
isFullReplot = false;
}

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

for(var i = 0; i < cdSubplot.length; i++) {
var cd = cdSubplot[i];
// Get all calcdata for this subplot:
cdSubplot = [];
for(j = 0; j < calcdata.length; j++) {
var cd = calcdata[j];
var trace = cd[0].trace;

if((trace._module === _module) && (trace.visible === true)) {
cdModule.push(cd);
// Skip trace if whitelist provided and it's not whitelisted:
// if (Array.isArray(traces) && traces.indexOf(i) === -1) continue;

if(trace.xaxis + trace.yaxis === subplot && traces.indexOf(trace.index) !== -1) {
cdSubplot.push(cd);
}
}

return cdModule;
}

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

// remove old traces, then redraw everything
// TODO: use enter/exit appropriately in the plot functions
// so we don't need this - should sometimes be a big speedup
if(subplotInfo.plot) subplotInfo.plot.selectAll('g.trace').remove();
// 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(subplotInfo.plot) {
subplotInfo.plot.selectAll('g:not(.scatterlayer)').selectAll('g.trace').remove();
}

for(var j = 0; j < modules.length; j++) {
// Plot all traces for each module at once:
for(j = 0; j < modules.length; j++) {
var _module = modules[j];

// skip over non-cartesian trace modules
if(_module.basePlotModule.name !== 'cartesian') continue;

// plot all traces of this type on this subplot at once
var cdModule = getCdModule(cdSubplot, _module);
_module.plot(gd, subplotInfo, cdModule);
var cdModule = [];
for(k = 0; k < cdSubplot.length; k++) {
var cd = cdSubplot[k];
var trace = cd[0].trace;

if((trace._module === _module) && (trace.visible === true)) {
cdModule.push(cd);
}
}

_module.plot(gd, subplotInfo, cdModule, isFullReplot);
}
}
};
3 changes: 2 additions & 1 deletion src/plots/plots.js
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,8 @@ plots.cleanPlot = function(newFullData, newFullLayout, oldFullData, oldFullLayou
oldFullLayout._paper.selectAll(
'.hm' + oldUid +
',.contour' + oldUid +
',#clip' + oldUid
',#clip' + oldUid +
',.trace' + oldUid
).remove();
}

Expand Down
44 changes: 44 additions & 0 deletions src/traces/scatter/link_traces.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

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

module.exports = function linkTraces(gd, plotinfo, cdscatter) {
var i, cd, trace;
var xa = plotinfo.x();
var ya = plotinfo.y();

var prevtrace = null;

for(i = 0; i < cdscatter.length; ++i) {
cd = cdscatter[i];
trace = cd[0].trace;

// console.log('visible:', trace.uid, trace.visible);
if(trace.visible === true && Plots.traceIs(trace, 'cartesian') &&
trace.xaxis === xa._id &&
trace.yaxis === ya._id) {

trace._nexttrace = null;

if(['tonextx', 'tonexty', 'tonext'].indexOf(trace.fill) !== -1) {
trace._prevtrace = prevtrace;

if(prevtrace) {
prevtrace._nexttrace = trace;
}
}

prevtrace = trace;
} else {
trace._prevtrace = trace._nexttrace = null;
}
}
};
Loading