Skip to content

Split scatter module #184

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jan 15, 2016
7 changes: 5 additions & 2 deletions src/components/drawing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ var Plotly = require('../../plotly');
var d3 = require('d3');
var isNumeric = require('fast-isnumeric');

var subTypes = require('../../traces/scatter/subtypes');
var makeBubbleSizeFn = require('../../traces/scatter/make_bubble_size_func');

var drawing = module.exports = {};

// -----------------------------------------------------
Expand Down Expand Up @@ -175,14 +178,14 @@ drawing.pointStyle = function(s, trace) {
// only scatter & box plots get marker path and opacity
// bars, histograms don't
if(Plotly.Plots.traceIs(trace, 'symbols')) {
var sizeFn = Plotly.Scatter.getBubbleSizeFn(trace);
var sizeFn = makeBubbleSizeFn(trace);

s.attr('d', function(d) {
var r;

// handle multi-trace graph edit case
if(d.ms==='various' || marker.size==='various') r = 3;
else r = Plotly.Scatter.isBubble(trace) ?
else r = subTypes.isBubble(trace) ?
sizeFn(d.ms) : (marker.size || 6) / 2;

// store the calculated size so hover can use it
Expand Down
14 changes: 9 additions & 5 deletions src/components/errorbars/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@

'use strict';

var Plotly = require('../../plotly');
var d3 = require('d3');
var isNumeric = require('fast-isnumeric');

var Lib = require('../../lib');
var Color = require('../color');
var subTypes = require('../../traces/scatter/subtypes');


var errorBars = module.exports = {};

errorBars.attributes = require('./attributes');
Expand Down Expand Up @@ -70,13 +74,13 @@ errorBars.plot = function(gd, plotinfo, cd) {
var trace = d[0].trace,
xObj = trace.error_x,
yObj = trace.error_y,
sparse = Plotly.Scatter.hasMarkers(trace) &&
sparse = subTypes.hasMarkers(trace) &&
trace.marker.maxdisplayed>0;

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

d3.select(this).selectAll('g')
.data(Plotly.Lib.identity)
.data(Lib.identity)
.enter().append('g')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the .enter() line is only indented 2.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a pretty normal pattern in d3, because .enter() is changing the selection so we want people to know it's not quite part of the normal method chain.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd vote for keeping the classic d3 style here.

Plus, it passed the eslint indent rule check, so nothing to worry.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh I see. Carry on then 😆

.each(function(d){
coords = errorcoords(d, xa, ya);
Expand Down Expand Up @@ -121,13 +125,13 @@ errorBars.style = function(gd){

eb.selectAll('g path.yerror')
.style('stroke-width', yObj.thickness+'px')
.call(Plotly.Color.stroke, yObj.color);
.call(Color.stroke, yObj.color);

if(xObj.copy_ystyle) xObj = yObj;

eb.selectAll('g path.xerror')
.style('stroke-width', xObj.thickness+'px')
.call(Plotly.Color.stroke, xObj.color);
.call(Color.stroke, xObj.color);
});
};

Expand Down
9 changes: 5 additions & 4 deletions src/components/legend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
var Plotly = require('../../plotly');
var d3 = require('d3');

var subTypes = require('../../traces/scatter/subtypes');
var styleOne = require('../../traces/pie/style_one');

var legend = module.exports = {};
Expand Down Expand Up @@ -80,7 +81,7 @@ legend.supplyLayoutDefaults = function(layoutIn, layoutOut, fullData) {
legend.lines = function(d){
var trace = d[0].trace,
showFill = trace.visible && trace.fill && trace.fill!=='none',
showLine = Plotly.Scatter.hasLines(trace);
showLine = subTypes.hasLines(trace);

var fill = d3.select(this).select('.legendfill').selectAll('path')
.data(showFill ? [d] : []);
Expand All @@ -100,9 +101,9 @@ legend.lines = function(d){
legend.points = function(d){
var d0 = d[0],
trace = d0.trace,
showMarkers = Plotly.Scatter.hasMarkers(trace),
showText = Plotly.Scatter.hasText(trace),
showLines = Plotly.Scatter.hasLines(trace);
showMarkers = subTypes.hasMarkers(trace),
showText = subTypes.hasText(trace),
showLines = subTypes.hasLines(trace);

var dMod, tMod;

Expand Down
5 changes: 1 addition & 4 deletions src/plotly.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,8 @@ exports.register = function register(_modules) {
}
};


exports.register(require('./traces/scatter'));

// Scatter is the only trace included by default
exports.Scatter = Plots.getModule('scatter');
exports.register(require('./traces/scatter'));

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


'use strict';

var Lib = require('../../lib');


// arrayOk attributes, merge them into calcdata array
module.exports = function arraysToCalcdata(cd) {
var trace = cd[0].trace,
marker = trace.marker;

Lib.mergeArray(trace.text, cd, 'tx');
Lib.mergeArray(trace.textposition, cd, 'tp');
if(trace.textfont) {
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;
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');
}
};
7 changes: 4 additions & 3 deletions src/traces/scatter/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@

var Drawing = require('../../components/drawing');

var PTS_LINESONLY = 20; // TODO put in constants/
var constants = require('./constants');


module.exports = {
x: {
Expand Down Expand Up @@ -76,15 +77,15 @@ module.exports = {
},
mode: {
valType: 'flaglist',
flags: ['lines','markers','text'],
flags: ['lines', 'markers', 'text'],
extras: ['none'],
role: 'info',
description: [
'Determines the drawing mode for this scatter trace.',
'If the provided `mode` includes *text* then the `text` elements',
'appear at the coordinates. Otherwise, the `text` elements',
'appear on hover.',
'If there are less than ' + PTS_LINESONLY + ' points,',
'If there are less than ' + constants.PTS_LINESONLY + ' points,',
'then the default is *lines+markers*. Otherwise, *lines*.'
].join(' ')
},
Expand Down
132 changes: 132 additions & 0 deletions src/traces/scatter/calc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var isNumeric = require('fast-isnumeric');

var Axes = require('../../plots/cartesian/axes');
var Lib = require('../../lib');

var subTypes = require('./subtypes');
var calcMarkerColorscale = require('./marker_colorscale_calc');


module.exports = function calc(gd, trace) {
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');
Lib.markTime('finished convert x');

var y = ya.makeCalcdata(trace, 'y');
Lib.markTime('finished convert y');

var serieslen = Math.min(x.length, y.length),
marker,
s,
i;

// cancel minimum tick spacings (only applies to bars and boxes)
xa._minDtick = 0;
ya._minDtick = 0;

if(x.length > serieslen) x.splice(serieslen, x.length - serieslen);
if(y.length > serieslen) y.splice(serieslen, y.length - serieslen);

// check whether bounds should be tight, padded, extended to zero...
// most cases both should be padded on both ends, so start with that.
var xOptions = {padded: true},
yOptions = {padded: true};

if(subTypes.hasMarkers(trace)) {

// Treat size like x or y arrays --- Run d2c
// this needs to go before ppad computation
marker = trace.marker;
s = marker.size;

if (Array.isArray(s)) {
// I tried auto-type but category and dates dont make much sense.
var ax = {type: 'linear'};
Axes.setConvert(ax);
s = ax.makeCalcdata(trace.marker, 'size');
if(s.length > serieslen) s.splice(serieslen, s.length - serieslen);
}

var sizeref = 1.6 * (trace.marker.sizeref || 1),
markerTrans;
if(trace.marker.sizemode === 'area') {
markerTrans = function(v) {
return Math.max(Math.sqrt((v || 0) / sizeref), 3);
};
}
else {
markerTrans = function(v) {
return Math.max((v || 0) / sizeref, 3);
};
}
xOptions.ppad = yOptions.ppad = Array.isArray(s) ?
s.map(markerTrans) : markerTrans(s);
}

calcMarkerColorscale(trace);

// TODO: text size

// include zero (tight) and extremes (padded) if fill to zero
// (unless the shape is closed, then it's just filling the shape regardless)
if(((trace.fill === 'tozerox') ||
((trace.fill === 'tonextx') && gd.firstscatter)) &&
((x[0] !== x[serieslen - 1]) || (y[0] !== y[serieslen - 1]))) {
xOptions.tozero = true;
}

// if no error bars, markers or text, or fill to y=0 remove x padding
else if(!trace.error_y.visible && (
['tonexty', 'tozeroy'].indexOf(trace.fill) !== -1 ||
(!subTypes.hasMarkers(trace) && !subTypes.hasText(trace))
)) {
xOptions.padded = false;
xOptions.ppad = 0;
}

// now check for y - rather different logic, though still mostly padded both ends
// include zero (tight) and extremes (padded) if fill to zero
// (unless the shape is closed, then it's just filling the shape regardless)
if(((trace.fill === 'tozeroy') || ((trace.fill === 'tonexty') && gd.firstscatter)) &&
((x[0] !== x[serieslen - 1]) || (y[0] !== y[serieslen - 1]))) {
yOptions.tozero = true;
}

// tight y: any x fill
else if(['tonextx', 'tozerox'].indexOf(trace.fill) !== -1) {
yOptions.padded = false;
}

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);
for(i = 0; i < serieslen; i++) {
cd[i] = (isNumeric(x[i]) && isNumeric(y[i])) ?
{x: x[i], y: y[i]} : {x: false, y: false};
}

// this has migrated up from arraysToCalcdata as we have a reference to 's' here
if (typeof s !== undefined) Lib.mergeArray(s, cd, 'ms');

gd.firstscatter = false;
return cd;
};
39 changes: 39 additions & 0 deletions src/traces/scatter/clean_data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/


'use strict';


module.exports = function cleanData(fullData) {
var i,
tracei,
filli,
j,
tracej;

// remove opacity for any trace that has a fill or is filled to
for(i = 0; i < fullData.length; i++) {
tracei = fullData[i];
filli = tracei.fill;
if((filli === 'none') || (tracei.type !== 'scatter')) continue;
tracei.opacity = undefined;

if(filli === 'tonexty' || filli === 'tonextx') {
for(j = i - 1; j >= 0; j--) {
tracej = fullData[j];
if((tracej.type === 'scatter') &&
(tracej.xaxis === tracei.xaxis) &&
(tracej.yaxis === tracei.yaxis)) {
tracej.opacity = undefined;
break;
}
}
}
}
};
2 changes: 1 addition & 1 deletion src/traces/scatter/colorbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = function colorbar(gd, cd) {
// TODO unify Scatter.colorbar and Heatmap.colorbar
// TODO make Plotly[module].colorbar support multiple colorbar per trace

if(marker===undefined || !marker.showscale){
if((marker === undefined) || !marker.showscale){
Plotly.Plots.autoMargin(gd, cbId);
return;
}
Expand Down
14 changes: 14 additions & 0 deletions src/traces/scatter/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/


'use strict';

module.exports = {
PTS_LINESONLY: 20
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slightly abusive, but it's the only way to clear us of circular dependencies while keeping things 🌴

};
Loading