diff --git a/src/components/legend/index.js b/src/components/legend/index.js index aad718ce53d..2fb6e7c4b03 100644 --- a/src/components/legend/index.js +++ b/src/components/legend/index.js @@ -12,6 +12,8 @@ var Plotly = require('../../plotly'); var d3 = require('d3'); +var styleOne = require('../../traces/pie/style_one'); + var legend = module.exports = {}; legend.layoutAttributes = require('./attributes'); @@ -233,7 +235,7 @@ legend.pie = function(d) { .attr('transform', 'translate(20,0)'); pts.exit().remove(); - if(pts.size()) pts.call(Plotly.Pie.styleOne, d[0], trace); + if(pts.size()) pts.call(styleOne, d[0], trace); }; legend.style = function(s) { diff --git a/src/index.js b/src/index.js index 922f578152b..22f621b601d 100644 --- a/src/index.js +++ b/src/index.js @@ -45,3 +45,20 @@ exports.Queue = Plotly.Queue; // export d3 used in the bundle exports.d3 = require('d3'); + +Plotly.register([ + require('./traces/bar'), + require('./traces/box'), + require('./traces/heatmap'), + require('./traces/histogram'), + require('./traces/histogram2d'), + require('./traces/histogram2dcontour'), + require('./traces/pie'), + require('./traces/contour'), + require('./traces/scatter3d'), + require('./traces/surface'), + require('./traces/mesh3d'), + require('./traces/scattergeo'), + require('./traces/choropleth'), + require('./traces/scattergl') +]); diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index 5c111503ebc..38b2f8ae51a 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -9,15 +9,28 @@ 'use strict'; -var Plotly = require('../plotly'); -var Events = require('../lib/events'); -var manageModeBar = require('../components/modebar/manage'); - var d3 = require('d3'); var m4FromQuat = require('gl-mat4/fromQuat'); var isNumeric = require('fast-isnumeric'); -var plots = Plotly.Plots; +var Plotly = require('../plotly'); +var Lib = require('../lib'); +var Events = require('../lib/events'); +var Queue = require('../lib/queue'); + +var Plots = require('../plots/plots'); +var Fx = require('../plots/cartesian/graph_interact'); + +var Pie = require('../traces/pie'); + +var Color = require('../components/color'); +var Drawing = require('../components/drawing'); +var ErrorBars = require('../components/errorbars'); +var Legend = require('../components/legend'); +var Shapes = require('../components/shapes'); +var Titles = require('../components/titles'); +var manageModeBar = require('../components/modebar/manage'); + /** * Main plot-creation function @@ -36,7 +49,7 @@ var plots = Plotly.Plots; * */ Plotly.plot = function(gd, data, layout, config) { - Plotly.Lib.markTime('in plot'); + Lib.markTime('in plot'); gd = getGraphDiv(gd); @@ -51,7 +64,7 @@ Plotly.plot = function(gd, data, layout, config) { // if there's no data or layout, and this isn't yet a plotly plot // container, log a warning to help plotly.js users debug - if(!data && !layout && !Plotly.Lib.isPlotDiv(gd)) { + if(!data && !layout && !Lib.isPlotDiv(gd)) { console.log('Warning: calling Plotly.plot as if redrawing ' + 'but this container doesn\'t yet have a plot.', gd); } @@ -69,7 +82,7 @@ Plotly.plot = function(gd, data, layout, config) { // off-screen getBoundingClientRect testing space, // in #js-plotly-tester (and stored as gd._tester) // so we can share cached text across tabs - Plotly.Drawing.makeTester(gd); + Drawing.makeTester(gd); // collect promises for any async actions during plotting // any part of the plotting code can push to gd._promises, then @@ -106,7 +119,7 @@ Plotly.plot = function(gd, data, layout, config) { gd._replotPending = false; } - plots.supplyDefaults(gd); + Plots.supplyDefaults(gd); // Polar plots if(data && data[0] && data[0].r) return plotPolar(gd, data, layout); @@ -164,32 +177,32 @@ Plotly.plot = function(gd, data, layout, config) { var calcdata = gd.calcdata; var i, cd, trace; - Plotly.Legend.draw(gd); + Legend.draw(gd); for (i = 0; i < calcdata.length; i++) { cd = calcdata[i]; trace = cd[0].trace; if (trace.visible !== true || !trace._module.colorbar) { - plots.autoMargin(gd, 'cb'+trace.uid); + Plots.autoMargin(gd, 'cb'+trace.uid); } else trace._module.colorbar(gd, cd); } - plots.doAutoMargin(gd); - return plots.previousPromises(gd); + Plots.doAutoMargin(gd); + return Plots.previousPromises(gd); } function marginPushersAgain() { // in case the margins changed, draw margin pushers again var seq = JSON.stringify(fullLayout._size)===oldmargins ? [] : [marginPushers, layoutStyles]; - return Plotly.Lib.syncOrAsync(seq.concat(Plotly.Fx.init),gd); + return Lib.syncOrAsync(seq.concat(Fx.init),gd); } function positionAndAutorange() { if(!recalc) return; - var subplots = plots.getSubplotIds(fullLayout, 'cartesian'), + var subplots = Plots.getSubplotIds(fullLayout, 'cartesian'), modules = gd._modules; // position and range calculations for traces that @@ -207,15 +220,15 @@ Plotly.plot = function(gd, data, layout, config) { } } - Plotly.Lib.markTime('done with bar/box adjustments'); + Lib.markTime('done with bar/box adjustments'); // calc and autorange for errorbars - Plotly.ErrorBars.calc(gd); - Plotly.Lib.markTime('done Plotly.ErrorBars.calc'); + ErrorBars.calc(gd); + Lib.markTime('done ErrorBars.calc'); // TODO: autosize extra for text markers - return Plotly.Lib.syncOrAsync([ - Plotly.Shapes.calcAutorange, + return Lib.syncOrAsync([ + Shapes.calcAutorange, Plotly.Annotations.calcAutorange, doAutoRange ], gd); @@ -236,11 +249,11 @@ Plotly.plot = function(gd, data, layout, config) { function drawData() { // Now plot the data var calcdata = gd.calcdata, - subplots = plots.getSubplotIds(fullLayout, 'cartesian'), + subplots = Plots.getSubplotIds(fullLayout, 'cartesian'), modules = gd._modules; var i, j, cd, trace, uid, subplot, subplotInfo, - cdSubplot, cdError, cdModule, module; + cdSubplot, cdError, cdModule, _module; function getCdSubplot(calcdata, subplot) { var cdSubplot = []; @@ -253,13 +266,13 @@ Plotly.plot = function(gd, data, layout, config) { return cdSubplot; } - function getCdModule(cdSubplot, module) { + function getCdModule(cdSubplot, _module) { var cdModule = []; var i, cd, trace; for (i = 0; i < cdSubplot.length; i++) { cd = cdSubplot[i]; trace = cd[0].trace; - if (trace._module===module && trace.visible===true) cdModule.push(cd); + if (trace._module === _module && trace.visible === true) cdModule.push(cd); } return cdModule; } @@ -267,7 +280,7 @@ Plotly.plot = function(gd, data, layout, config) { // clean up old scenes that no longer have associated data // will this be a performance hit? - var plotRegistry = plots.subplotsRegistry; + var plotRegistry = Plots.subplotsRegistry; // TODO incorporate cartesian and polar plots into this paradigm if(fullLayout._hasGL3D) plotRegistry.gl3d.plot(gd); @@ -298,56 +311,56 @@ Plotly.plot = function(gd, data, layout, config) { if(subplotInfo.plot) subplotInfo.plot.selectAll('g.trace').remove(); for(j = 0; j < modules.length; j++) { - module = modules[j]; - if(!module.plot) continue; + _module = modules[j]; + if(!_module.plot) continue; // plot all traces of this type on this subplot at once - cdModule = getCdModule(cdSubplot, module); - module.plot(gd, subplotInfo, cdModule); - Plotly.Lib.markTime('done ' + (cdModule[0] && cdModule[0][0].trace.type)); + cdModule = getCdModule(cdSubplot, _module); + _module.plot(gd, subplotInfo, cdModule); + Lib.markTime('done ' + (cdModule[0] && cdModule[0][0].trace.type)); // collect the traces that may have error bars - if(cdModule[0] && cdModule[0][0].trace && plots.traceIs(cdModule[0][0].trace, 'errorBarsOK')) { + if(cdModule[0] && cdModule[0][0].trace && Plots.traceIs(cdModule[0][0].trace, 'errorBarsOK')) { cdError = cdError.concat(cdModule); } } // finally do all error bars at once if(gd._fullLayout._hasCartesian) { - Plotly.ErrorBars.plot(gd, subplotInfo, cdError); - Plotly.Lib.markTime('done ErrorBars'); + ErrorBars.plot(gd, subplotInfo, cdError); + Lib.markTime('done ErrorBars'); } } // now draw stuff not on subplots (ie, pies) // TODO: gotta be a better way to handle this - var cdPie = getCdModule(calcdata, Plotly.Pie); - if(cdPie.length) Plotly.Pie.plot(gd, cdPie); + var cdPie = getCdModule(calcdata, Pie); + if(cdPie.length) Pie.plot(gd, cdPie); // styling separate from drawing - plots.style(gd); - Plotly.Lib.markTime('done plots.style'); + Plots.style(gd); + Lib.markTime('done Plots.style'); // show annotations and shapes - Plotly.Shapes.drawAll(gd); + Shapes.drawAll(gd); Plotly.Annotations.drawAll(gd); // source links - plots.addLinks(gd); + Plots.addLinks(gd); - return plots.previousPromises(gd); + return Plots.previousPromises(gd); } function cleanUp() { // now we're REALLY TRULY done plotting... // so mark it as done and let other procedures call a replot gd._replotting = false; - Plotly.Lib.markTime('done plot'); + Lib.markTime('done plot'); gd.emit('plotly_afterplot'); } - var donePlotting = Plotly.Lib.syncOrAsync([ - plots.previousPromises, + var donePlotting = Lib.syncOrAsync([ + Plots.previousPromises, marginPushers, layoutStyles, marginPushersAgain, @@ -390,7 +403,7 @@ function opaqueSetBackground(gd, bgColor) { } function setPlotContext(gd, config) { - if(!gd._context) gd._context = Plotly.Lib.extendFlat({}, Plotly.defaultConfig); + if(!gd._context) gd._context = Lib.extendFlat({}, Plotly.defaultConfig); var context = gd._context; if(config) { @@ -514,7 +527,7 @@ function plotPolar(gd, data, layout) { } gd._context.setBackground(gd, gd._fullLayout.paper_bgcolor); - plots.addLinks(gd); + Plots.addLinks(gd); return Promise.resolve(); } @@ -640,7 +653,7 @@ function cleanLayout(layout) { /* * Clean up Scene layouts */ - var sceneIds = plots.getSubplotIds(layout, 'gl3d'); + var sceneIds = Plots.getSubplotIds(layout, 'gl3d'); var scene, cameraposition, rotation, radius, center, mat, eye; for (i = 0; i < sceneIds.length; i++) { @@ -670,9 +683,9 @@ function cleanLayout(layout) { // sanitize rgb(fractions) and rgba(fractions) that old tinycolor // supported, but new tinycolor does not because they're not valid css - Plotly.Lib.markTime('finished rest of cleanLayout, starting color'); - Plotly.Color.clean(layout); - Plotly.Lib.markTime('finished cleanLayout color.clean'); + Lib.markTime('finished rest of cleanLayout, starting color'); + Color.clean(layout); + Lib.markTime('finished cleanLayout color.clean'); return layout; } @@ -703,10 +716,10 @@ function cleanData(data, existingData) { if (!('uid' in trace) || suids.indexOf(trace.uid) !== -1) { var newUid, i; for(i=0; i<100; i++) { - newUid = Plotly.Lib.randstr(uids); + newUid = Lib.randstr(uids); if(suids.indexOf(newUid)===-1) break; } - trace.uid = Plotly.Lib.randstr(uids); + trace.uid = Lib.randstr(uids); uids.push(trace.uid); } // keep track of already seen uids, so that if there are @@ -724,19 +737,19 @@ function cleanData(data, existingData) { // error_y.opacity is obsolete - merge into color if(trace.error_y && 'opacity' in trace.error_y) { - var dc = Plotly.Color.defaults, + var dc = Color.defaults, yeColor = trace.error_y.color || - (plots.traceIs(trace, 'bar') ? Plotly.Color.defaultLine : dc[tracei % dc.length]); - trace.error_y.color = Plotly.Color.addOpacity( - Plotly.Color.rgb(yeColor), - Plotly.Color.opacity(yeColor) * trace.error_y.opacity); + (Plots.traceIs(trace, 'bar') ? Color.defaultLine : dc[tracei % dc.length]); + trace.error_y.color = Color.addOpacity( + Color.rgb(yeColor), + Color.opacity(yeColor) * trace.error_y.opacity); delete trace.error_y.opacity; } // convert bardir to orientation, and put the data into // the axes it's eventually going to be used with if('bardir' in trace) { - if(trace.bardir==='h' && (plots.traceIs(trace, 'bar') || + if(trace.bardir==='h' && (Plots.traceIs(trace, 'bar') || trace.type.substr(0,9)==='histogram')) { trace.orientation = 'h'; swapXYData(trace); @@ -766,11 +779,11 @@ function cleanData(data, existingData) { if(trace.yaxis) trace.yaxis = Plotly.Axes.cleanId(trace.yaxis, 'y'); // scene ids scene1 -> scene - if(plots.traceIs(trace, 'gl3d') && trace.scene) { - trace.scene = plots.subplotsRegistry.gl3d.cleanId(trace.scene); + if(Plots.traceIs(trace, 'gl3d') && trace.scene) { + trace.scene = Plots.subplotsRegistry.gl3d.cleanId(trace.scene); } - if(!plots.traceIs(trace, 'pie')) { + if(!Plots.traceIs(trace, 'pie')) { if(Array.isArray(trace.textposition)) { trace.textposition = trace.textposition.map(cleanTextPosition); } @@ -788,9 +801,9 @@ function cleanData(data, existingData) { // sanitize rgb(fractions) and rgba(fractions) that old tinycolor // supported, but new tinycolor does not because they're not valid css - Plotly.Lib.markTime('finished rest of cleanData, starting color'); - Plotly.Color.clean(trace); - Plotly.Lib.markTime('finished cleanData color.clean'); + Lib.markTime('finished rest of cleanData, starting color'); + Color.clean(trace); + Lib.markTime('finished cleanData color.clean'); } } @@ -818,7 +831,7 @@ function emptyContainer(outer, innerStr) { Plotly.redraw = function(gd) { gd = getGraphDiv(gd); - if(!Plotly.Lib.isPlotDiv(gd)) { + if(!Lib.isPlotDiv(gd)) { console.log('This element is not a Plotly Plot', gd); return; } @@ -840,7 +853,7 @@ Plotly.redraw = function(gd) { */ Plotly.newPlot = function(gd, data, layout, config) { gd = getGraphDiv(gd); - plots.purge(gd); + Plots.purge(gd); return Plotly.plot(gd, data, layout, config); }; @@ -894,7 +907,7 @@ function doCalcdata(gd) { if (!cd[0].t) cd[0].t = {}; cd[0].trace = trace; - Plotly.Lib.markTime('done with calcdata for '+i); + Lib.markTime('done with calcdata for '+i); calcdata[i] = cd; } } @@ -1050,12 +1063,12 @@ function checkAddTracesArgs(gd, traces, newIndices) { */ function assertExtendTracesArgs(gd, update, indices, maxPoints) { - var maxPointsIsObject = Plotly.Lib.isPlainObject(maxPoints); + var maxPointsIsObject = Lib.isPlainObject(maxPoints); if (!Array.isArray(gd.data)) { throw new Error('gd.data must be an array'); } - if (!Plotly.Lib.isPlainObject(update)) { + if (!Lib.isPlainObject(update)) { throw new Error('update must be a key:value object'); } @@ -1098,7 +1111,7 @@ function assertExtendTracesArgs(gd, update, indices, maxPoints) { */ function getExtendProperties(gd, update, indices, maxPoints) { - var maxPointsIsObject = Plotly.Lib.isPlainObject(maxPoints), + var maxPointsIsObject = Lib.isPlainObject(maxPoints), updateProps = []; var trace, target, prop, insert, maxp; @@ -1118,7 +1131,7 @@ function getExtendProperties(gd, update, indices, maxPoints) { * instance that references the key and value for this particular trace. */ trace = gd.data[indices[j]]; - prop = Plotly.Lib.nestedProperty(trace, key); + prop = Lib.nestedProperty(trace, key); /* * Target is the existing gd.data.trace.dataArray value like "x" or "marker.size" @@ -1265,8 +1278,8 @@ Plotly.extendTraces = function extendTraces(gd, update, indices, maxPoints) { var promise = Plotly.redraw(gd); var undoArgs = [gd, undo.update, indices, undo.maxPoints]; - if (Plotly.Queue) { - Plotly.Queue.add(gd, Plotly.prependTraces, undoArgs, extendTraces, arguments); + if (Queue) { + Queue.add(gd, Plotly.prependTraces, undoArgs, extendTraces, arguments); } return promise; @@ -1294,8 +1307,8 @@ Plotly.prependTraces = function prependTraces(gd, update, indices, maxPoints) { var promise = Plotly.redraw(gd); var undoArgs = [gd, undo.update, indices, undo.maxPoints]; - if (Plotly.Queue) { - Plotly.Queue.add(gd, Plotly.extendTraces, undoArgs, prependTraces, arguments); + if (Queue) { + Queue.add(gd, Plotly.extendTraces, undoArgs, prependTraces, arguments); } return promise; @@ -1344,7 +1357,7 @@ Plotly.addTraces = function addTraces(gd, traces, newIndices) { // i.e., we can simply redraw and be done if (typeof newIndices === 'undefined') { promise = Plotly.redraw(gd); - if (Plotly.Queue) Plotly.Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs); + if (Queue) Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs); return promise; } @@ -1367,11 +1380,10 @@ Plotly.addTraces = function addTraces(gd, traces, newIndices) { // if we're here, the user has defined specific places to place the new traces // this requires some extra work that moveTraces will do - if (Plotly.Queue) Plotly.Queue.startSequence(gd); - if (Plotly.Queue) Plotly.Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs); - + if (Queue) Queue.startSequence(gd); + if (Queue) Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs); promise = Plotly.moveTraces(gd, currentIndices, newIndices); - if (Plotly.Queue) Plotly.Queue.stopSequence(gd); + if (Queue) Queue.stopSequence(gd); return promise; }; @@ -1413,7 +1425,7 @@ Plotly.deleteTraces = function deleteTraces(gd, indices) { var promise = Plotly.redraw(gd); - if (Plotly.Queue) Plotly.Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs); + if (Queue) Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs); return promise; }; @@ -1512,7 +1524,7 @@ Plotly.moveTraces = function moveTraces(gd, currentIndices, newIndices) { var promise = Plotly.redraw(gd); - if (Plotly.Queue) Plotly.Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs); + if (Queue) Queue.add(gd, undoFunc, undoArgs, redoFunc, redoArgs); return promise; }; @@ -1547,7 +1559,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) { aobj = {}; if(typeof astr === 'string') aobj[astr] = val; - else if(Plotly.Lib.isPlainObject(astr)) { + else if(Lib.isPlainObject(astr)) { aobj = astr; if(traces===undefined) traces = val; // the 3-arg form } @@ -1599,7 +1611,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) { 'tilt', 'tiltaxis', 'depth', 'direction', 'rotation', 'pull' ]; for(i = 0; i < traces.length; i++) { - if(plots.traceIs(gd._fullData[traces[i]], 'box')) { + if(Plots.traceIs(gd._fullData[traces[i]], 'box')) { recalcAttrs.push('name'); break; } @@ -1685,9 +1697,9 @@ Plotly.restyle = function restyle(gd, astr, val, traces) { var extraparam; if(attr.substr(0, 6) === 'LAYOUT') { - extraparam = Plotly.Lib.nestedProperty(gd.layout, attr.replace('LAYOUT', '')); + extraparam = Lib.nestedProperty(gd.layout, attr.replace('LAYOUT', '')); } else { - extraparam = Plotly.Lib.nestedProperty(gd.data[traces[i]], attr); + extraparam = Lib.nestedProperty(gd.data[traces[i]], attr); } if(!(attr in undoit)) { @@ -1717,7 +1729,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) { redoit[ai] = vi; if(ai.substr(0,6)==='LAYOUT'){ - param = Plotly.Lib.nestedProperty(gd.layout, ai.replace('LAYOUT', '')); + param = Lib.nestedProperty(gd.layout, ai.replace('LAYOUT', '')); undoit[ai] = [param.get()]; // since we're allowing val to be an array, allow it here too, // even though that's meaningless @@ -1733,7 +1745,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) { for(i=0; i1 && - Plotly.Lib.containsAny(p.parts[1], ['tick', 'exponent', 'grid', 'zeroline'])) { + Lib.containsAny(p.parts[1], ['tick', 'exponent', 'grid', 'zeroline'])) { doticks = true; } else if(ai.indexOf('.linewidth')!==-1 && @@ -2331,8 +2344,8 @@ Plotly.relayout = function relayout(gd, astr, val) { } // now all attribute mods are done, as are // redo and undo so we can save them - if(Plotly.Queue) { - Plotly.Queue.add(gd, relayout, [gd, undoit], relayout, [gd, redoit]); + if(Queue) { + Queue.add(gd, relayout, [gd, undoit], relayout, [gd, redoit]); } // calculate autosizing - if size hasn't changed, @@ -2344,7 +2357,7 @@ Plotly.relayout = function relayout(gd, astr, val) { // redraw // first check if there's still anything to do var ak = Object.keys(aobj), - seq = [plots.previousPromises]; + seq = [Plots.previousPromises]; if(doplot || docalc) { seq.push(function layoutReplot() { @@ -2358,13 +2371,13 @@ Plotly.relayout = function relayout(gd, astr, val) { } else if(ak.length) { // if we didn't need to redraw entirely, just do the needed parts - plots.supplyDefaults(gd); + Plots.supplyDefaults(gd); fullLayout = gd._fullLayout; if(dolegend) { seq.push(function doLegend() { - Plotly.Legend.draw(gd); - return plots.previousPromises(gd); + Legend.draw(gd); + return Plots.previousPromises(gd); }); } @@ -2373,8 +2386,8 @@ Plotly.relayout = function relayout(gd, astr, val) { if(doticks) { seq.push(function() { Plotly.Axes.doTicks(gd,'redraw'); - Plotly.Titles.draw(gd, 'gtitle'); - return plots.previousPromises(gd); + Titles.draw(gd, 'gtitle'); + return Plots.previousPromises(gd); }); } @@ -2383,13 +2396,13 @@ Plotly.relayout = function relayout(gd, astr, val) { manageModeBar(gd); var subplotIds; - subplotIds = plots.getSubplotIds(fullLayout, 'gl3d'); + subplotIds = Plots.getSubplotIds(fullLayout, 'gl3d'); for(i = 0; i < subplotIds.length; i++) { scene = fullLayout[subplotIds[i]]._scene; scene.handleDragmode(fullLayout.dragmode); } - subplotIds = plots.getSubplotIds(fullLayout, 'gl2d'); + subplotIds = Plots.getSubplotIds(fullLayout, 'gl2d'); for(i = 0; i < subplotIds.length; i++) { scene = fullLayout._plots[subplotIds[i]]._scene2d; scene.updateFx(fullLayout); @@ -2397,12 +2410,12 @@ Plotly.relayout = function relayout(gd, astr, val) { } } - var plotDone = Plotly.Lib.syncOrAsync(seq, gd); + var plotDone = Lib.syncOrAsync(seq, gd); if(!plotDone || !plotDone.then) plotDone = Promise.resolve(gd); return plotDone.then(function() { - gd.emit('plotly_relayout', Plotly.Lib.extendDeep({}, redoit)); + gd.emit('plotly_relayout', Lib.extendDeep({}, redoit)); return gd; }); }; @@ -2482,7 +2495,7 @@ function plotAutoSize(gd, aobj) { fullLayout.autosize = gd.layout.autosize = true; } - plots.sanitizeMargins(fullLayout); + Plots.sanitizeMargins(fullLayout); return aobj; } @@ -2495,7 +2508,7 @@ function makePlotFramework(gd) { fullLayout = gd._fullLayout; // TODO - find a better place for 3D to initialize axes - if(fullLayout._hasGL3D) plots.subplotsRegistry.gl3d.initAxes(gd); + if(fullLayout._hasGL3D) Plots.subplotsRegistry.gl3d.initAxes(gd); // Plot container fullLayout._container = gd3.selectAll('.plot-container').data([0]); @@ -2544,7 +2557,7 @@ function makePlotFramework(gd) { d3.selectAll('defs').each(function() { if(this.id) otherUids.push(this.id.split('-')[1]); }); - fullLayout._uid = Plotly.Lib.randstr(otherUids); + fullLayout._uid = Lib.randstr(otherUids); } fullLayout._paperdiv.selectAll('.main-svg') @@ -2584,10 +2597,10 @@ function makePlotFramework(gd) { gd.emit('plotly_framework'); // position and style the containers, make main title - var frameWorkDone = Plotly.Lib.syncOrAsync([ + var frameWorkDone = Lib.syncOrAsync([ layoutStyles, function goAxes() { return Plotly.Axes.doTicks(gd,'redraw'); }, - Plotly.Fx.init + Fx.init ], gd); if(frameWorkDone && frameWorkDone.then) { @@ -2719,7 +2732,7 @@ function makeCartesianPlotFramwork(gd, subplots) { // now make the components of overlaid subplots // overlays don't have backgrounds, and append all // their other components to the corresponding - // extra groups of their main plots. + // extra groups of their main Plots. overlays.forEach(function(plotinfo) { var mainplot = fullLayout._plots[plotinfo.mainplot]; mainplot.overlays.push(plotinfo); @@ -2751,7 +2764,7 @@ function makeCartesianPlotFramwork(gd, subplots) { // layoutStyles: styling for plot layout elements function layoutStyles(gd) { - return Plotly.Lib.syncOrAsync([plots.doAutoMargin, lsInner], gd); + return Lib.syncOrAsync([Plots.doAutoMargin, lsInner], gd); } function lsInner(gd) { @@ -2769,7 +2782,7 @@ function lsInner(gd) { height: fullLayout.height + 'px' }) .selectAll('.main-svg') - .call(Plotly.Drawing.setSize, fullLayout.width, fullLayout.height); + .call(Drawing.setSize, fullLayout.width, fullLayout.height); gd._context.setBackground(gd, fullLayout.paper_bgcolor); @@ -2783,17 +2796,17 @@ function lsInner(gd) { if(plotinfo.bg) { plotinfo.bg - .call(Plotly.Drawing.setRect, + .call(Drawing.setRect, xa._offset-gs.p, ya._offset-gs.p, xa._length+2*gs.p, ya._length+2*gs.p) - .call(Plotly.Color.fill, fullLayout.plot_bgcolor); + .call(Color.fill, fullLayout.plot_bgcolor); } plotinfo.plot - .call(Plotly.Drawing.setRect, + .call(Drawing.setRect, xa._offset, ya._offset, xa._length, ya._length); - var xlw = Plotly.Drawing.crispRound(gd, xa.linewidth, 1), - ylw = Plotly.Drawing.crispRound(gd, ya.linewidth, 1), + var xlw = Drawing.crispRound(gd, xa.linewidth, 1), + ylw = Drawing.crispRound(gd, ya.linewidth, 1), xp = gs.p+ylw, xpathPrefix = 'M'+(-xp)+',', xpathSuffix = 'h'+(xa._length+2*xp), @@ -2888,7 +2901,7 @@ function lsInner(gd) { // so it doesn't barf with no lines shown 'M0,0') .style('stroke-width',xlw+'px') - .call(Plotly.Color.stroke, xa.showline ? + .call(Color.stroke, xa.showline ? xa.linecolor : 'rgba(0,0,0,0)'); plotinfo.ylines .attr('transform', originy) @@ -2898,7 +2911,7 @@ function lsInner(gd) { (showfreey ? ('M'+freeposy+ypathSuffix) : '')) || 'M0,0') .attr('stroke-width',ylw+'px') - .call(Plotly.Color.stroke,ya.showline ? + .call(Color.stroke,ya.showline ? ya.linecolor : 'rgba(0,0,0,0)'); plotinfo.xaxislayer.attr('transform',originx); @@ -2914,7 +2927,7 @@ function lsInner(gd) { Plotly.Axes.makeClipPaths(gd); - Plotly.Titles.draw(gd, 'gtitle'); + Titles.draw(gd, 'gtitle'); manageModeBar(gd); diff --git a/src/plotly.js b/src/plotly.js index 975565e0df9..b7834839b4a 100644 --- a/src/plotly.js +++ b/src/plotly.js @@ -39,9 +39,6 @@ var Plots = exports.Plots = require('./plots/plots'); var Cartesian = require('./plots/cartesian'); Plots.registerSubplot(Cartesian); -exports.Axes = require('./plots/cartesian/axes'); -exports.Fx = require('./plots/cartesian/graph_interact'); - var Geo = require('./plots/geo'); Plots.registerSubplot(Geo); @@ -51,8 +48,11 @@ Plots.registerSubplot(Gl3d); var Gl2d = require('./plots/gl2d'); Plots.registerSubplot(Gl2d); +exports.Axes = require('./plots/cartesian/axes'); +exports.Fx = require('./plots/cartesian/graph_interact'); exports.micropolar = require('./plots/polar/micropolar'); + // components exports.Color = require('./components/color'); exports.Drawing = require('./components/drawing'); @@ -65,22 +65,30 @@ exports.Titles = require('./components/titles'); exports.Legend = require('./components/legend'); exports.ModeBar = require('./components/modebar'); -// traces -exports.Scatter = require('./traces/scatter'); -exports.Bar = require('./traces/bar'); -exports.Box = require('./traces/box'); -exports.Heatmap = require('./traces/heatmap'); -exports.Histogram = require('./traces/histogram'); -exports.Histogram2d = require('./traces/histogram2d'); -exports.Histogram2dContour = require('./traces/histogram2dcontour'); -exports.Pie = require('./traces/pie'); -exports.Contour = require('./traces/contour'); -exports.Scatter3D = require('./traces/scatter3d'); -exports.Surface = require('./traces/surface'); -exports.Mesh3D = require('./traces/mesh3d'); -exports.ScatterGeo = require('./traces/scattergeo'); -exports.Choropleth = require('./traces/choropleth'); -exports.ScatterGl = require('./traces/scattergl'); +exports.register = function register(_modules) { + if(!_modules){ + throw new Error('No argument passed to Plotly.register.'); + } else if(_modules && !Array.isArray(_modules)){ + _modules = [_modules]; + } + + + for(var i = 0; i < _modules.length; i++){ + var newModule = _modules[i]; + + if(newModule && newModule.moduleType !== 'trace'){ + throw new Error('Invalid module was attempted to be registered!'); + } else { + Plots.register(newModule, newModule.name, newModule.categories, newModule.meta); + } + } +}; + + +exports.register(require('./traces/scatter')); + +// Scatter is the only trace included by default +exports.Scatter = Plots.getModule('scatter'); // plot api require('./plot_api/plot_api'); diff --git a/src/plots/geo/geo.js b/src/plots/geo/geo.js index a3142060f6a..7bd6ed0aa35 100644 --- a/src/plots/geo/geo.js +++ b/src/plots/geo/geo.js @@ -14,14 +14,13 @@ var Plotly = require('../../plotly'); var d3 = require('d3'); +var Plots = require('../../plots/plots'); + var addProjectionsToD3 = require('./projections'); var createGeoScale = require('./set_scale'); var createGeoZoom = require('./zoom'); var createGeoZoomReset = require('./zoom_reset'); -var plotScatterGeo = require('../../traces/scattergeo/plot'); -var plotChoropleth = require('../../traces/choropleth/plot'); - var constants = require('../../constants/geo_constants'); var topojsonUtils = require('../../lib/topojson_utils'); var topojsonFeature = require('topojson').feature; @@ -136,21 +135,22 @@ proto.plot = function(geoData, fullLayout, promises) { }; proto.onceTopojsonIsLoaded = function(geoData, geoLayout) { - var scattergeoData = [], - choroplethData = []; + var traceData = {}; this.drawLayout(geoLayout); for(var i = 0; i < geoData.length; i++) { var trace = geoData[i]; - var traceType = trace.type; - if(traceType === 'scattergeo') scattergeoData.push(trace); - else if(traceType === 'choropleth') choroplethData.push(trace); + traceData[trace.type] = traceData[trace.type] || []; + traceData[trace.type].push(trace); } - if(scattergeoData.length>0) plotScatterGeo.plot(this, scattergeoData); - if(choroplethData.length>0) plotChoropleth.plot(this, choroplethData, geoLayout); + var traceKeys = Object.keys(traceData); + for(var j = 0; j < traceKeys.length; j++){ + var traceKey = traceKeys[j]; + Plots.getModule(traceKey).plot(this, traceData[traceKey], geoLayout); + } this.render(); }; diff --git a/src/plots/geo/zoom_reset.js b/src/plots/geo/zoom_reset.js index 1314b1b675b..612267bfeba 100644 --- a/src/plots/geo/zoom_reset.js +++ b/src/plots/geo/zoom_reset.js @@ -9,8 +9,7 @@ 'use strict'; -var loneUnhover = require('../../plotly').Fx.loneUnhover; - +var Fx = require('../cartesian/graph_interact'); function createGeoZoomReset(geo, geoLayout) { var projection = geo.projection, @@ -23,7 +22,7 @@ function createGeoZoomReset(geo, geoLayout) { zoom.scale(projection.scale()); zoom.translate(projection.translate()); - loneUnhover(geo.hoverContainer); + Fx.loneUnhover(geo.hoverContainer); geo.render(); }; diff --git a/src/plots/gl2d/scene2d.js b/src/plots/gl2d/scene2d.js index 7c69ae39dd1..37440e9d8e6 100644 --- a/src/plots/gl2d/scene2d.js +++ b/src/plots/gl2d/scene2d.js @@ -9,7 +9,10 @@ 'use strict'; -var Plotly = require('../../plotly'); +var Plots = require('../../plots/plots'); +var Axes = require('../../plots/cartesian/axes'); +var Fx = require('../../plots/cartesian/graph_interact'); + var createPlot2D = require('gl-plot2d'); var createSpikes = require('gl-spikes2d'); var createSelectBox = require('gl-select-box'); @@ -17,8 +20,6 @@ var createSelectBox = require('gl-select-box'); var createOptions = require('./convert'); var createCamera = require('./camera'); -var createLineWithMarkers = require('../../traces/scattergl/convert'); - var htmlToUnicode = require('../../lib/html2unicode'); var showNoWebGlMsg = require('../../lib/show_no_webgl_msg'); @@ -223,8 +224,8 @@ proto.computeTickMarks = function() { this.glplot.viewBox[3] - this.glplot.viewBox[1]; var nextTicks = [ - Plotly.Axes.calcTicks(this.xaxis), - Plotly.Axes.calcTicks(this.yaxis) + Axes.calcTicks(this.xaxis), + Axes.calcTicks(this.yaxis) ]; for(var j = 0; j < 2; ++j) { @@ -254,7 +255,7 @@ function compareTicks(a, b) { } proto.updateAxes = function(options) { - var spmatch = Plotly.Axes.subplotMatch, + var spmatch = Axes.subplotMatch, xaxisName = 'xaxis' + this.id.match(spmatch)[1], yaxisName = 'yaxis' + this.id.match(spmatch)[2]; @@ -325,11 +326,8 @@ proto.plot = function(fullData, fullLayout) { if(trace) trace.update(traceData); else { - switch(traceData.type) { - case 'scattergl': - trace = createLineWithMarkers(this, traceData); - break; - } + var traceModule = Plots.getModule(traceData.type); + trace = traceModule.plot(this, traceData); } this.traces[traceData.uid] = trace; } @@ -392,7 +390,7 @@ proto.plot = function(fullData, fullLayout) { ax = this[AXES[i]]; ax._length = options.viewBox[i+2] - options.viewBox[i]; - Plotly.Axes.doAutoRange(ax); + Axes.doAutoRange(ax); } options.ticks = this.computeTickMarks(); @@ -475,7 +473,7 @@ proto.draw = function() { if(parts.indexOf('name') === -1) selection.name = undefined; } - Plotly.Fx.loneHover({ + Fx.loneHover({ x: selection.screenCoord[0], y: selection.screenCoord[1], xLabel: this.hoverFormatter('xaxis', selection.traceCoord[0]), @@ -493,7 +491,7 @@ proto.draw = function() { else if(!result && this.lastPickResult) { this.spikes.update({}); this.lastPickResult = null; - Plotly.Fx.loneUnhover(this.svgContainer); + Fx.loneUnhover(this.svgContainer); } } @@ -504,5 +502,5 @@ proto.hoverFormatter = function(axisName, val) { if(val === undefined) return undefined; var axis = this[axisName]; - return Plotly.Axes.tickText(axis, axis.c2l(val), 'hover').text; + return Axes.tickText(axis, axis.c2l(val), 'hover').text; }; diff --git a/src/plots/gl3d/index.js b/src/plots/gl3d/index.js index 68f15f0177a..d7daba44104 100644 --- a/src/plots/gl3d/index.js +++ b/src/plots/gl3d/index.js @@ -9,11 +9,9 @@ 'use strict'; -var Plotly = require('../../plotly'); - var Scene = require('./scene'); +var Plots = require('../plots'); -var plots = Plotly.Plots; var axesNames = ['xaxis', 'yaxis', 'zaxis']; @@ -32,7 +30,7 @@ exports.supplyLayoutDefaults = require('./layout/defaults'); exports.plot = function plotGl3d(gd) { var fullLayout = gd._fullLayout, fullData = gd._fullData, - sceneIds = plots.getSubplotIds(fullLayout, 'gl3d'); + sceneIds = Plots.getSubplotIds(fullLayout, 'gl3d'); fullLayout._paperdiv.style({ width: fullLayout.width + 'px', @@ -43,7 +41,7 @@ exports.plot = function plotGl3d(gd) { for(var i = 0; i < sceneIds.length; i++) { var sceneId = sceneIds[i], - fullSceneData = plots.getSubplotData(fullData, 'gl3d', sceneId), + fullSceneData = Plots.getSubplotData(fullData, 'gl3d', sceneId), scene = fullLayout[sceneId]._scene; // ref. to corresp. Scene instance // If Scene is not instantiated, create one! @@ -83,7 +81,7 @@ exports.initAxes = function(gd) { delete fullLayout.xaxis; delete fullLayout.yaxis; - var sceneIds = Plotly.Plots.getSubplotIds(fullLayout, 'gl3d'); + var sceneIds = Plots.getSubplotIds(fullLayout, 'gl3d'); for(var i = 0; i < sceneIds.length; ++i) { var sceneId = sceneIds[i]; diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index 07903635a86..db742d5bb0b 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -12,12 +12,14 @@ 'use strict'; -var Plotly = require('../../plotly'); var createPlot = require('gl-plot3d'); -var createScatterTrace = require('../../traces/scatter3d/convert'); -var createSurfaceTrace = require('../../traces/surface/convert'); -var createMeshTrace = require('../../traces/mesh3d/convert'); +var Lib = require('../../lib'); + +var Plots = require('../../plots/plots'); +var Axes = require('../../plots/cartesian/axes'); +var Fx = require('../../plots/cartesian/graph_interact'); + var str2RGBAarray = require('../../lib/str2rgbarray'); var showNoWebGlMsg = require('../../lib/show_no_webgl_msg'); @@ -30,7 +32,6 @@ var computeTickMarks = require('./layout/tick_marks'); var STATIC_CANVAS, STATIC_CONTEXT; - function render(scene) { //Update size of svg container @@ -62,7 +63,7 @@ function render(scene) { if(typeof val === 'string') return val; var axis = scene.fullSceneLayout[axisName]; - return Plotly.Axes.tickText(axis, axis.c2l(val), 'hover').text; + return Axes.tickText(axis, axis.c2l(val), 'hover').text; } if(lastPicked !== null) { @@ -78,7 +79,7 @@ function render(scene) { if(hoverinfoParts.indexOf('name') === -1) lastPicked.name = undefined; } - Plotly.Fx.loneHover({ + Fx.loneHover({ x: (0.5 + 0.5 * pdata[0]/pdata[3]) * width, y: (0.5 - 0.5 * pdata[1]/pdata[3]) * height, xLabel: formatter('xaxis', selection.traceCoordinate[0]), @@ -91,7 +92,7 @@ function render(scene) { container: svgContainer }); } - else Plotly.Fx.loneUnhover(svgContainer); + else Fx.loneUnhover(svgContainer); } function initializeGLPlot(scene, fullLayout, canvas, gl) { @@ -351,21 +352,8 @@ proto.plot = function(sceneData, fullLayout, layout) { if(trace) { trace.update(data); } else { - switch(data.type) { - case 'scatter3d': - trace = createScatterTrace(this, data); - break; - - case 'surface': - trace = createSurfaceTrace(this, data); - break; - - case 'mesh3d': - trace = createMeshTrace(this, data); - break; - - default: - } + var traceModule = Plots.getModule(data.type); + trace = traceModule.plot(this, data); this.traces[data.uid] = trace; } trace.name = data.name; @@ -569,7 +557,7 @@ proto.setCamera = function setCamera(cameraData) { // save camera to user layout (i.e. gd.layout) proto.saveCamera = function saveCamera(layout) { var cameraData = this.getCamera(), - cameraNestedProp = Plotly.Lib.nestedProperty(layout, this.id + '.camera'), + cameraNestedProp = Lib.nestedProperty(layout, this.id + '.camera'), cameraDataLastSave = cameraNestedProp.get(), hasChanged = false; diff --git a/src/plots/plots.js b/src/plots/plots.js index 0bdee8c6328..915b4706030 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -13,6 +13,8 @@ var Plotly = require('../plotly'); var d3 = require('d3'); var isNumeric = require('fast-isnumeric'); +var Lib = require('../lib'); + var plots = module.exports = {}; var modules = plots.modules = {}, @@ -39,7 +41,8 @@ plots.fontWeight = 'normal'; */ plots.register = function(_module, thisType, categoriesIn, meta) { if(modules[thisType]) { - throw new Error('type ' + thisType + ' already registered'); + console.warn('type ' + thisType + ' already registered'); + return; } var categoryObj = {}; @@ -269,7 +272,7 @@ plots.resize = function(gd) { }; -// for use in Plotly.Lib.syncOrAsync, check if there are any +// for use in Lib.syncOrAsync, check if there are any // pending promises in this plot and wait for them plots.previousPromises = function(gd) { if((gd._promises || []).length) { @@ -416,7 +419,7 @@ plots.supplyDefaults = function(gd) { newData = gd.data || [], modules = gd._modules = []; - var i, trace, fullTrace, module, axList, ax; + var i, trace, fullTrace, _module, axList, ax; // first fill in what we can of layout without looking at data @@ -441,14 +444,14 @@ plots.supplyDefaults = function(gd) { else if(plots.traceIs(fullTrace, 'gl2d')) newFullLayout._hasGL2D = true; else if('r' in fullTrace) newFullLayout._hasPolar = true; - module = fullTrace._module; - if (module && modules.indexOf(module)===-1) modules.push(module); + _module = fullTrace._module; + if (_module && modules.indexOf(_module)===-1) modules.push(_module); } // special cases that introduce interactions between traces for (i = 0; i < modules.length; i++) { - module = modules[i]; - if (module.cleanData) module.cleanData(newFullData); + _module = modules[i]; + if (_module.cleanData) _module.cleanData(newFullData); } if (oldFullData.length === newData.length) { @@ -524,7 +527,7 @@ function relinkPrivateKeys(toLayout, fromLayout) { else if (Array.isArray(fromLayout[k]) && Array.isArray(toLayout[k]) && fromLayout[k].length && - Plotly.Lib.isPlainObject(fromLayout[k][0])) { + Lib.isPlainObject(fromLayout[k][0])) { if(fromLayout[k].length !== toLayout[k].length) { // this should be handled elsewhere, it causes // ambiguity if we try to deal with it here. @@ -536,8 +539,8 @@ function relinkPrivateKeys(toLayout, fromLayout) { relinkPrivateKeys(toLayout[k][j], fromLayout[k][j]); } } - else if (Plotly.Lib.isPlainObject(fromLayout[k]) && - Plotly.Lib.isPlainObject(toLayout[k])) { + else if (Lib.isPlainObject(fromLayout[k]) && + Lib.isPlainObject(toLayout[k])) { // recurse into objects, but only if they still exist relinkPrivateKeys(toLayout[k], fromLayout[k]); if (!Object.keys(toLayout[k]).length) delete toLayout[k]; @@ -550,12 +553,12 @@ plots.supplyDataDefaults = function(traceIn, i, layout) { defaultColor = Plotly.Color.defaults[i % Plotly.Color.defaults.length]; function coerce(attr, dflt) { - return Plotly.Lib.coerce(traceIn, traceOut, plots.attributes, attr, dflt); + return Lib.coerce(traceIn, traceOut, plots.attributes, attr, dflt); } function coerceSubplotAttr(subplotType, subplotAttr) { if(!plots.traceIs(traceOut, subplotType)) return; - return Plotly.Lib.coerce(traceIn, traceOut, + return Lib.coerce(traceIn, traceOut, plots.subplotsRegistry[subplotType].attributes, subplotAttr); } @@ -563,7 +566,7 @@ plots.supplyDataDefaults = function(traceIn, i, layout) { traceOut.index = i; var visible = coerce('visible'), scene, - module; + _module; coerce('type'); coerce('uid'); @@ -577,14 +580,14 @@ plots.supplyDataDefaults = function(traceIn, i, layout) { // module-specific attributes --- note: we need to send a trace into // the 3D modules to have it removed from the webgl context. if(visible || scene) { - module = plots.getModule(traceOut); - traceOut._module = module; + _module = plots.getModule(traceOut); + traceOut._module = _module; } // gets overwritten in pie and geo if(visible) coerce('hoverinfo', (layout._dataLength === 1) ? 'x+y+z+text' : undefined); - if(module && visible) module.supplyDefaults(traceIn, traceOut, defaultColor, layout); + if(_module && visible) _module.supplyDefaults(traceIn, traceOut, defaultColor, layout); if(visible) { coerce('name', 'trace ' + i); @@ -615,14 +618,14 @@ plots.supplyDataDefaults = function(traceIn, i, layout) { plots.supplyLayoutGlobalDefaults = function(layoutIn, layoutOut) { function coerce(attr, dflt) { - return Plotly.Lib.coerce(layoutIn, layoutOut, plots.layoutAttributes, attr, dflt); + return Lib.coerce(layoutIn, layoutOut, plots.layoutAttributes, attr, dflt); } - var globalFont = Plotly.Lib.coerceFont(coerce, 'font'); + var globalFont = Lib.coerceFont(coerce, 'font'); coerce('title'); - Plotly.Lib.coerceFont(coerce, 'titlefont', { + Lib.coerceFont(coerce, 'titlefont', { family: globalFont.family, size: Math.round(globalFont.size * 1.4), color: globalFont.color @@ -928,7 +931,7 @@ plots.graphJson = function(gd, dataonly, mode, output, useDefaults){ if(typeof d === 'function') { return null; } - if(Plotly.Lib.isPlainObject(d)) { + if(Lib.isPlainObject(d)) { var o={}, v, src; for(v in d) { // remove private elements and functions @@ -951,7 +954,7 @@ plots.graphJson = function(gd, dataonly, mode, output, useDefaults){ // in a trace, we will keep the data array. src = d[v+'src']; if(typeof src==='string' && src.indexOf(':')>0) { - if(!Plotly.Lib.isPlainObject(d.stream)) { + if(!Lib.isPlainObject(d.stream)) { continue; } } @@ -978,7 +981,7 @@ plots.graphJson = function(gd, dataonly, mode, output, useDefaults){ // convert native dates to date strings... // mostly for external users exporting to plotly if(d && d.getTime) { - return Plotly.Lib.ms2DateTime(d); + return Lib.ms2DateTime(d); } return d; diff --git a/src/traces/bar/index.js b/src/traces/bar/index.js index 3814fa265dd..ec24b7ec76b 100644 --- a/src/traces/bar/index.js +++ b/src/traces/bar/index.js @@ -9,38 +9,30 @@ 'use strict'; -var Plotly = require('../../plotly'); - -Plotly.Plots.register(exports, 'bar', - ['cartesian', 'bar', 'oriented', 'markerColorscale', 'errorBarsOK', 'showLegend'], { - description: [ - 'The data visualized by the span of the bars is set in `y`', - 'if `orientation` is set th *v* (the default)', - 'and the labels are set in `x`.', - - 'By setting `orientation` to *h*, the roles are interchanged.' - ].join(' ') - } -); - -exports.attributes = require('./attributes'); - -exports.layoutAttributes = require('./layout_attributes'); - -exports.supplyDefaults = require('./defaults'); - -exports.supplyLayoutDefaults = require('./layout_defaults'); - -exports.calc = require('./calc'); - -exports.setPositions = require('./set_positions'); - -exports.colorbar = require('../scatter/colorbar'); - -exports.arraysToCalcdata = require('./arrays_to_calcdata'); - -exports.plot = require('./plot'); - -exports.style = require('./style'); - -exports.hoverPoints = require('./hover'); +var Bar = {}; + +Bar.attributes = require('./attributes'); +Bar.layoutAttributes = require('./layout_attributes'); +Bar.supplyDefaults = require('./defaults'); +Bar.supplyLayoutDefaults = require('./layout_defaults'); +Bar.calc = require('./calc'); +Bar.setPositions = require('./set_positions'); +Bar.colorbar = require('../scatter/colorbar'); +Bar.arraysToCalcdata = require('./arrays_to_calcdata'); +Bar.plot = require('./plot'); +Bar.style = require('./style'); +Bar.hoverPoints = require('./hover'); + +Bar.moduleType = 'trace'; +Bar.name = 'bar'; +Bar.categories = ['cartesian', 'bar', 'oriented', 'markerColorscale', 'errorBarsOK', 'showLegend']; +Bar.meta = { + description: [ + 'The data visualized by the span of the bars is set in `y`', + 'if `orientation` is set th *v* (the default)', + 'and the labels are set in `x`.', + 'By setting `orientation` to *h*, the roles are interchanged.' + ].join(' ') +}; + +module.exports = Bar; diff --git a/src/traces/box/index.js b/src/traces/box/index.js index bab6b26dd2c..e97f6c625ee 100644 --- a/src/traces/box/index.js +++ b/src/traces/box/index.js @@ -8,33 +8,36 @@ 'use strict'; -var Plotly = require('../../plotly'); +var Box = {}; -Plotly.Plots.register(exports, 'box', - ['cartesian', 'symbols', 'oriented', 'box', 'showLegend'], { - description: [ - 'In vertical (horizontal) box plots,', - 'statistics are computed using `y` (`x`) values.', - 'By supplying an `x` (`y`) array, one box per distinct x (y) value', - 'is drawn', - 'If no `x` (`y`) {array} is provided, a single box is drawn.', - 'That box position is then positioned with', - 'with `name` or with `x0` (`y0`) if provided.', - 'Each box spans from quartile 1 (Q1) to quartile 3 (Q3).', - 'The second quartile (Q2) is marked by a line inside the box.', - 'By default, the whiskers correspond to the box\' edges', - '+/- 1.5 times the interquartile range (IQR = Q3-Q1),', - 'see *boxpoints* for other options.' - ].join(' ') - } -); +Box.attributes = require('./attributes'); +Box.layoutAttributes = require('./layout_attributes'); +Box.supplyDefaults = require('./defaults'); +Box.supplyLayoutDefaults = require('./layout_defaults'); +Box.calc = require('./calc'); +Box.setPositions = require('./set_positions'); +Box.plot = require('./plot'); +Box.style = require('./style'); +Box.hoverPoints = require('./hover'); -exports.attributes = require('./attributes'); -exports.layoutAttributes = require('./layout_attributes'); -exports.supplyDefaults = require('./defaults'); -exports.supplyLayoutDefaults = require('./layout_defaults'); -exports.calc = require('./calc'); -exports.setPositions = require('./set_positions'); -exports.plot = require('./plot'); -exports.style = require('./style'); -exports.hoverPoints = require('./hover'); +Box.moduleType = 'trace'; +Box.name = 'box'; +Box.categories = ['cartesian', 'symbols', 'oriented', 'box', 'showLegend']; +Box.meta = { + description: [ + 'In vertical (horizontal) box plots,', + 'statistics are computed using `y` (`x`) values.', + 'By supplying an `x` (`y`) array, one box per distinct x (y) value', + 'is drawn', + 'If no `x` (`y`) {array} is provided, a single box is drawn.', + 'That box position is then positioned with', + 'with `name` or with `x0` (`y0`) if provided.', + 'Each box spans from quartile 1 (Q1) to quartile 3 (Q3).', + 'The second quartile (Q2) is marked by a line inside the box.', + 'By default, the whiskers correspond to the box\' edges', + '+/- 1.5 times the interquartile range (IQR = Q3-Q1),', + 'see *boxpoints* for other options.' + ].join(' ') +}; + +module.exports = Box; diff --git a/src/traces/choropleth/index.js b/src/traces/choropleth/index.js index f5beed4d62a..4999be85ae3 100644 --- a/src/traces/choropleth/index.js +++ b/src/traces/choropleth/index.js @@ -9,21 +9,24 @@ 'use strict'; -var Plots = require('../../plots/plots'); - -Plots.register(exports, 'choropleth', ['geo', 'noOpacity'], { +var Choropleth = {}; + +Choropleth.attributes = require('./attributes'); +Choropleth.supplyDefaults = require('./defaults'); +Choropleth.colorbar = require('../heatmap/colorbar'); +Choropleth.calc = require('../surface/calc'); +Choropleth.plot = require('./plot').plot; + +Choropleth.moduleType = 'trace'; +Choropleth.name = 'choropleth'; +Choropleth.categories = ['geo', 'noOpacity']; +Choropleth.meta = { description: [ 'The data that describes the choropleth value-to-color mapping', 'is set in `z`.', 'The geographic locations corresponding to each value in `z`', 'are set in `locations`.' ].join(' ') -}); - -exports.attributes = require('./attributes'); - -exports.supplyDefaults = require('./defaults'); - -exports.colorbar = require('../heatmap/colorbar'); +}; -exports.calc = require('../surface/calc'); +module.exports = Choropleth; diff --git a/src/traces/contour/index.js b/src/traces/contour/index.js index 6eed1bb667b..2a61c9c5db0 100644 --- a/src/traces/contour/index.js +++ b/src/traces/contour/index.js @@ -9,34 +9,30 @@ 'use strict'; -var Plotly = require('../../plotly'); - -Plotly.Plots.register(exports, 'contour', - ['cartesian', '2dMap', 'contour'], { - description: [ - 'The data from which contour lines are computed is set in `z`.', - 'Data in `z` must be a {2D array} of numbers.', - - 'Say that `z` has N rows and M columns, then by default,', - 'these N rows correspond to N y coordinates', - '(set in `y` or auto-generated) and the M columns', - 'correspond to M x coordinates (set in `x` or auto-generated).', - - 'By setting `transpose` to *true*, the above behavior is flipped.' - ].join(' ') - } -); - -exports.attributes = require('./attributes'); - -exports.supplyDefaults = require('./defaults'); - -exports.calc = require('./calc'); - -exports.plot = require('./plot'); - -exports.style = require('./style'); - -exports.colorbar = require('./colorbar'); - -exports.hoverPoints = require('./hover'); +var Contour = {}; + +Contour.attributes = require('./attributes'); +Contour.supplyDefaults = require('./defaults'); +Contour.calc = require('./calc'); +Contour.plot = require('./plot'); +Contour.style = require('./style'); +Contour.colorbar = require('./colorbar'); +Contour.hoverPoints = require('./hover'); + +Contour.moduleType = 'trace'; +Contour.name = 'contour'; +Contour.categories = ['cartesian', '2dMap', 'contour']; +Contour.meta = { + description: [ + 'The data from which contour lines are computed is set in `z`.', + 'Data in `z` must be a {2D array} of numbers.', + + 'Say that `z` has N rows and M columns, then by default,', + 'these N rows correspond to N y coordinates', + '(set in `y` or auto-generated) and the M columns', + 'correspond to M x coordinates (set in `x` or auto-generated).', + 'By setting `transpose` to *true*, the above behavior is flipped.' + ].join(' ') +}; + +module.exports = Contour; diff --git a/src/traces/heatmap/index.js b/src/traces/heatmap/index.js index baf8d30f27b..fd4f7882296 100644 --- a/src/traces/heatmap/index.js +++ b/src/traces/heatmap/index.js @@ -9,9 +9,20 @@ 'use strict'; -var Plotly = require('../../plotly'); - -Plotly.Plots.register(exports, 'heatmap', ['cartesian', '2dMap'], { +var Heatmap = {}; + +Heatmap.attributes = require('./attributes'); +Heatmap.supplyDefaults = require('./defaults'); +Heatmap.calc = require('./calc'); +Heatmap.plot = require('./plot'); +Heatmap.colorbar = require('./colorbar'); +Heatmap.style = require('./style'); +Heatmap.hoverPoints = require('./hover'); + +Heatmap.moduleType = 'trace'; +Heatmap.name = 'heatmap'; +Heatmap.categories = ['cartesian', '2dMap']; +Heatmap.meta = { description: [ 'The data that describes the heatmap value-to-color mapping', 'is set in `z`.', @@ -36,18 +47,6 @@ Plotly.Plots.register(exports, 'heatmap', ['cartesian', '2dMap'], { 'In the case where `z` is a 1D {array}, the x and y coordinates must be', 'provided in `x` and `y` respectively to form data triplets.' ].join(' ') -}); - -exports.attributes = require('./attributes'); - -exports.supplyDefaults = require('./defaults'); - -exports.calc = require('./calc'); - -exports.plot = require('./plot'); - -exports.colorbar = require('./colorbar'); - -exports.style = require('./style'); +}; -exports.hoverPoints = require('./hover'); +module.exports = Heatmap; diff --git a/src/traces/histogram/index.js b/src/traces/histogram/index.js index aeadc19e1ce..a18eb36b9c2 100644 --- a/src/traces/histogram/index.js +++ b/src/traces/histogram/index.js @@ -9,8 +9,6 @@ 'use strict'; -var Plotly = require('../../plotly'); - /** * Histogram has its own attribute, defaults and calc steps, * but uses bar's plot to display @@ -24,35 +22,31 @@ var Plotly = require('../../plotly'); * to allow quadrature combination of errors in summed histograms... */ -Plotly.Plots.register(exports, 'histogram', - ['cartesian', 'bar', 'histogram', 'oriented', 'errorBarsOK', 'showLegend'], { - description: [ - 'The sample data from which statistics are computed is set in `x`', - 'for vertically spanning histograms and', - 'in `y` for horizontally spanning histograms.', - - 'Binning options are set `xbins` and `ybins` respectively', - 'if no aggregation data is provided.' - ].join(' ') - } -); - -exports.attributes = require('./attributes'); - -exports.layoutAttributes = require('../bar/layout_attributes'); - -exports.supplyDefaults = require('./defaults'); - -exports.supplyLayoutDefaults = require('../bar/layout_defaults'); - -exports.calc = require('./calc'); - -exports.setPositions = require('../bar/set_positions'); - -exports.plot = require('../bar/plot'); - -exports.style = require('../bar/style'); - -exports.colorbar = require('../scatter/colorbar'); -exports.hoverPoints = require('../bar/hover'); +var Histogram = {}; + +Histogram.attributes = require('./attributes'); +Histogram.layoutAttributes = require('../bar/layout_attributes'); +Histogram.supplyDefaults = require('./defaults'); +Histogram.supplyLayoutDefaults = require('../bar/layout_defaults'); +Histogram.calc = require('./calc'); +Histogram.setPositions = require('../bar/set_positions'); +Histogram.plot = require('../bar/plot'); +Histogram.style = require('../bar/style'); +Histogram.colorbar = require('../scatter/colorbar'); +Histogram.hoverPoints = require('../bar/hover'); + +Histogram.moduleType = 'trace'; +Histogram.name = 'histogram'; +Histogram.categories = ['cartesian', 'bar', 'histogram', 'oriented', 'errorBarsOK', 'showLegend']; +Histogram.meta = { + description: [ + 'The sample data from which statistics are computed is set in `x`', + 'for vertically spanning histograms and', + 'in `y` for horizontally spanning histograms.', + 'Binning options are set `xbins` and `ybins` respectively', + 'if no aggregation data is provided.' + ].join(' ') +}; + +module.exports = Histogram; diff --git a/src/traces/histogram2d/index.js b/src/traces/histogram2d/index.js index 1fd50c4f094..e555fde47c6 100644 --- a/src/traces/histogram2d/index.js +++ b/src/traces/histogram2d/index.js @@ -9,32 +9,29 @@ 'use strict'; -var Plotly = require('../../plotly'); - -Plotly.Plots.register(exports, 'histogram2d', - ['cartesian', '2dMap', 'histogram'], { - hrName: 'histogram_2d', - description: [ - 'The sample data from which statistics are computed is set in `x`', - 'and `y` (where `x` and `y` represent marginal distributions,', - 'binning is set in `xbins` and `ybins` in this case)', - 'or `z` (where `z` represent the 2D distribution and binning set,', - 'binning is set by `x` and `y` in this case).', - 'The resulting distribution is visualized as a heatmap.' - ].join(' ') - } -); - -exports.attributes = require('./attributes'); - -exports.supplyDefaults = require('./defaults'); - -exports.calc = require('../heatmap/calc'); - -exports.plot = require('../heatmap/plot'); - -exports.colorbar = require('../heatmap/colorbar'); - -exports.style = require('../heatmap/style'); - -exports.hoverPoints = require('../heatmap/hover'); +var Histogram2D = {}; + +Histogram2D.attributes = require('./attributes'); +Histogram2D.supplyDefaults = require('./defaults'); +Histogram2D.calc = require('../heatmap/calc'); +Histogram2D.plot = require('../heatmap/plot'); +Histogram2D.colorbar = require('../heatmap/colorbar'); +Histogram2D.style = require('../heatmap/style'); +Histogram2D.hoverPoints = require('../heatmap/hover'); + +Histogram2D.moduleType = 'trace'; +Histogram2D.name = 'histogram2d'; +Histogram2D.categories = ['cartesian', '2dMap', 'histogram']; +Histogram2D.meta = { + hrName: 'histogram_2d', + description: [ + 'The sample data from which statistics are computed is set in `x`', + 'and `y` (where `x` and `y` represent marginal distributions,', + 'binning is set in `xbins` and `ybins` in this case)', + 'or `z` (where `z` represent the 2D distribution and binning set,', + 'binning is set by `x` and `y` in this case).', + 'The resulting distribution is visualized as a heatmap.' + ].join(' ') +}; + +module.exports = Histogram2D; diff --git a/src/traces/histogram2dcontour/index.js b/src/traces/histogram2dcontour/index.js index 5fc9fb40e0e..d8c4f5fdd17 100644 --- a/src/traces/histogram2dcontour/index.js +++ b/src/traces/histogram2dcontour/index.js @@ -9,32 +9,29 @@ 'use strict'; -var Plotly = require('../../plotly'); - -Plotly.Plots.register(exports, 'histogram2dcontour', - ['cartesian', '2dMap', 'contour', 'histogram'], { - hrName: 'histogram_2d_contour', - description: [ - 'The sample data from which statistics are computed is set in `x`', - 'and `y` (where `x` and `y` represent marginal distributions,', - 'binning is set in `xbins` and `ybins` in this case)', - 'or `z` (where `z` represent the 2D distribution and binning set,', - 'binning is set by `x` and `y` in this case).', - 'The resulting distribution is visualized as a contour plot.' - ].join(' ') - } -); - -exports.attributes = require('./attributes'); - -exports.supplyDefaults = require('./defaults'); - -exports.calc = require('../contour/calc'); - -exports.plot = require('../contour/plot'); - -exports.style = require('../contour/style'); - -exports.colorbar = require('../contour/colorbar'); - -exports.hoverPoints = require('../contour/hover'); +var Histogram2dContour = {}; + +Histogram2dContour.attributes = require('./attributes'); +Histogram2dContour.supplyDefaults = require('./defaults'); +Histogram2dContour.calc = require('../contour/calc'); +Histogram2dContour.plot = require('../contour/plot'); +Histogram2dContour.style = require('../contour/style'); +Histogram2dContour.colorbar = require('../contour/colorbar'); +Histogram2dContour.hoverPoints = require('../contour/hover'); + +Histogram2dContour.moduleType = 'trace'; +Histogram2dContour.name = 'histogram2dcontour'; +Histogram2dContour.categories = ['cartesian', '2dMap', 'contour', 'histogram']; +Histogram2dContour.meta = { + hrName: 'histogram_2d_contour', + description: [ + 'The sample data from which statistics are computed is set in `x`', + 'and `y` (where `x` and `y` represent marginal distributions,', + 'binning is set in `xbins` and `ybins` in this case)', + 'or `z` (where `z` represent the 2D distribution and binning set,', + 'binning is set by `x` and `y` in this case).', + 'The resulting distribution is visualized as a contour plot.' + ].join(' ') +}; + +module.exports = Histogram2dContour; diff --git a/src/traces/mesh3d/defaults.js b/src/traces/mesh3d/defaults.js index 64060c2ae33..8a0ff964c6d 100644 --- a/src/traces/mesh3d/defaults.js +++ b/src/traces/mesh3d/defaults.js @@ -10,12 +10,13 @@ 'use strict'; var Plotly = require('../../plotly'); -var Mesh3D = require('./'); +var Lib = require('../../lib'); +var attributes = require('./attributes'); module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) { function coerce(attr, dflt) { - return Plotly.Lib.coerce(traceIn, traceOut, Mesh3D.attributes, attr, dflt); + return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); } // read in face/vertex properties diff --git a/src/traces/mesh3d/index.js b/src/traces/mesh3d/index.js index 4f69c0dfcaa..63f472aee00 100644 --- a/src/traces/mesh3d/index.js +++ b/src/traces/mesh3d/index.js @@ -9,11 +9,17 @@ 'use strict'; -var Plotly = require('../../plotly'); +var Mesh3D = {}; -var Mesh3D = module.exports = {}; +Mesh3D.attributes = require('./attributes'); +Mesh3D.supplyDefaults = require('./defaults'); +Mesh3D.colorbar = require('../heatmap/colorbar'); +Mesh3D.plot = require('./convert'); -Plotly.Plots.register(Mesh3D, 'mesh3d', ['gl3d'], { +Mesh3D.moduleType = 'trace'; +Mesh3D.name = 'mesh3d', +Mesh3D.categories = ['gl3d']; +Mesh3D.meta = { description: [ 'Draws sets of triangles with coordinates given by', 'three 1-dimensional arrays in `x`, `y`, `z` and', @@ -22,10 +28,6 @@ Plotly.Plots.register(Mesh3D, 'mesh3d', ['gl3d'], { '(3) the Alpha-shape algorithm or', '(4) the Convex-hull algorithm' ].join(' ') -}); - -Mesh3D.attributes = require('./attributes'); - -Mesh3D.supplyDefaults = require('./defaults'); +}; -Mesh3D.colorbar = require('../heatmap/colorbar'); +module.exports = Mesh3D; diff --git a/src/traces/pie/index.js b/src/traces/pie/index.js index bde8f3ef91a..b11c828968e 100644 --- a/src/traces/pie/index.js +++ b/src/traces/pie/index.js @@ -8,21 +8,26 @@ 'use strict'; -var Plotly = require('../../plotly'); +var Pie = {}; -Plotly.Plots.register(exports, 'pie', ['pie', 'showLegend'], { +Pie.attributes = require('./attributes'); +Pie.supplyDefaults = require('./defaults'); +Pie.supplyLayoutDefaults = require('./layout_defaults'); +Pie.layoutAttributes = require('./layout_attributes'); +Pie.calc = require('./calc'); +Pie.plot = require('./plot'); +Pie.style = require('./style'); +Pie.styleOne = require('./style_one'); + +Pie.moduleType = 'trace'; +Pie.name = 'pie'; +Pie.categories = ['pie', 'showLegend']; +Pie.meta = { description: [ 'A data visualized by the sectors of the pie is set in `values`.', 'The sector labels are set in `labels`.', 'The sector colors are set in `marker.colors`' ].join(' ') -}); +}; -exports.attributes = require('./attributes'); -exports.supplyDefaults = require('./defaults'); -exports.supplyLayoutDefaults = require('./layout_defaults'); -exports.layoutAttributes = require('./layout_attributes'); -exports.calc = require('./calc'); -exports.plot = require('./plot'); -exports.style = require('./style'); -exports.styleOne = require('./style_one'); +module.exports = Pie; diff --git a/src/traces/scatter/index.js b/src/traces/scatter/index.js index 05ce0c5f8eb..1a9291617f9 100644 --- a/src/traces/scatter/index.js +++ b/src/traces/scatter/index.js @@ -12,7 +12,15 @@ var d3 = require('d3'); var isNumeric = require('fast-isnumeric'); -var Plotly = require('../../plotly'); +var Lib = require('../../lib'); + +var Fx = require('../../plots/cartesian/graph_interact'); +var Axes = require('../../plots/cartesian/axes'); + +var Color = require('../../components/color'); +var Colorscale = require('../../components/colorscale'); +var Drawing = require('../../components/drawing'); +var ErrorBars = require('../../components/errorbars'); var subtypes = require('./subtypes'); @@ -25,17 +33,18 @@ scatter.isBubble = subtypes.isBubble; scatter.selectPoints = require('./select'); -Plotly.Plots.register(scatter, 'scatter', - ['cartesian', 'symbols', 'markerColorscale', 'errorBarsOK', 'showLegend'], { - description: [ - 'The scatter trace type encompasses line charts, scatter charts, text charts, and bubble charts.', - 'The data visualized as scatter point or lines is set in `x` and `y`.', - 'Text (appearing either on the chart or on hover only) is via `text`.', - 'Bubble charts are achieved by setting `marker.size` and/or `marker.color`', - 'to a numerical arrays.' - ].join(' ') - } -); +scatter.moduleType = 'trace'; +scatter.name = 'scatter'; +scatter.categories = ['cartesian', 'symbols', 'markerColorscale', 'errorBarsOK', 'showLegend']; +scatter.meta = { + description: [ + 'The scatter trace type encompasses line charts, scatter charts, text charts, and bubble charts.', + 'The data visualized as scatter point or lines is set in `x` and `y`.', + 'Text (appearing either on the chart or on hover only) is via `text`.', + 'Bubble charts are achieved by setting `marker.size` and/or `marker.color`', + 'to a numerical arrays.' + ].join(' ') +}; // traces with < this many points are by default shown // with points and lines, > just get lines @@ -47,7 +56,7 @@ var handleXYDefaults = require('./xy_defaults'); scatter.supplyDefaults = function(traceIn, traceOut, defaultColor, layout) { function coerce(attr, dflt) { - return Plotly.Lib.coerce(traceIn, traceOut, scatter.attributes, attr, dflt); + return Lib.coerce(traceIn, traceOut, scatter.attributes, attr, dflt); } var len = handleXYDefaults(traceIn, traceOut, coerce), @@ -85,8 +94,8 @@ scatter.supplyDefaults = function(traceIn, traceOut, defaultColor, layout) { if(!scatter.hasLines(traceOut)) lineShapeDefaults(traceIn, traceOut, coerce); } - Plotly.ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'y'}); - Plotly.ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'x', inherit: 'y'}); + ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'y'}); + ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'x', inherit: 'y'}); }; // common to 'scatter', 'scatter3d', 'scattergeo' and 'scattergl' @@ -118,8 +127,8 @@ scatter.markerDefaults = function(traceIn, traceOut, defaultColor, layout, coerc coerce('marker.size'); coerce('marker.color', defaultColor); - if(Plotly.Colorscale.hasColorscale(traceIn, 'marker')) { - Plotly.Colorscale.handleDefaults( + if(Colorscale.hasColorscale(traceIn, 'marker')) { + Colorscale.handleDefaults( traceIn, traceOut, layout, coerce, {prefix: 'marker.', cLetter: 'c'} ); } @@ -130,12 +139,12 @@ scatter.markerDefaults = function(traceIn, traceOut, defaultColor, layout, coerc if(lineColor && traceOut.marker.color!==lineColor) { defaultMLC = lineColor; } - else if(isBubble) defaultMLC = Plotly.Color.background; - else defaultMLC = Plotly.Color.defaultLine; + else if(isBubble) defaultMLC = Color.background; + else defaultMLC = Color.defaultLine; coerce('marker.line.color', defaultMLC); - if(Plotly.Colorscale.hasColorscale(traceIn, 'marker.line')) { - Plotly.Colorscale.handleDefaults( + if(Colorscale.hasColorscale(traceIn, 'marker.line')) { + Colorscale.handleDefaults( traceIn, traceOut, layout, coerce, {prefix: 'marker.line.', cLetter: 'c'} ); } @@ -152,7 +161,7 @@ scatter.markerDefaults = function(traceIn, traceOut, defaultColor, layout, coerc // common to 'scatter', 'scatter3d' and 'scattergeo' scatter.textDefaults = function(traceIn, traceOut, layout, coerce) { coerce('textposition'); - Plotly.Lib.coerceFont(coerce, 'textfont', layout.font); + Lib.coerceFont(coerce, 'textfont', layout.font); }; // common to 'scatter' and 'scattergl' @@ -172,7 +181,7 @@ scatter.fillColorDefaults = function(traceIn, traceOut, defaultColor, coerce) { } } - coerce('fillcolor', Plotly.Color.addOpacity( + coerce('fillcolor', Color.addOpacity( (traceOut.line || {}).color || inheritColorFromMarker || defaultColor, 0.5 @@ -236,13 +245,13 @@ scatter.getBubbleSizeFn = function(trace) { }; scatter.calc = function(gd, trace) { - var xa = Plotly.Axes.getFromId(gd,trace.xaxis||'x'), - ya = Plotly.Axes.getFromId(gd,trace.yaxis||'y'); - Plotly.Lib.markTime('in Scatter.calc'); + var xa = Axes.getFromId(gd,trace.xaxis||'x'), + ya = Axes.getFromId(gd,trace.yaxis||'y'); + Lib.markTime('in Scatter.calc'); var x = xa.makeCalcdata(trace,'x'); - Plotly.Lib.markTime('finished convert x'); + Lib.markTime('finished convert x'); var y = ya.makeCalcdata(trace,'y'); - Plotly.Lib.markTime('finished convert y'); + Lib.markTime('finished convert y'); var serieslen = Math.min(x.length,y.length), marker, s, @@ -270,7 +279,7 @@ scatter.calc = function(gd, trace) { if (Array.isArray(s)) { // I tried auto-type but category and dates dont make much sense. var ax = {type: 'linear'}; - Plotly.Axes.setConvert(ax); + Axes.setConvert(ax); s = ax.makeCalcdata(trace.marker, 'size'); if(s.length>serieslen) s.splice(serieslen, s.length-serieslen); } @@ -324,11 +333,11 @@ scatter.calc = function(gd, trace) { yOptions.padded = false; } - Plotly.Lib.markTime('ready for Axes.expand'); - Plotly.Axes.expand(xa, x, xOptions); - Plotly.Lib.markTime('done expand x'); - Plotly.Axes.expand(ya, y, yOptions); - Plotly.Lib.markTime('done expand y'); + Lib.markTime('ready for Axes.expand'); + Axes.expand(xa, x, xOptions); + Lib.markTime('done expand x'); + Axes.expand(ya, y, yOptions); + Lib.markTime('done expand y'); // create the "calculated data" to plot var cd = new Array(serieslen); @@ -338,7 +347,7 @@ scatter.calc = function(gd, trace) { } // this has migrated up from arraysToCalcdata as we have a reference to 's' here - if (typeof s !== undefined) Plotly.Lib.mergeArray(s, cd, 'ms'); + if (typeof s !== undefined) Lib.mergeArray(s, cd, 'ms'); gd.firstscatter = false; return cd; @@ -351,11 +360,11 @@ scatter.calcMarkerColorscales = function(trace) { var marker = trace.marker; // auto-z and autocolorscale if applicable - if(Plotly.Colorscale.hasColorscale(trace, 'marker')) { - Plotly.Colorscale.calc(trace, marker.color, 'marker', 'c'); + if(Colorscale.hasColorscale(trace, 'marker')) { + Colorscale.calc(trace, marker.color, 'marker', 'c'); } - if(Plotly.Colorscale.hasColorscale(trace, 'marker.line')) { - Plotly.Colorscale.calc(trace, marker.line.color, 'marker.line', 'c'); + if(Colorscale.hasColorscale(trace, 'marker.line')) { + Colorscale.calc(trace, marker.line.color, 'marker.line', 'c'); } }; @@ -408,21 +417,21 @@ scatter.arraysToCalcdata = function(cd) { var trace = cd[0].trace, marker = trace.marker; - Plotly.Lib.mergeArray(trace.text, cd, 'tx'); - Plotly.Lib.mergeArray(trace.textposition, cd, 'tp'); + Lib.mergeArray(trace.text, cd, 'tx'); + Lib.mergeArray(trace.textposition, cd, 'tp'); if(trace.textfont) { - Plotly.Lib.mergeArray(trace.textfont.size, cd, 'ts'); - Plotly.Lib.mergeArray(trace.textfont.color, cd, 'tc'); - Plotly.Lib.mergeArray(trace.textfont.family, cd, 'tf'); + Lib.mergeArray(trace.textfont.size, cd, 'ts'); + Lib.mergeArray(trace.textfont.color, cd, 'tc'); + Lib.mergeArray(trace.textfont.family, cd, 'tf'); } if(marker && marker.line) { var markerLine = marker.line; - Plotly.Lib.mergeArray(marker.opacity, cd, 'mo'); - Plotly.Lib.mergeArray(marker.symbol, cd, 'mx'); - Plotly.Lib.mergeArray(marker.color, cd, 'mc'); - Plotly.Lib.mergeArray(markerLine.color, cd, 'mlc'); - Plotly.Lib.mergeArray(markerLine.width, cd, 'mlw'); + Lib.mergeArray(marker.opacity, cd, 'mo'); + Lib.mergeArray(marker.symbol, cd, 'mx'); + Lib.mergeArray(marker.color, cd, 'mc'); + Lib.mergeArray(markerLine.color, cd, 'mlc'); + Lib.mergeArray(markerLine.width, cd, 'mlw'); } }; @@ -485,14 +494,14 @@ scatter.plot = function(gd, plotinfo, cdscatter) { nexttonext = tr.append('path').classed('js-fill',true); if(['hv','vh','hvh','vhv'].indexOf(line.shape)!==-1) { - pathfn = Plotly.Drawing.steps(line.shape); - revpathbase = Plotly.Drawing.steps( + pathfn = Drawing.steps(line.shape); + revpathbase = Drawing.steps( line.shape.split('').reverse().join('') ); } else if(line.shape==='spline') { pathfn = revpathbase = function(pts) { - return Plotly.Drawing.smoothopen(pts, line.smoothing); + return Drawing.smoothopen(pts, line.smoothing); }; } else { @@ -567,19 +576,19 @@ scatter.plot = function(gd, plotinfo, cdscatter) { else { if(showMarkers) { s.selectAll('path.point') - .data(trace.marker.maxdisplayed ? visFilter : Plotly.Lib.identity) + .data(trace.marker.maxdisplayed ? visFilter : Lib.identity) .enter().append('path') .classed('point', true) - .call(Plotly.Drawing.translatePoints, xa, ya); + .call(Drawing.translatePoints, xa, ya); } if(showText) { s.selectAll('g') - .data(trace.marker.maxdisplayed ? visFilter : Plotly.Lib.identity) + .data(trace.marker.maxdisplayed ? visFilter : Lib.identity) // each text needs to go in its own 'g' in case // it gets converted to mathjax .enter().append('g') .append('text') - .call(Plotly.Drawing.translatePoints, xa, ya); + .call(Drawing.translatePoints, xa, ya); } } }); @@ -592,7 +601,7 @@ scatter.linePoints = function(d, opts) { baseTolerance = opts.baseTolerance, linear = opts.linear, segments = [], - badnum = Plotly.Axes.BADNUM, + badnum = Axes.BADNUM, minTolerance = 0.2, // fraction of tolerance "so close we don't even consider it a new point" pts = new Array(d.length), pti = 0, @@ -747,16 +756,16 @@ scatter.style = function(gd) { s.selectAll('g.points') .each(function(d){ d3.select(this).selectAll('path.point') - .call(Plotly.Drawing.pointStyle,d.trace||d[0].trace); + .call(Drawing.pointStyle,d.trace||d[0].trace); d3.select(this).selectAll('text') - .call(Plotly.Drawing.textPointStyle,d.trace||d[0].trace); + .call(Drawing.textPointStyle,d.trace||d[0].trace); }); s.selectAll('g.trace path.js-line') - .call(Plotly.Drawing.lineGroupStyle); + .call(Drawing.lineGroupStyle); s.selectAll('g.trace path.js-fill') - .call(Plotly.Drawing.fillGroupStyle); + .call(Drawing.fillGroupStyle); }; scatter.getTraceColor = function(trace, di) { @@ -766,7 +775,7 @@ scatter.getTraceColor = function(trace, di) { if(trace.mode === 'lines') { lc = trace.line.color; - return (lc && Plotly.Color.opacity(lc)) ? + return (lc && Color.opacity(lc)) ? lc : trace.fillcolor; } else if(trace.mode === 'none') { @@ -776,20 +785,20 @@ scatter.getTraceColor = function(trace, di) { var mc = di.mcc || (trace.marker || {}).color, mlc = di.mlcc || ((trace.marker || {}).line || {}).color; - tc = (mc && Plotly.Color.opacity(mc)) ? mc : - (mlc && Plotly.Color.opacity(mlc) && + tc = (mc && Color.opacity(mc)) ? mc : + (mlc && Color.opacity(mlc) && (di.mlw || ((trace.marker || {}).line || {}).width)) ? mlc : ''; if(tc) { // make sure the points aren't TOO transparent - if(Plotly.Color.opacity(tc) < 0.3) { - return Plotly.Color.addOpacity(tc, 0.3); + if(Color.opacity(tc) < 0.3) { + return Color.addOpacity(tc, 0.3); } else return tc; } else { lc = (trace.line || {}).color; - return (lc && Plotly.Color.opacity(lc) && + return (lc && Color.opacity(lc) && scatter.hasLines(trace) && trace.line.width) ? lc : trace.fillcolor; } @@ -819,9 +828,9 @@ scatter.hoverPoints = function(pointData, xval, yval, hovermode) { dy = Math.abs(ya.c2p(di.y)-ya.c2p(yval)); return Math.max(Math.sqrt(dx*dx + dy*dy)-rad, 1-3/rad); }, - distfn = Plotly.Fx.getDistanceFunction(hovermode, dx, dy, dxy); + distfn = Fx.getDistanceFunction(hovermode, dx, dy, dxy); - Plotly.Fx.getClosest(cd, distfn, pointData); + Fx.getClosest(cd, distfn, pointData); // skip the rest (for this trace) if we didn't find a close point if(pointData.index===false) return; @@ -845,7 +854,7 @@ scatter.hoverPoints = function(pointData, xval, yval, hovermode) { if(di.tx) pointData.text = di.tx; else if(trace.text) pointData.text = trace.text; - Plotly.ErrorBars.hoverInfo(di, trace, pointData); + ErrorBars.hoverInfo(di, trace, pointData); return [pointData]; }; diff --git a/src/traces/scatter3d/convert.js b/src/traces/scatter3d/convert.js index c0d33ef67b5..67011faba0c 100644 --- a/src/traces/scatter3d/convert.js +++ b/src/traces/scatter3d/convert.js @@ -9,17 +9,18 @@ 'use strict'; -var Plotly = require('../../plotly'); - var createLinePlot = require('gl-line3d'); var createScatterPlot = require('gl-scatter3d'); var createErrorBars = require('gl-error3d'); var createMesh = require('gl-mesh3d'); var triangulate = require('delaunay-triangulate'); +var Lib = require('../../lib'); var str2RgbaArray = require('../../lib/str2rgbarray'); var formatColor = require('../../lib/gl_format_color'); +var Scatter = require('../scatter'); + var DASH_PATTERNS = require('../../constants/gl3d_dashes.json'); var MARKER_SYMBOLS = require('../../constants/gl_markers.json'); @@ -156,7 +157,7 @@ function formatParam(paramIn, len, calculate, dflt, extraFn) { } } - else paramOut = calculate(paramIn, Plotly.Lib.identity); + else paramOut = calculate(paramIn, Lib.identity); return paramOut; } @@ -209,7 +210,7 @@ function convertPlotlyOptions(scene, data) { } if ('marker' in data) { - var sizeFn = Plotly.Scatter.getBubbleSizeFn(data); + var sizeFn = Scatter.getBubbleSizeFn(data); params.scatterColor = formatColor(marker, 1, len); params.scatterSize = formatParam(marker.size, len, calculateSize, 20, sizeFn); @@ -222,7 +223,7 @@ function convertPlotlyOptions(scene, data) { if ('textposition' in data) { params.textOffset = calculateTextOffset(data.textposition); // arrayOk === false params.textColor = formatColor(data.textfont, 1, len); - params.textSize = formatParam(data.textfont.size, len, Plotly.Lib.identity, 12); + params.textSize = formatParam(data.textfont.size, len, Lib.identity, 12); params.textFont = data.textfont.family; // arrayOk === false params.textAngle = 0; } diff --git a/src/traces/scatter3d/defaults.js b/src/traces/scatter3d/defaults.js index 65ce9fcb136..23e3df9b166 100644 --- a/src/traces/scatter3d/defaults.js +++ b/src/traces/scatter3d/defaults.js @@ -9,15 +9,17 @@ 'use strict'; -var Plotly = require('../../plotly'); -var Scatter3D = require('./'); +var Scatter = require('../../traces/scatter'); +var Lib = require('../../lib'); +var ErrorBars = require('../../components/errorbars'); + +var attributes = require('./attributes'); module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) { - var Scatter = Plotly.Scatter; function coerce(attr, dflt) { - return Plotly.Lib.coerce(traceIn, traceOut, Scatter3D.attributes, attr, dflt); + return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); } var len = handleXYZDefaults(traceIn, traceOut, coerce); @@ -54,9 +56,9 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout } } - Plotly.ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'z'}); - Plotly.ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'y', inherit: 'z'}); - Plotly.ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'x', inherit: 'z'}); + ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'z'}); + ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'y', inherit: 'z'}); + ErrorBars.supplyDefaults(traceIn, traceOut, defaultColor, {axis: 'x', inherit: 'z'}); }; function handleXYZDefaults(traceIn, traceOut, coerce) { diff --git a/src/traces/scatter3d/index.js b/src/traces/scatter3d/index.js index 5d193ffc74e..5073ae12533 100644 --- a/src/traces/scatter3d/index.js +++ b/src/traces/scatter3d/index.js @@ -6,43 +6,43 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; -var Plotly = require('../../plotly'); - -var Scatter3D = module.exports = {}; +var Scatter = require('../scatter'); -Plotly.Plots.register(Scatter3D, - 'scatter3d', ['gl3d', 'symbols', 'markerColorscale', 'showLegend'], { - hrName: 'scatter_3d', - description: [ - 'The data visualized as scatter point or lines in 3D dimension', - 'is set in `x`, `y`, `z`.', - 'Text (appearing either on the chart or on hover only) is via `text`.', - 'Bubble charts are achieved by setting `marker.size` and/or `marker.color`', - 'Projections are achieved via `projection`.', - 'Surface fills are achieved via `surfaceaxis`.' - ].join(' ') - } -); +var Scatter3D = {}; +Scatter3D.plot = require('./convert'); Scatter3D.attributes = require('./attributes'); - Scatter3D.markerSymbols = require('../../constants/gl_markers.json'); - Scatter3D.supplyDefaults = require('./defaults'); - -Scatter3D.colorbar = Plotly.Scatter.colorbar; +Scatter3D.colorbar = require('../scatter/colorbar'); Scatter3D.calc = function(gd, trace) { // this is a kludge to put the array attributes into // calcdata the way Scatter.plot does, so that legends and // popovers know what to do with them. var cd = [{x: false, y: false, trace: trace, t: {}}]; - Plotly.Scatter.arraysToCalcdata(cd); + Scatter.arraysToCalcdata(cd); - Plotly.Scatter.calcMarkerColorscales(trace); + Scatter.calcMarkerColorscales(trace); return cd; }; + +Scatter3D.moduleType = 'trace'; +Scatter3D.name = 'scatter3d'; +Scatter3D.categories = ['gl3d', 'symbols', 'markerColorscale', 'showLegend']; +Scatter3D.meta = { + hrName: 'scatter_3d', + description: [ + 'The data visualized as scatter point or lines in 3D dimension', + 'is set in `x`, `y`, `z`.', + 'Text (appearing either on the chart or on hover only) is via `text`.', + 'Bubble charts are achieved by setting `marker.size` and/or `marker.color`', + 'Projections are achieved via `projection`.', + 'Surface fills are achieved via `surfaceaxis`.' + ].join(' ') +}; + +module.exports = Scatter3D; diff --git a/src/traces/scattergeo/defaults.js b/src/traces/scattergeo/defaults.js index 7be4a56ed02..073eee96503 100644 --- a/src/traces/scattergeo/defaults.js +++ b/src/traces/scattergeo/defaults.js @@ -9,15 +9,15 @@ 'use strict'; -var Plotly = require('../../plotly'); -var ScatterGeo = require('./'); +var Lib = require('../../lib'); +var Scatter = require('../scatter'); +var attributes = require('./attributes'); module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) { - var Scatter = Plotly.Scatter; function coerce(attr, dflt) { - return Plotly.Lib.coerce(traceIn, traceOut, ScatterGeo.attributes, attr, dflt); + return Lib.coerce(traceIn, traceOut, attributes, attr, dflt); } var len = handleLonLatLocDefaults(traceIn, traceOut, coerce); diff --git a/src/traces/scattergeo/index.js b/src/traces/scattergeo/index.js index 868f2a1b652..c193af4816c 100644 --- a/src/traces/scattergeo/index.js +++ b/src/traces/scattergeo/index.js @@ -9,29 +9,31 @@ 'use strict'; -var Plotly = require('../../plotly'); +var Scatter = require('../scatter'); -var ScatterGeo = module.exports = {}; - -Plotly.Plots.register(ScatterGeo, 'scattergeo', - ['geo', 'symbols', 'markerColorscale', 'showLegend'], { - hrName: 'scatter_geo', - description: [ - 'The data visualized as scatter point or lines on a geographic map', - 'is provided either by longitude/latitude pairs in `lon` and `lat`', - 'respectively or by geographic location IDs or names in `locations`.' - ].join(' ') - } -); +var ScatterGeo = {}; ScatterGeo.attributes = require('./attributes'); - ScatterGeo.supplyDefaults = require('./defaults'); - -ScatterGeo.colorbar = Plotly.Scatter.colorbar; +ScatterGeo.colorbar = Scatter.colorbar; +ScatterGeo.plot = require('./plot').plot; ScatterGeo.calc = function(gd, trace) { - Plotly.Scatter.calcMarkerColorscales(trace); + Scatter.calcMarkerColorscales(trace); }; + +ScatterGeo.moduleType = 'trace'; +ScatterGeo.name = 'scattergeo'; +ScatterGeo.categories = ['geo', 'symbols', 'markerColorscale', 'showLegend']; +ScatterGeo.meta = { + hrName: 'scatter_geo', + description: [ + 'The data visualized as scatter point or lines on a geographic map', + 'is provided either by longitude/latitude pairs in `lon` and `lat`', + 'respectively or by geographic location IDs or names in `locations`.' + ].join(' ') +}; + +module.exports = ScatterGeo; diff --git a/src/traces/scattergeo/plot.js b/src/traces/scattergeo/plot.js index 29dbb737811..4a3f2d987ba 100644 --- a/src/traces/scattergeo/plot.js +++ b/src/traces/scattergeo/plot.js @@ -16,6 +16,13 @@ var getTopojsonFeatures = require('../../lib/topojson_utils').getTopojsonFeature var locationToFeature = require('../../lib/geo_location_utils').locationToFeature; var arrayToCalcItem = require('../../lib/array_to_calc_item'); +var Color = require('../../components/color'); +var Drawing = require('../../components/drawing'); + +var Scatter = require('../scatter'); + +var attributes = require('./attributes'); + var plotScatterGeo = module.exports = {}; @@ -109,7 +116,6 @@ function makeLineGeoJSON(trace) { plotScatterGeo.plot = function(geo, scattergeoData) { var gScatterGeo = geo.framework.select('g.scattergeolayer'), - Scatter = Plotly.Scatter, topojson = geo.topojson; // TODO move to more d3-idiomatic pattern (that's work on replot) @@ -204,12 +210,12 @@ plotScatterGeo.style = function(geo) { selection.selectAll('g.points') .each(function(trace){ d3.select(this).selectAll('path.point') - .call(Plotly.Drawing.pointStyle, trace); + .call(Drawing.pointStyle, trace); d3.select(this).selectAll('text') - .call(Plotly.Drawing.textPointStyle, trace); + .call(Drawing.textPointStyle, trace); }); - // GeoJSON calc data is incompatible with Plotly.Drawing.lineGroupStyle + // GeoJSON calc data is incompatible with Drawing.lineGroupStyle selection.selectAll('path.js-line') .style('fill', 'none') .each(function(d) { @@ -217,8 +223,8 @@ plotScatterGeo.style = function(geo) { line = trace.line || {}; d3.select(this) - .call(Plotly.Color.stroke, line.color) - .call(Plotly.Drawing.dashLine, line.dash || '', line.width || 0); + .call(Color.stroke, line.color) + .call(Drawing.dashLine, line.dash || '', line.width || 0); }); }; @@ -230,7 +236,7 @@ function makeCleanHoverLabelsFunc(geo, trace) { } var hoverinfoParts = (hoverinfo === 'all') ? - Plotly.ScatterGeo.attributes.hoverinfo.flags : + attributes.hoverinfo.flags : hoverinfo.split('+'); var hasLocation = (hoverinfoParts.indexOf('location') !== -1 && diff --git a/src/traces/scattergl/convert.js b/src/traces/scattergl/convert.js index db780939278..389da3b257f 100644 --- a/src/traces/scattergl/convert.js +++ b/src/traces/scattergl/convert.js @@ -17,9 +17,14 @@ var createLine = require('gl-line2d'); var createError = require('gl-error2d'); var isNumeric = require('fast-isnumeric'); +var Lib = require('../../lib'); var str2RGBArray = require('../../lib/str2rgbarray'); var formatColor = require('../../lib/gl_format_color'); +var Scatter = require('../scatter'); + +var ErrorBars = require('../../components/errorbars'); + var MARKER_SYMBOLS = require('../../constants/gl_markers.json'); var DASHES = require('../../constants/gl2d_dashes.json'); var AXES = ['xaxis', 'yaxis']; @@ -185,7 +190,7 @@ function convertColorScale(containerIn, markerOpacity, traceOpacity, count) { colors = Array.isArray(colors[0]) ? colors : - _convertArray(Plotly.Lib.identity, [colors], count); + _convertArray(Lib.identity, [colors], count); return _convertColor( colors, @@ -234,10 +239,10 @@ proto.update = function(options) { this.hasMarkers = false; } else { - this.hasLines = Plotly.Scatter.hasLines(options); + this.hasLines = Scatter.hasLines(options); this.hasErrorX = options.error_x.visible === true; this.hasErrorY = options.error_y.visible === true; - this.hasMarkers = Plotly.Scatter.hasMarkers(options); + this.hasMarkers = Scatter.hasMarkers(options); } this.textLabels = options.text; @@ -254,7 +259,7 @@ proto.update = function(options) { // not quite on-par with 'scatter', but close enough for now // does not handle the colorscale case - this.color = Plotly.Scatter.getTraceColor(options, {}); + this.color = Scatter.getTraceColor(options, {}); }; proto.updateFast = function(options) { @@ -344,7 +349,7 @@ proto.updateFancy = function(options) { var y = this.yData = yaxis.makeCalcdata(options, 'y'); // get error values - var errorVals = Plotly.ErrorBars.calcFromTrace(options, scene.fullLayout); + var errorVals = ErrorBars.calcFromTrace(options, scene.fullLayout); var len = x.length, idToIndex = new Array(len), @@ -413,7 +418,7 @@ proto.updateFancy = function(options) { this.scatterOptions.colors = new Array(pId * 4); this.scatterOptions.borderColors = new Array(pId * 4); - var markerSizeFunc = Plotly.Scatter.getBubbleSizeFn(options), + var markerSizeFunc = Scatter.getBubbleSizeFn(options), markerOpts = options.marker, markerOpacity = markerOpts.opacity, traceOpacity = options.opacity, diff --git a/src/traces/scattergl/index.js b/src/traces/scattergl/index.js index 4f7ad417ba8..53734f61ff4 100644 --- a/src/traces/scattergl/index.js +++ b/src/traces/scattergl/index.js @@ -6,29 +6,31 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; -var Plotly = require('../../plotly'); - -var ScatterGl = module.exports = {}; +var Scatter = require('../scatter'); +var Scatter3D = require('../scatter3d'); -Plotly.Plots.register(ScatterGl, 'scattergl', - ['gl2d', 'symbols', 'errorBarsOK', 'markerColorscale', 'showLegend'], { - description: [ - 'The data visualized as scatter point or lines is set in `x` and `y`', - 'using the WebGl plotting engine.', - 'Bubble charts are achieved by setting `marker.size` and/or `marker.color`', - 'to a numerical arrays.' - ].join(' ') - } -); +var ScatterGl = {}; ScatterGl.attributes = require('./attributes'); - ScatterGl.supplyDefaults = require('./defaults'); - -ScatterGl.colorbar = Plotly.Scatter.colorbar; +ScatterGl.colorbar = Scatter.colorbar; // reuse the Scatter3D 'dummy' calc step so that legends know what to do -ScatterGl.calc = Plotly.Scatter3D.calc; +ScatterGl.calc = Scatter3D.calc; +ScatterGl.plot = require('./convert'); + +ScatterGl.moduleType = 'trace'; +ScatterGl.name = 'scattergl'; +ScatterGl.categories = ['gl2d', 'symbols', 'errorBarsOK', 'markerColorscale', 'showLegend']; +ScatterGl.meta = { + description: [ + 'The data visualized as scatter point or lines is set in `x` and `y`', + 'using the WebGl plotting engine.', + 'Bubble charts are achieved by setting `marker.size` and/or `marker.color`', + 'to a numerical arrays.' + ].join(' ') +}; + +module.exports = ScatterGl; diff --git a/src/traces/surface/index.js b/src/traces/surface/index.js index cbe9995d918..c621ef1521b 100644 --- a/src/traces/surface/index.js +++ b/src/traces/surface/index.js @@ -9,11 +9,18 @@ 'use strict'; -var Plotly = require('../../plotly'); +var Surface = {}; -var Surface = module.exports = {}; +Surface.attributes = require('./attributes'); +Surface.supplyDefaults = require('./defaults'); +Surface.colorbar = require('../heatmap/colorbar'); +Surface.calc = require('./calc'); +Surface.plot = require('./convert'); -Plotly.Plots.register(Surface, 'surface', ['gl3d', 'noOpacity'], { +Surface.moduleType = 'trace'; +Surface.name = 'surface'; +Surface.categories = ['gl3d', 'noOpacity']; +Surface.meta = { description: [ 'The data the describes the coordinates of the surface is set in `z`.', 'Data in `z` should be a {2D array}.', @@ -24,12 +31,6 @@ Plotly.Plots.register(Surface, 'surface', ['gl3d', 'noOpacity'], { 'If not provided in `x` and `y`, the x and y coordinates are assumed', 'to be linear starting at 0 with a unit step.' ].join(' ') -}); - -Surface.attributes = require('./attributes'); +}; -Surface.supplyDefaults = require('./defaults'); - -Surface.colorbar = require('../heatmap/colorbar'); - -Surface.calc = require('./calc'); +module.exports = Surface; diff --git a/test/jasmine/tests/choropleth_test.js b/test/jasmine/tests/choropleth_test.js index 65d2ab9cf61..ffaf31570bc 100644 --- a/test/jasmine/tests/choropleth_test.js +++ b/test/jasmine/tests/choropleth_test.js @@ -1,11 +1,10 @@ var Plotly = require('@src/plotly'); +var Choropleth = require('@src/traces/choropleth'); describe('Test choropleth', function() { 'use strict'; - var Choropleth = Plotly.Choropleth; - describe('supplyDefaults', function() { var traceIn, traceOut; diff --git a/test/jasmine/tests/colorscale_test.js b/test/jasmine/tests/colorscale_test.js index 4af568c5d7f..e5af0a26c70 100644 --- a/test/jasmine/tests/colorscale_test.js +++ b/test/jasmine/tests/colorscale_test.js @@ -1,5 +1,7 @@ var Plotly = require('@src/plotly'); var Colorscale = require('@src/components/colorscale'); +var Heatmap = require('@src/traces/heatmap'); +var Scatter = require('@src/traces/scatter'); describe('Test colorscale:', function() { @@ -191,7 +193,7 @@ describe('Test colorscale:', function() { var traceIn, traceOut; function coerce(attr, dflt) { - return Plotly.Lib.coerce(traceIn, traceOut, Plotly.Heatmap.attributes, attr, dflt); + return Plotly.Lib.coerce(traceIn, traceOut, Heatmap.attributes, attr, dflt); } beforeEach(function() { @@ -261,7 +263,7 @@ describe('Test colorscale:', function() { var traceIn, traceOut; function coerce(attr, dflt) { - return Plotly.Lib.coerce(traceIn, traceOut, Plotly.Scatter.attributes, attr, dflt); + return Plotly.Lib.coerce(traceIn, traceOut, Scatter.attributes, attr, dflt); } beforeEach(function() { diff --git a/test/jasmine/tests/contour_test.js b/test/jasmine/tests/contour_test.js index f65296140e0..3dd05aa0a13 100644 --- a/test/jasmine/tests/contour_test.js +++ b/test/jasmine/tests/contour_test.js @@ -1,4 +1,5 @@ -var Plotly = require('@src/plotly'); +var Plots = require('@src/plots/plots'); +var Contour = require('@src/traces/contour'); describe('Test contour', function() { @@ -10,10 +11,10 @@ describe('Test contour', function() { var defaultColor = '#444', layout = { - font: Plotly.Plots.layoutAttributes.font + font: Plots.layoutAttributes.font }; - var supplyDefaults = Plotly.Contour.supplyDefaults; + var supplyDefaults = Contour.supplyDefaults; beforeEach(function() { traceOut = {}; diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index ecde41d96cf..cd65ffb9cde 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -1,6 +1,6 @@ -var Plotly = require('@src/plotly'); -var Heatmap = require('@src/traces/heatmap'); var convertColumnXYZ = require('@src/traces/heatmap/convert_column_xyz'); +var Heatmap = require('@src/traces/heatmap'); +var Plots = require('@src/plots/plots'); describe('Test heatmap', function() { @@ -12,7 +12,7 @@ describe('Test heatmap', function() { var defaultColor = '#444', layout = { - font: Plotly.Plots.layoutAttributes.font + font: Plots.layoutAttributes.font }; var supplyDefaults = Heatmap.supplyDefaults; @@ -44,13 +44,13 @@ describe('Test heatmap', function() { type: 'heatmap', z: [[1, 2], []] }; - traceOut = Plotly.Plots.supplyDataDefaults(traceIn, 0, layout); + traceOut = Plots.supplyDataDefaults(traceIn, 0, layout); traceIn = { type: 'heatmap', z: [[], [1, 2], [1, 2, 3]] }; - traceOut = Plotly.Plots.supplyDataDefaults(traceIn, 0, layout); + traceOut = Plots.supplyDataDefaults(traceIn, 0, layout); expect(traceOut.visible).toBe(true); expect(traceOut.visible).toBe(true); }); diff --git a/test/jasmine/tests/plot_api_test.js b/test/jasmine/tests/plot_api_test.js index 698304c93ca..8deb46899af 100644 --- a/test/jasmine/tests/plot_api_test.js +++ b/test/jasmine/tests/plot_api_test.js @@ -1,20 +1,24 @@ var Plotly = require('@src/plotly'); +var Plots = require('@src/plots/plots'); +var Scatter = require('@src/traces/scatter'); +var Bar = require('@src/traces/bar'); +var Legend = require('@src/components/legend'); describe('Test graph_obj', function() { 'use strict'; describe('Plotly.restyle', function() { beforeEach(function() { - spyOn(Plotly.Plots, 'previousPromises'); spyOn(Plotly, 'plot'); - spyOn(Plotly.Scatter, 'arraysToCalcdata'); - spyOn(Plotly.Bar, 'arraysToCalcdata'); - spyOn(Plotly.Plots, 'style'); - spyOn(Plotly.Legend, 'draw'); + spyOn(Plots, 'previousPromises'); + spyOn(Scatter, 'arraysToCalcdata'); + spyOn(Bar, 'arraysToCalcdata'); + spyOn(Plots, 'style'); + spyOn(Legend, 'draw'); }); function mockDefaultsAndCalc(gd) { - Plotly.Plots.supplyDefaults(gd); + Plots.supplyDefaults(gd); gd.calcdata = gd._fullData.map(function(trace) { return [{x: 1, y: 1, trace: trace}]; }); @@ -27,9 +31,9 @@ describe('Test graph_obj', function() { }; mockDefaultsAndCalc(gd); Plotly.restyle(gd, {'marker.color': 'red'}); - expect(Plotly.Scatter.arraysToCalcdata).toHaveBeenCalled(); - expect(Plotly.Bar.arraysToCalcdata).not.toHaveBeenCalled(); - expect(Plotly.Plots.style).toHaveBeenCalled(); + expect(Scatter.arraysToCalcdata).toHaveBeenCalled(); + expect(Bar.arraysToCalcdata).not.toHaveBeenCalled(); + expect(Plots.style).toHaveBeenCalled(); expect(Plotly.plot).not.toHaveBeenCalled(); // "docalc" deletes gd.calcdata - make sure this didn't happen expect(gd.calcdata).toBeDefined(); @@ -42,9 +46,9 @@ describe('Test graph_obj', function() { }; mockDefaultsAndCalc(gd); Plotly.restyle(gd, {'marker.color': 'red'}); - expect(Plotly.Scatter.arraysToCalcdata).not.toHaveBeenCalled(); - expect(Plotly.Bar.arraysToCalcdata).toHaveBeenCalled(); - expect(Plotly.Plots.style).toHaveBeenCalled(); + expect(Scatter.arraysToCalcdata).not.toHaveBeenCalled(); + expect(Bar.arraysToCalcdata).toHaveBeenCalled(); + expect(Plots.style).toHaveBeenCalled(); expect(Plotly.plot).not.toHaveBeenCalled(); expect(gd.calcdata).toBeDefined(); }); diff --git a/test/jasmine/tests/plots_test.js b/test/jasmine/tests/plots_test.js index e3bed3e7ad9..8565ca5c189 100644 --- a/test/jasmine/tests/plots_test.js +++ b/test/jasmine/tests/plots_test.js @@ -1,17 +1,19 @@ var Plotly = require('@src/plotly'); +var Plots = require('@src/plots/plots'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); -describe('Test Plotly.Plots', function() { + +describe('Test Plots', function() { 'use strict'; - describe('Plotly.Plots.supplyLayoutGlobalDefaults should', function() { + describe('Plots.supplyLayoutGlobalDefaults should', function() { var layoutIn, layoutOut, expected; - var supplyLayoutDefaults = Plotly.Plots.supplyLayoutGlobalDefaults; + var supplyLayoutDefaults = Plots.supplyLayoutGlobalDefaults; beforeEach(function() { layoutOut = {}; @@ -65,8 +67,8 @@ describe('Test Plotly.Plots', function() { }); - describe('Plotly.Plots.supplyDataDefaults', function() { - var supplyDataDefaults = Plotly.Plots.supplyDataDefaults, + describe('Plots.supplyDataDefaults', function() { + var supplyDataDefaults = Plots.supplyDataDefaults, layout = {}; var traceIn, traceOut; @@ -98,8 +100,8 @@ describe('Test Plotly.Plots', function() { }); }); - describe('Plotly.Plots.getSubplotIds', function() { - var getSubplotIds = Plotly.Plots.getSubplotIds; + describe('Plots.getSubplotIds', function() { + var getSubplotIds = Plots.getSubplotIds; var layout; it('returns scene ids', function() { @@ -143,8 +145,8 @@ describe('Test Plotly.Plots', function() { }); }); - describe('Plotly.Plots.getSubplotIdsInData', function() { - var getSubplotIdsInData = Plotly.Plots.getSubplotIdsInData; + describe('Plots.getSubplotIdsInData', function() { + var getSubplotIdsInData = Plots.getSubplotIdsInData; var ids, data; @@ -173,11 +175,11 @@ describe('Test Plotly.Plots', function() { }); - describe('Plotly.Plots.register, getModule, and traceIs', function() { + describe('Plots.register, getModule, and traceIs', function() { beforeEach(function() { - this.modulesKeys = Object.keys(Plotly.Plots.modules); - this.allTypesKeys = Object.keys(Plotly.Plots.allTypes); - this.allCategoriesKeys = Object.keys(Plotly.Plots.allCategories); + this.modulesKeys = Object.keys(Plots.modules); + this.allTypesKeys = Object.keys(Plots.allTypes); + this.allCategoriesKeys = Object.keys(Plots.allCategories); this.fakeModule = { calc: function() { return 42; }, @@ -187,7 +189,7 @@ describe('Test Plotly.Plots', function() { plot: function() { throw new Error('nope!'); } }; - Plotly.Plots.register(this.fakeModule, 'newtype', ['red', 'green']); + Plots.register(this.fakeModule, 'newtype', ['red', 'green']); spyOn(console, 'warn'); }); @@ -199,42 +201,40 @@ describe('Test Plotly.Plots', function() { }); } - revertObj(Plotly.Plots.modules, this.modulesKeys); - revertObj(Plotly.Plots.allTypes, this.allTypesKeys); - revertObj(Plotly.Plots.allCategories, this.allCategoriesKeys); + revertObj(Plots.modules, this.modulesKeys); + revertObj(Plots.allTypes, this.allTypesKeys); + revertObj(Plots.allCategories, this.allCategoriesKeys); }); - it('should error on attempts to reregister a type', function() { - var fm2 = this.fakeModule2; - expect(function() { Plotly.Plots.register(fm2, 'newtype', ['yellow', 'blue']); }) - .toThrow(new Error('type newtype already registered')); - expect(Plotly.Plots.allCategories.yellow).toBeUndefined(); + it('should warn on attempts to reregister a type', function() { + Plots.register(this.fakeModule2, 'newtype', ['yellow', 'blue']); + expect(Plots.allCategories.yellow).toBeUndefined(); }); it('should find the module for a type', function() { - expect(Plotly.Plots.getModule('newtype')).toBe(this.fakeModule); - expect(Plotly.Plots.getModule({type: 'newtype'})).toBe(this.fakeModule); + expect(Plots.getModule('newtype')).toBe(this.fakeModule); + expect(Plots.getModule({type: 'newtype'})).toBe(this.fakeModule); }); it('should return false for types it doesn\'t know', function() { - expect(Plotly.Plots.getModule('notatype')).toBe(false); - expect(Plotly.Plots.getModule({type: 'notatype'})).toBe(false); - expect(Plotly.Plots.getModule({type: 'newtype', r: 'this is polar'})).toBe(false); + expect(Plots.getModule('notatype')).toBe(false); + expect(Plots.getModule({type: 'notatype'})).toBe(false); + expect(Plots.getModule({type: 'newtype', r: 'this is polar'})).toBe(false); }); it('should find the categories for this type', function() { - expect(Plotly.Plots.traceIs('newtype', 'red')).toBe(true); - expect(Plotly.Plots.traceIs({type: 'newtype'}, 'red')).toBe(true); + expect(Plots.traceIs('newtype', 'red')).toBe(true); + expect(Plots.traceIs({type: 'newtype'}, 'red')).toBe(true); }); it('should not find other real categories', function() { - expect(Plotly.Plots.traceIs('newtype', 'cartesian')).toBe(false); - expect(Plotly.Plots.traceIs({type: 'newtype'}, 'cartesian')).toBe(false); + expect(Plots.traceIs('newtype', 'cartesian')).toBe(false); + expect(Plots.traceIs({type: 'newtype'}, 'cartesian')).toBe(false); expect(console.warn).not.toHaveBeenCalled(); }); }); - describe('Plotly.Plots.registerSubplot', function() { + describe('Plots.registerSubplot', function() { var fake = { name: 'fake', attr: 'abc', @@ -242,9 +242,9 @@ describe('Test Plotly.Plots', function() { attributes: { stuff: { 'more stuff': 102102 } } }; - Plotly.Plots.registerSubplot(fake); + Plots.registerSubplot(fake); - var subplotsRegistry = Plotly.Plots.subplotsRegistry; + var subplotsRegistry = Plots.subplotsRegistry; it('should register attr, idRoot and attributes', function() { expect(subplotsRegistry.fake.attr).toEqual('abc'); @@ -307,7 +307,7 @@ describe('Test Plotly.Plots', function() { }); - describe('Plotly.Plots.purge', function() { + describe('Plots.purge', function() { var gd; beforeEach(function(done) { @@ -324,7 +324,7 @@ describe('Test Plotly.Plots', function() { '_hmpixcount', '_hmlumcount' ]; - Plotly.Plots.purge(gd); + Plots.purge(gd); expect(Object.keys(gd)).toEqual(expectedKeys); expect(gd.data).toBeUndefined(); expect(gd.layout).toBeUndefined(); diff --git a/test/jasmine/tests/register_test.js b/test/jasmine/tests/register_test.js new file mode 100644 index 00000000000..bedcb79851b --- /dev/null +++ b/test/jasmine/tests/register_test.js @@ -0,0 +1,48 @@ +var Plotly = require('@src/plotly'); + +describe('the register function', function() { + + it('should throw an error when no argument is given', function() { + expect(function() { + Plotly.register(); + }).toThrowError(Error, 'No argument passed to Plotly.register.'); + }); + + it('should work with a single module', function() { + var mockTrace1 = { + moduleType: 'trace', + name: 'mockTrace1', + meta: 'Meta string', + categories: ['categories', 'array'] + }; + + expect(function() { + Plotly.register(mockTrace1); + }).not.toThrow(); + + expect(Plotly.Plots.getModule('mockTrace1')).toBe(mockTrace1); + }); + + it('should work with an array of modules', function() { + var mockTrace2 = { + moduleType: 'trace', + name: 'mockTrace2', + meta: 'Meta string', + categories: ['categories', 'array'] + }; + + expect(function() { + Plotly.register([mockTrace2]); + }).not.toThrow(); + + expect(Plotly.Plots.getModule('mockTrace2')).toBe(mockTrace2); + }); + + it('should throw an error when an invalid module is given', function() { + var invalidTrace = { moduleType: 'invalid' }; + + expect(function() { + Plotly.register([invalidTrace]); + }).toThrowError(Error, 'Invalid module was attempted to be registered!'); + }); +}); diff --git a/test/jasmine/tests/scattergeo_test.js b/test/jasmine/tests/scattergeo_test.js index 0168d3249f6..2391cdfb512 100644 --- a/test/jasmine/tests/scattergeo_test.js +++ b/test/jasmine/tests/scattergeo_test.js @@ -1,10 +1,8 @@ -var Plotly = require('@src/plotly'); +var ScatterGeo = require('@src/traces/scattergeo'); describe('Test scattergeo', function() { 'use strict'; - var ScatterGeo = Plotly.ScatterGeo; - describe('supplyDefaults', function() { var traceIn, traceOut;