Skip to content

Commit 56f3bb7

Browse files
authored
Merge pull request #3967 from plotly/scattergl-separate-calc-plot
Split and reuse functions reside inside index files of scattergl scatterpolargl and splom traces
2 parents a0021cd + bb12f68 commit 56f3bb7

19 files changed

+1782
-1584
lines changed

src/traces/scattergl/calc.js

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/**
2+
* Copyright 2012-2019, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
var cluster = require('point-cluster');
12+
13+
var Lib = require('../../lib');
14+
var AxisIDs = require('../../plots/cartesian/axis_ids');
15+
var findExtremes = require('../../plots/cartesian/autorange').findExtremes;
16+
17+
var scatterCalc = require('../scatter/calc');
18+
var calcMarkerSize = scatterCalc.calcMarkerSize;
19+
var calcAxisExpansion = scatterCalc.calcAxisExpansion;
20+
var setFirstScatter = scatterCalc.setFirstScatter;
21+
var calcColorscale = require('../scatter/colorscale_calc');
22+
var convert = require('./convert');
23+
var sceneUpdate = require('./scene_update');
24+
25+
var BADNUM = require('../../constants/numerical').BADNUM;
26+
var TOO_MANY_POINTS = require('./constants').TOO_MANY_POINTS;
27+
28+
module.exports = function calc(gd, trace) {
29+
var fullLayout = gd._fullLayout;
30+
var xa = AxisIDs.getFromId(gd, trace.xaxis);
31+
var ya = AxisIDs.getFromId(gd, trace.yaxis);
32+
var subplot = fullLayout._plots[trace.xaxis + trace.yaxis];
33+
var len = trace._length;
34+
var hasTooManyPoints = len >= TOO_MANY_POINTS;
35+
var len2 = len * 2;
36+
var stash = {};
37+
var i, xx, yy;
38+
39+
var x = xa.makeCalcdata(trace, 'x');
40+
var y = ya.makeCalcdata(trace, 'y');
41+
42+
// we need hi-precision for scatter2d,
43+
// regl-scatter2d uses NaNs for bad/missing values
44+
var positions = new Array(len2);
45+
for(i = 0; i < len; i++) {
46+
xx = x[i];
47+
yy = y[i];
48+
positions[i * 2] = xx === BADNUM ? NaN : xx;
49+
positions[i * 2 + 1] = yy === BADNUM ? NaN : yy;
50+
}
51+
52+
if(xa.type === 'log') {
53+
for(i = 0; i < len2; i += 2) {
54+
positions[i] = xa.c2l(positions[i]);
55+
}
56+
}
57+
if(ya.type === 'log') {
58+
for(i = 1; i < len2; i += 2) {
59+
positions[i] = ya.c2l(positions[i]);
60+
}
61+
}
62+
63+
// we don't build a tree for log axes since it takes long to convert log2px
64+
// and it is also
65+
if(hasTooManyPoints && (xa.type !== 'log' && ya.type !== 'log')) {
66+
// FIXME: delegate this to webworker
67+
stash.tree = cluster(positions);
68+
} else {
69+
var ids = stash.ids = new Array(len);
70+
for(i = 0; i < len; i++) {
71+
ids[i] = i;
72+
}
73+
}
74+
75+
// create scene options and scene
76+
calcColorscale(gd, trace);
77+
var opts = sceneOptions(gd, subplot, trace, positions, x, y);
78+
var scene = sceneUpdate(gd, subplot);
79+
80+
// Reuse SVG scatter axis expansion routine.
81+
// For graphs with very large number of points and array marker.size,
82+
// use average marker size instead to speed things up.
83+
setFirstScatter(fullLayout, trace);
84+
var ppad;
85+
if(!hasTooManyPoints) {
86+
ppad = calcMarkerSize(trace, len);
87+
} else if(opts.marker) {
88+
ppad = 2 * (opts.marker.sizeAvg || Math.max(opts.marker.size, 3));
89+
}
90+
calcAxisExpansion(gd, trace, xa, ya, x, y, ppad);
91+
if(opts.errorX) expandForErrorBars(trace, xa, opts.errorX);
92+
if(opts.errorY) expandForErrorBars(trace, ya, opts.errorY);
93+
94+
// set flags to create scene renderers
95+
if(opts.fill && !scene.fill2d) scene.fill2d = true;
96+
if(opts.marker && !scene.scatter2d) scene.scatter2d = true;
97+
if(opts.line && !scene.line2d) scene.line2d = true;
98+
if((opts.errorX || opts.errorY) && !scene.error2d) scene.error2d = true;
99+
if(opts.text && !scene.glText) scene.glText = true;
100+
101+
// FIXME: organize it in a more appropriate manner, probably in sceneOptions
102+
// put point-cluster instance for optimized regl calc
103+
if(opts.marker) {
104+
opts.marker.snap = stash.tree || TOO_MANY_POINTS;
105+
}
106+
107+
scene.lineOptions.push(opts.line);
108+
scene.errorXOptions.push(opts.errorX);
109+
scene.errorYOptions.push(opts.errorY);
110+
scene.fillOptions.push(opts.fill);
111+
scene.markerOptions.push(opts.marker);
112+
scene.markerSelectedOptions.push(opts.markerSel);
113+
scene.markerUnselectedOptions.push(opts.markerUnsel);
114+
scene.textOptions.push(opts.text);
115+
scene.textSelectedOptions.push(opts.textSel);
116+
scene.textUnselectedOptions.push(opts.textUnsel);
117+
scene.selectBatch.push([]);
118+
scene.unselectBatch.push([]);
119+
120+
stash._scene = scene;
121+
stash.index = scene.count;
122+
stash.x = x;
123+
stash.y = y;
124+
stash.positions = positions;
125+
scene.count++;
126+
127+
return [{x: false, y: false, t: stash, trace: trace}];
128+
};
129+
130+
function expandForErrorBars(trace, ax, opts) {
131+
var extremes = trace._extremes[ax._id];
132+
var errExt = findExtremes(ax, opts._bnds, {padded: true});
133+
extremes.min = extremes.min.concat(errExt.min);
134+
extremes.max = extremes.max.concat(errExt.max);
135+
}
136+
137+
function sceneOptions(gd, subplot, trace, positions, x, y) {
138+
var opts = convert.style(gd, trace);
139+
140+
if(opts.marker) {
141+
opts.marker.positions = positions;
142+
}
143+
144+
if(opts.line && positions.length > 1) {
145+
Lib.extendFlat(
146+
opts.line,
147+
convert.linePositions(gd, trace, positions)
148+
);
149+
}
150+
151+
if(opts.errorX || opts.errorY) {
152+
var errors = convert.errorBarPositions(gd, trace, positions, x, y);
153+
154+
if(opts.errorX) {
155+
Lib.extendFlat(opts.errorX, errors.x);
156+
}
157+
if(opts.errorY) {
158+
Lib.extendFlat(opts.errorY, errors.y);
159+
}
160+
}
161+
162+
if(opts.text) {
163+
Lib.extendFlat(
164+
opts.text,
165+
{positions: positions},
166+
convert.textPosition(gd, trace, opts.text, opts.marker)
167+
);
168+
Lib.extendFlat(
169+
opts.textSel,
170+
{positions: positions},
171+
convert.textPosition(gd, trace, opts.text, opts.markerSel)
172+
);
173+
Lib.extendFlat(
174+
opts.textUnsel,
175+
{positions: positions},
176+
convert.textPosition(gd, trace, opts.text, opts.markerUnsel)
177+
);
178+
}
179+
180+
return opts;
181+
}

src/traces/scattergl/edit_style.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright 2012-2019, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
var Lib = require('../../lib');
12+
var Color = require('../../components/color');
13+
14+
var DESELECTDIM = require('../../constants/interactions').DESELECTDIM;
15+
16+
function styleTextSelection(cd) {
17+
var cd0 = cd[0];
18+
var trace = cd0.trace;
19+
var stash = cd0.t;
20+
var scene = stash._scene;
21+
var index = stash.index;
22+
var els = scene.selectBatch[index];
23+
var unels = scene.unselectBatch[index];
24+
var baseOpts = scene.textOptions[index];
25+
var selOpts = scene.textSelectedOptions[index] || {};
26+
var unselOpts = scene.textUnselectedOptions[index] || {};
27+
var opts = Lib.extendFlat({}, baseOpts);
28+
var i, j;
29+
30+
if(els.length || unels.length) {
31+
var stc = selOpts.color;
32+
var utc = unselOpts.color;
33+
var base = baseOpts.color;
34+
var hasArrayBase = Array.isArray(base);
35+
opts.color = new Array(trace._length);
36+
37+
for(i = 0; i < els.length; i++) {
38+
j = els[i];
39+
opts.color[j] = stc || (hasArrayBase ? base[j] : base);
40+
}
41+
for(i = 0; i < unels.length; i++) {
42+
j = unels[i];
43+
var basej = hasArrayBase ? base[j] : base;
44+
opts.color[j] = utc ? utc :
45+
stc ? basej : Color.addOpacity(basej, DESELECTDIM);
46+
}
47+
}
48+
49+
scene.glText[index].update(opts);
50+
}
51+
52+
module.exports = {
53+
styleTextSelection: styleTextSelection
54+
};

0 commit comments

Comments
 (0)