|
10 | 10 | 'use strict'; |
11 | 11 |
|
12 | 12 | var d3 = require('d3'); |
| 13 | + |
| 14 | +var Registry = require('../../registry'); |
13 | 15 | var Lib = require('../../lib'); |
14 | 16 | var Plots = require('../plots'); |
15 | | -var getModuleCalcData = require('../get_data').getModuleCalcData; |
| 17 | +var Drawing = require('../../components/drawing'); |
16 | 18 |
|
| 19 | +var getModuleCalcData = require('../get_data').getModuleCalcData; |
17 | 20 | var axisIds = require('./axis_ids'); |
18 | 21 | var constants = require('./constants'); |
19 | 22 | var xmlnsNamespaces = require('../../constants/xmlns_namespaces'); |
@@ -179,40 +182,75 @@ exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) { |
179 | 182 | }; |
180 | 183 |
|
181 | 184 | function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback) { |
| 185 | + var traceLayerClasses = constants.traceLayerClasses; |
182 | 186 | var fullLayout = gd._fullLayout; |
183 | 187 | var modules = fullLayout._modules; |
184 | | - // list of plot methods to call (this list includes plot methods of 'gone' modules) |
185 | | - var plotMethodsToCall = plotinfo.plotMethods || []; |
186 | | - // list of plot methods of visible module on this subplot |
187 | | - var plotMethods = []; |
188 | | - var i, plotMethod; |
189 | | - |
190 | | - for(i = 0; i < modules.length; i++) { |
191 | | - var _module = modules[i]; |
192 | | - |
193 | | - if(_module.basePlotModule.name === 'cartesian') { |
194 | | - plotMethod = _module.plot; |
195 | | - Lib.pushUnique(plotMethodsToCall, plotMethod); |
196 | | - Lib.pushUnique(plotMethods, plotMethod); |
| 188 | + var _module, cdModuleAndOthers, cdModule; |
| 189 | + |
| 190 | + var layerData = []; |
| 191 | + |
| 192 | + for(var i = 0; i < traceLayerClasses.length; i++) { |
| 193 | + var className = traceLayerClasses[i]; |
| 194 | + |
| 195 | + for(var j = 0; j < modules.length; j++) { |
| 196 | + _module = modules[j]; |
| 197 | + |
| 198 | + if(_module.basePlotModule.name === 'cartesian' && |
| 199 | + (_module.layerName || _module.name + 'layer') === className |
| 200 | + ) { |
| 201 | + var plotMethod = _module.plot; |
| 202 | + |
| 203 | + // plot all traces of this type on this subplot at once |
| 204 | + cdModuleAndOthers = getModuleCalcData(cdSubplot, plotMethod); |
| 205 | + cdModule = cdModuleAndOthers[0]; |
| 206 | + // don't need to search the found traces again - in fact we need to NOT |
| 207 | + // so that if two modules share the same plotter we don't double-plot |
| 208 | + cdSubplot = cdModuleAndOthers[1]; |
| 209 | + |
| 210 | + if(cdModule.length) { |
| 211 | + layerData.push({ |
| 212 | + className: className, |
| 213 | + plotMethod: plotMethod, |
| 214 | + cdModule: cdModule |
| 215 | + }); |
| 216 | + } |
| 217 | + break; |
| 218 | + } |
197 | 219 | } |
198 | 220 | } |
199 | 221 |
|
200 | | - for(i = 0; i < plotMethodsToCall.length; i++) { |
201 | | - plotMethod = plotMethodsToCall[i]; |
| 222 | + var layers = plotinfo.plot.selectAll('g.mlayer') |
| 223 | + .data(layerData, function(d) { return d.className; }); |
202 | 224 |
|
203 | | - // plot all traces of this type on this subplot at once |
204 | | - var cdModuleAndOthers = getModuleCalcData(cdSubplot, plotMethod); |
205 | | - var cdModule = cdModuleAndOthers[0]; |
206 | | - // don't need to search the found traces again - in fact we need to NOT |
207 | | - // so that if two modules share the same plotter we don't double-plot |
208 | | - cdSubplot = cdModuleAndOthers[1]; |
| 225 | + layers.enter().append('g') |
| 226 | + .attr('class', function(d) { return d.className; }) |
| 227 | + .classed('mlayer', true); |
209 | 228 |
|
210 | | - plotMethod(gd, plotinfo, cdModule, transitionOpts, makeOnCompleteCallback); |
211 | | - } |
| 229 | + layers.exit().remove(); |
| 230 | + |
| 231 | + layers.order(); |
| 232 | + |
| 233 | + layers.each(function(d) { |
| 234 | + var sel = d3.select(this); |
| 235 | + var className = d.className; |
212 | 236 |
|
213 | | - // save list of plot methods on subplot for later, |
214 | | - // so that they can be called to clear traces of 'gone' modules |
215 | | - plotinfo.plotMethods = plotMethods; |
| 237 | + d.plotMethod( |
| 238 | + gd, plotinfo, d.cdModule, sel, |
| 239 | + transitionOpts, makeOnCompleteCallback |
| 240 | + ); |
| 241 | + |
| 242 | + // layers that allow `cliponaxis: false` |
| 243 | + if(className !== 'scatterlayer' && className !== 'barlayer') { |
| 244 | + Drawing.setClipUrl(sel, plotinfo.layerClipId); |
| 245 | + } |
| 246 | + }); |
| 247 | + |
| 248 | + // call Scattergl.plot separately |
| 249 | + if(fullLayout._has('scattergl')) { |
| 250 | + _module = Registry.getModule('scattergl'); |
| 251 | + cdModule = getModuleCalcData(cdSubplot, _module)[0]; |
| 252 | + _module.plot(gd, plotinfo, cdModule); |
| 253 | + } |
216 | 254 | } |
217 | 255 |
|
218 | 256 | exports.clean = function(newFullData, newFullLayout, oldFullData, oldFullLayout) { |
@@ -441,10 +479,6 @@ function makeSubplotLayer(gd, plotinfo) { |
441 | 479 | ensureSingleAndAddDatum(plotinfo.gridlayer, 'g', plotinfo.xaxis._id); |
442 | 480 | ensureSingleAndAddDatum(plotinfo.gridlayer, 'g', plotinfo.yaxis._id); |
443 | 481 | plotinfo.gridlayer.selectAll('g').sort(axisIds.idSort); |
444 | | - |
445 | | - for(var i = 0; i < constants.traceLayerClasses.length; i++) { |
446 | | - ensureSingle(plotinfo.plot, 'g', constants.traceLayerClasses[i]); |
447 | | - } |
448 | 482 | } |
449 | 483 |
|
450 | 484 | plotinfo.xlines |
|
0 commit comments