Skip to content

Commit 0deaccc

Browse files
committed
added pointcloud2d (squashed)
1 parent 7387b2b commit 0deaccc

File tree

8 files changed

+281
-0
lines changed

8 files changed

+281
-0
lines changed

lib/index-gl2d.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var Plotly = require('./core');
1212

1313
Plotly.register([
1414
require('./scattergl'),
15+
require('./pointcloud'),
1516
require('./heatmapgl'),
1617
require('./contourgl')
1718
]);

lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Plotly.register([
2525
require('./scattergeo'),
2626
require('./choropleth'),
2727
require('./scattergl'),
28+
require('./pointcloud'),
2829
require('./scatterternary'),
2930
require('./scattermapbox')
3031
]);

lib/pointcloud.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/**
2+
* Copyright 2012-2016, 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+
module.exports = require('../src/traces/pointcloud');

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"gl-plot3d": "^1.5.0",
6969
"gl-scatter2d": "^1.0.5",
7070
"gl-scatter2d-fancy": "^1.1.1",
71+
"gl-pointcloud2d": "gl-vis/gl-pointcloud2d",
7172
"gl-scatter3d": "^1.0.4",
7273
"gl-select-box": "^1.0.1",
7374
"gl-spikes2d": "^1.0.1",

src/traces/pointcloud/attributes.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright 2012-2016, 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 scatterglAttrs = require('../scattergl/attributes');
12+
13+
module.exports = {
14+
x: scatterglAttrs.x,
15+
x0: scatterglAttrs.x0,
16+
dx: scatterglAttrs.dx,
17+
y: scatterglAttrs.y,
18+
y0: scatterglAttrs.y0,
19+
dy: scatterglAttrs.dy,
20+
text: scatterglAttrs.text,
21+
marker: scatterglAttrs.marker
22+
};

src/traces/pointcloud/convert.js

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/**
2+
* Copyright 2012-2016, 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 createpointcloud = require('gl-pointcloud2d');
12+
var isNumeric = require('fast-isnumeric');
13+
14+
var str2RGBArray = require('../../lib/str2rgbarray');
15+
var getTraceColor = require('../scatter/get_trace_color');
16+
17+
var AXES = ['xaxis', 'yaxis'];
18+
19+
function Pointcloud(scene, uid) {
20+
this.scene = scene;
21+
this.uid = uid;
22+
23+
this.pickXData = [];
24+
this.pickYData = [];
25+
this.xData = [];
26+
this.yData = [];
27+
this.textLabels = [];
28+
this.color = 'rgb(0, 0, 0)';
29+
this.name = '';
30+
this.hoverinfo = 'all';
31+
32+
this.idToIndex = [];
33+
this.bounds = [0, 0, 0, 0];
34+
35+
this.pointcloudOptions = {
36+
positions: new Float32Array(0),
37+
size: 12,
38+
color: [0, 0, 0, 1],
39+
borderSize: 1,
40+
borderColor: [0, 0, 0, 1]
41+
};
42+
this.pointcloud = createpointcloud(scene.glplot, this.pointcloudOptions);
43+
this.pointcloud._trace = this; // scene2d requires this prop
44+
}
45+
46+
var proto = Pointcloud.prototype;
47+
48+
proto.handlePick = function(pickResult) {
49+
50+
var index = this.idToIndex[pickResult.pointId];
51+
52+
return {
53+
trace: this,
54+
dataCoord: pickResult.dataCoord,
55+
traceCoord: [
56+
this.pickXData[index],
57+
this.pickYData[index]
58+
],
59+
textLabel: Array.isArray(this.textLabels) ?
60+
this.textLabels[index] :
61+
this.textLabels,
62+
color: Array.isArray(this.color) ?
63+
this.color[index] :
64+
this.color,
65+
name: this.name,
66+
hoverinfo: this.hoverinfo
67+
};
68+
};
69+
70+
/**
71+
* Truncate a Float32Array to some length. A wrapper to support environments
72+
* (e.g. node-webkit) that do not implement Float32Array.prototype.slice
73+
*/
74+
function truncate(float32ArrayIn, len) {
75+
if(Float32Array.slice === undefined) {
76+
var float32ArrayOut = new Float32Array(len);
77+
for(var i = 0; i < len; i++) float32ArrayOut[i] = float32ArrayIn[i];
78+
return float32ArrayOut;
79+
}
80+
81+
return float32ArrayIn.slice(0, len);
82+
}
83+
84+
proto.update = function(options) {
85+
86+
this.textLabels = options.text;
87+
this.name = options.name;
88+
this.hoverinfo = options.hoverinfo;
89+
this.bounds = [Infinity, Infinity, -Infinity, -Infinity];
90+
91+
this.updateFast(options);
92+
93+
this.color = getTraceColor(options, {});
94+
};
95+
96+
proto.updateFast = function(options) {
97+
var x = this.xData = this.pickXData = options.x;
98+
var y = this.yData = this.pickYData = options.y;
99+
100+
var len = x.length,
101+
idToIndex = new Array(len),
102+
positions = new Float32Array(2 * len),
103+
bounds = this.bounds,
104+
pId = 0,
105+
ptr = 0;
106+
107+
var xx, yy;
108+
109+
// TODO add 'very fast' mode that bypasses this loop
110+
// TODO bypass this on modebar +/- zoom
111+
for(var i = 0; i < len; ++i) {
112+
xx = x[i];
113+
yy = y[i];
114+
115+
// check for isNaN is faster but doesn't skip over nulls
116+
if(!isNumeric(xx) || !isNumeric(yy)) continue;
117+
118+
idToIndex[pId++] = i;
119+
120+
positions[ptr++] = xx;
121+
positions[ptr++] = yy;
122+
123+
bounds[0] = Math.min(bounds[0], xx);
124+
bounds[1] = Math.min(bounds[1], yy);
125+
bounds[2] = Math.max(bounds[2], xx);
126+
bounds[3] = Math.max(bounds[3], yy);
127+
}
128+
129+
positions = truncate(positions, ptr);
130+
this.idToIndex = idToIndex;
131+
132+
var markerSize;
133+
134+
this.pointcloudOptions.positions = positions;
135+
136+
var markerColor = str2RGBArray(options.marker.color),
137+
borderColor = str2RGBArray(options.marker.line.color),
138+
opacity = options.opacity * options.marker.opacity;
139+
140+
markerColor[3] *= opacity;
141+
this.pointcloudOptions.color = markerColor;
142+
143+
borderColor[3] *= opacity;
144+
this.pointcloudOptions.borderColor = borderColor;
145+
146+
markerSize = options.marker.size;
147+
this.pointcloudOptions.size = markerSize;
148+
this.pointcloudOptions.borderSize = options.marker.line.width;
149+
150+
this.pointcloud.update(this.pointcloudOptions);
151+
152+
// add item for autorange routine
153+
this.expandAxesFast(bounds, markerSize);
154+
};
155+
156+
proto.expandAxesFast = function(bounds, markerSize) {
157+
var pad = markerSize || 10;
158+
var ax, min, max;
159+
160+
for(var i = 0; i < 2; i++) {
161+
ax = this.scene[AXES[i]];
162+
163+
min = ax._min;
164+
if(!min) min = [];
165+
min.push({ val: bounds[i], pad: pad });
166+
167+
max = ax._max;
168+
if(!max) max = [];
169+
max.push({ val: bounds[i + 2], pad: pad });
170+
}
171+
};
172+
173+
proto.dispose = function() {
174+
this.pointcloud.dispose();
175+
};
176+
177+
function createPointcloud(scene, data) {
178+
var plot = new Pointcloud(scene, data.uid);
179+
plot.update(data);
180+
return plot;
181+
}
182+
183+
module.exports = createPointcloud;

src/traces/pointcloud/defaults.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Copyright 2012-2016, 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+
10+
'use strict';
11+
12+
var Lib = require('../../lib');
13+
14+
var handleXYDefaults = require('../scatter/xy_defaults');
15+
var handleMarkerDefaults = require('../scatter/marker_defaults');
16+
17+
var attributes = require('./attributes');
18+
19+
module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
20+
function coerce(attr, dflt) {
21+
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
22+
}
23+
24+
var len = handleXYDefaults(traceIn, traceOut, coerce);
25+
if(!len) {
26+
traceOut.visible = false;
27+
return;
28+
}
29+
30+
coerce('text');
31+
32+
handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce);
33+
};

src/traces/pointcloud/index.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright 2012-2016, 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 pointcloud = {};
12+
13+
pointcloud.attributes = require('./attributes');
14+
pointcloud.supplyDefaults = require('./defaults');
15+
16+
// reuse the Scatter3D 'dummy' calc step so that legends know what to do
17+
pointcloud.calc = require('../scatter3d/calc');
18+
pointcloud.plot = require('./convert');
19+
20+
pointcloud.moduleType = 'trace';
21+
pointcloud.name = 'pointcloud';
22+
pointcloud.basePlotModule = require('../../plots/gl2d');
23+
pointcloud.categories = ['gl2d', 'showLegend'];
24+
pointcloud.meta = {
25+
description: [
26+
'The data visualized as a point cloud set in `x` and `y`',
27+
'using the WebGl plotting engine.'
28+
].join(' ')
29+
};
30+
31+
module.exports = pointcloud;

0 commit comments

Comments
 (0)