Skip to content

Commit f1a8426

Browse files
committed
refactor scattergl - separate calc and scene_update from index file
1 parent 0690162 commit f1a8426

File tree

3 files changed

+339
-311
lines changed

3 files changed

+339
-311
lines changed

src/traces/scattergl/calc.js

Lines changed: 181 additions & 0 deletions
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+
}

0 commit comments

Comments
 (0)