Skip to content

Commit 812be20

Browse files
committed
streamline integration, first pass
1 parent b938842 commit 812be20

File tree

7 files changed

+477
-0
lines changed

7 files changed

+477
-0
lines changed

Diff for: lib/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ Plotly.register([
2727
require('./surface'),
2828
require('./mesh3d'),
2929

30+
require('../src/traces/streamline'),
31+
3032
require('./scattergeo'),
3133
require('./choropleth'),
3234

Diff for: src/traces/streamline/attributes.js

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/**
2+
* Copyright 2012-2018, 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 colorAttrs = require('../../components/colorscale/color_attributes');
12+
var colorscaleAttrs = require('../../components/colorscale/attributes');
13+
var colorbarAttrs = require('../../components/colorbar/attributes');
14+
var mesh3dAttrs = require('../mesh3d/attributes');
15+
var baseAttrs = require('../../plots/attributes');
16+
17+
var extendFlat = require('../../lib/extend').extendFlat;
18+
19+
var attrs = {
20+
x: {
21+
valType: 'data_array',
22+
editType: 'calc',
23+
description: ''
24+
},
25+
y: {
26+
valType: 'data_array',
27+
editType: 'calc'
28+
},
29+
z: {
30+
valType: 'data_array',
31+
editType: 'calc'
32+
},
33+
34+
u: {
35+
valType: 'data_array',
36+
editType: 'calc',
37+
description: [
38+
].join(' ')
39+
},
40+
v: {
41+
valType: 'data_array',
42+
editType: 'calc',
43+
description: [
44+
].join(' ')
45+
46+
},
47+
w: {
48+
valType: 'data_array',
49+
editType: 'calc',
50+
description: [
51+
].join(' ')
52+
53+
},
54+
55+
cx: {
56+
valType: 'data_array',
57+
editType: 'calc+clearAxisTypes',
58+
description: [
59+
].join(' ')
60+
},
61+
cy: {
62+
valType: 'data_array',
63+
editType: 'calc+clearAxisTypes',
64+
description: [
65+
].join(' ')
66+
},
67+
cz: {
68+
valType: 'data_array',
69+
editType: 'calc+clearAxisTypes',
70+
description: [
71+
].join(' ')
72+
},
73+
74+
bounds: {
75+
valType: 'data_array',
76+
editType: 'calc+clearAxisTypes',
77+
description: [
78+
].join(' ')
79+
},
80+
81+
colormap: {
82+
valType: 'string',
83+
role: 'style',
84+
editType: 'calc',
85+
description: [
86+
].join(' ')
87+
},
88+
89+
maxLength: {
90+
valType: 'number',
91+
min: 1,
92+
dflt: 1000,
93+
editType: 'calc',
94+
description: [
95+
].join(' ')
96+
},
97+
98+
widthScale: {
99+
valType: 'number',
100+
role: 'style',
101+
min: 0,
102+
dflt: 0.01,
103+
editType: 'calc',
104+
description: [
105+
].join(' ')
106+
},
107+
108+
// TODO
109+
// sizemode: {},
110+
// sizescale: {},
111+
112+
text: {
113+
valType: 'string',
114+
role: 'info',
115+
dflt: '',
116+
arrayOk: true,
117+
editType: 'calc',
118+
description: [
119+
120+
].join(' ')
121+
}
122+
};
123+
124+
extendFlat(attrs, colorAttrs('', 'calc', false), {
125+
showscale: colorscaleAttrs.showscale,
126+
colorbar: colorbarAttrs
127+
});
128+
129+
var fromMesh3d = ['opacity', 'flatshading', 'lightposition', 'lighting'];
130+
131+
fromMesh3d.forEach(function(k) {
132+
attrs[k] = mesh3dAttrs[k];
133+
});
134+
135+
attrs.hoverinfo = extendFlat({}, baseAttrs.hoverinfo, {editType: 'calc'});
136+
137+
module.exports = attrs;

Diff for: src/traces/streamline/calc.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/**
2+
* Copyright 2012-2018, 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 colorscaleCalc = require('../../components/colorscale/calc');
12+
13+
module.exports = function calc(gd, trace) {
14+
if(trace.intensity) {
15+
colorscaleCalc(trace, trace.intensity, '', 'c');
16+
}
17+
};

Diff for: src/traces/streamline/colorbar.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright 2012-2018, 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 isNumeric = require('fast-isnumeric');
12+
13+
var Lib = require('../../lib');
14+
var Plots = require('../../plots/plots');
15+
var Colorscale = require('../../components/colorscale');
16+
var drawColorbar = require('../../components/colorbar/draw');
17+
18+
module.exports = function colorbar(gd, cd) {
19+
var trace = cd[0].trace,
20+
cbId = 'cb' + trace.uid,
21+
cmin = trace.cmin,
22+
cmax = trace.cmax,
23+
vals = trace.intensity || [];
24+
25+
if(!isNumeric(cmin)) cmin = Lib.aggNums(Math.min, null, vals);
26+
if(!isNumeric(cmax)) cmax = Lib.aggNums(Math.max, null, vals);
27+
28+
gd._fullLayout._infolayer.selectAll('.' + cbId).remove();
29+
30+
if(!trace.showscale) {
31+
Plots.autoMargin(gd, cbId);
32+
return;
33+
}
34+
35+
var cb = cd[0].t.cb = drawColorbar(gd, cbId);
36+
var sclFunc = Colorscale.makeColorScaleFunc(
37+
Colorscale.extractScale(
38+
trace.colorscale,
39+
cmin,
40+
cmax
41+
),
42+
{ noNumericCheck: true }
43+
);
44+
45+
cb.fillcolor(sclFunc)
46+
.filllevels({start: cmin, end: cmax, size: (cmax - cmin) / 254})
47+
.options(trace.colorbar)();
48+
};

Diff for: src/traces/streamline/convert.js

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/**
2+
* Copyright 2012-2018, 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+
Usage example:
11+
12+
var x = [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5];
13+
var y = x, z = x;
14+
var len = x.length * y.length * z.length;
15+
var u=[],v=[],w=[]; for (var i=0; i<len; i++) { u.push(1+Math.sin(i)); v.push(Math.cos(i)); w.push(Math.sin(i*0.3)*0.3); }
16+
var cx=[],cy=[],cz=[]; for (var i=0; i<7; i++) for(var j=0; j<7; j++) { cx.push(-5); cy.push(i-3); cz.push(j-3); }
17+
18+
Plotly.newPlot(gd, [{
19+
type: 'streamline',
20+
cx, cy, cz,
21+
u, v, w,
22+
x, y, z,
23+
bounds: [[-5, -5, -5], [5, 5, 5]],
24+
widthScale: 100,
25+
colormap:'portland'
26+
}], {
27+
scene: {
28+
xaxis: {range: [-5, 5]},
29+
yaxis: {range: [-5, 5]},
30+
zaxis: {range: [-5, 5]}
31+
}
32+
})
33+
34+
*/
35+
36+
37+
38+
'use strict';
39+
40+
var tube2mesh = require('gl-streamtube3d');
41+
var createMesh = tube2mesh.createTubeMesh;
42+
43+
function Mesh3DTrace(scene, mesh, uid) {
44+
this.scene = scene;
45+
this.uid = uid;
46+
this.mesh = mesh;
47+
this.name = '';
48+
this.color = '#fff';
49+
this.data = null;
50+
this.showContour = false;
51+
}
52+
53+
var proto = Mesh3DTrace.prototype;
54+
55+
proto.handlePick = function(selection) {
56+
if(selection.object === this.mesh) {
57+
var selectIndex = selection.index = selection.data.index;
58+
59+
selection.traceCoordinate = [
60+
this.data.x[selectIndex],
61+
this.data.y[selectIndex],
62+
this.data.z[selectIndex]
63+
];
64+
65+
var text = this.data.text;
66+
if(Array.isArray(text) && text[selectIndex] !== undefined) {
67+
selection.textLabel = text[selectIndex];
68+
} else if(text) {
69+
selection.textLabel = text;
70+
}
71+
72+
return true;
73+
}
74+
};
75+
76+
function zip3(x, y, z) {
77+
var result = new Array(x.length);
78+
for(var i = 0; i < x.length; ++i) {
79+
result[i] = [x[i], y[i], z[i]];
80+
}
81+
return result;
82+
}
83+
84+
function convert(scene, trace) {
85+
var layout = scene.fullSceneLayout;
86+
87+
// Unpack position data
88+
function toDataCoords(axis, coord, scale) {
89+
return coord.map(function(x) {
90+
return axis.d2l(x) * scale;
91+
});
92+
}
93+
94+
function min(a) {
95+
var result = a[0];
96+
for (var i=1; i<a.length; i++) {
97+
if (a[i] < result) {
98+
result = a[i];
99+
}
100+
}
101+
return result;
102+
}
103+
104+
function max(a) {
105+
var result = a[0];
106+
for (var i=1; i<a.length; i++) {
107+
if (a[i] > result) {
108+
result = a[i];
109+
}
110+
}
111+
return result;
112+
}
113+
114+
var params = {
115+
startingPositions: zip3(
116+
toDataCoords(layout.xaxis, trace.cx, scene.dataScale[0]),
117+
toDataCoords(layout.yaxis, trace.cy, scene.dataScale[1]),
118+
toDataCoords(layout.zaxis, trace.cz, scene.dataScale[2])
119+
),
120+
meshgrid: [
121+
toDataCoords(layout.xaxis, trace.x, scene.dataScale[0]),
122+
toDataCoords(layout.yaxis, trace.y, scene.dataScale[1]),
123+
toDataCoords(layout.zaxis, trace.z, scene.dataScale[2])
124+
],
125+
vectors: zip3(
126+
toDataCoords(layout.xaxis, trace.u, scene.dataScale[0]),
127+
toDataCoords(layout.yaxis, trace.v, scene.dataScale[1]),
128+
toDataCoords(layout.zaxis, trace.w, scene.dataScale[2])
129+
),
130+
getDivergence: function(np, v, scale) { return scale; },
131+
colormap: trace.colormap,
132+
maxLength: trace.maxLength,
133+
widthScale: trace.widthScale
134+
};
135+
136+
var bounds = trace.bounds || [
137+
[min(trace.x.concat(trace.cx)), min(trace.y.concat(trace.cy)), min(trace.z.concat(trace.cz))],
138+
[max(trace.x.concat(trace.cx)), max(trace.y.concat(trace.cy)), max(trace.z.concat(trace.cz))]
139+
];
140+
141+
bounds = [
142+
[
143+
layout.xaxis.d2l(bounds[0][0]) * scene.dataScale[0],
144+
layout.yaxis.d2l(bounds[0][1]) * scene.dataScale[1],
145+
layout.zaxis.d2l(bounds[0][2]) * scene.dataScale[2]
146+
],
147+
[
148+
layout.xaxis.d2l(bounds[1][0]) * scene.dataScale[0],
149+
layout.yaxis.d2l(bounds[1][1]) * scene.dataScale[1],
150+
layout.zaxis.d2l(bounds[1][2]) * scene.dataScale[2]
151+
],
152+
];
153+
154+
var meshData = tube2mesh(
155+
params,
156+
bounds
157+
);
158+
159+
return meshData;
160+
};
161+
162+
proto.update = function(trace) {
163+
var meshData = convert(trace);
164+
this.mesh.update(meshData);
165+
};
166+
167+
proto.dispose = function() {
168+
this.scene.glplot.remove(this.mesh);
169+
this.mesh.dispose();
170+
};
171+
172+
function createMesh3DTrace(scene, trace) {
173+
var gl = scene.glplot.gl;
174+
var meshData = convert(scene, trace);
175+
var mesh = createMesh(gl, meshData);
176+
var result = new Mesh3DTrace(scene, mesh, trace.uid);
177+
result.data = {hoverinfo: 'skip'};
178+
179+
mesh._trace = result;
180+
scene.glplot.add(mesh);
181+
182+
return result;
183+
}
184+
185+
module.exports = createMesh3DTrace;

0 commit comments

Comments
 (0)