Skip to content

Commit db35191

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

File tree

8 files changed

+283
-0
lines changed

8 files changed

+283
-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('./pointcloud2d'),
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('./pointcloud2d'),
2829
require('./scatterternary'),
2930
require('./scattermapbox')
3031
]);

lib/pointcloud2d.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/pointcloud2d');

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/pointcloud2d/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/pointcloud2d/convert.js

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

src/traces/pointcloud2d/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/pointcloud2d/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 Pointcloud2d = {};
12+
13+
Pointcloud2d.attributes = require('./attributes');
14+
Pointcloud2d.supplyDefaults = require('./defaults');
15+
16+
// reuse the Scatter3D 'dummy' calc step so that legends know what to do
17+
Pointcloud2d.calc = require('../scatter3d/calc');
18+
Pointcloud2d.plot = require('./convert');
19+
20+
Pointcloud2d.moduleType = 'trace';
21+
Pointcloud2d.name = 'pointcloud2d';
22+
Pointcloud2d.basePlotModule = require('../../plots/gl2d');
23+
Pointcloud2d.categories = ['gl2d', 'showLegend'];
24+
Pointcloud2d.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 = Pointcloud2d;

0 commit comments

Comments
 (0)