Skip to content

Commit 83f3bdc

Browse files
committed
improve auto starting position algo
1 parent 9e3c533 commit 83f3bdc

File tree

2 files changed

+102
-18
lines changed

2 files changed

+102
-18
lines changed

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

+26-18
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ function distinctVals(col) {
6565
return Lib.distinctVals(col).vals;
6666
}
6767

68+
function getDfltStartingPositions(vec) {
69+
var len = vec.length;
70+
var s;
71+
72+
if(len > 2) {
73+
s = vec.slice(1, len - 1);
74+
} else if(len === 2) {
75+
s = [(vec[0] + vec[1]) / 2];
76+
} else {
77+
s = vec;
78+
}
79+
return s;
80+
}
81+
6882
function getBoundPads(vec) {
6983
var len = vec.length;
7084
if(len === 1) {
@@ -116,30 +130,24 @@ function convert(scene, trace) {
116130
toDataCoords(trace.starts.z.slice(0, slen), 'zaxis')
117131
);
118132
} else {
119-
// Default starting positions: cut xz plane at min-y,
133+
// Default starting positions:
134+
//
135+
// if len>2, cut xz plane at min-y,
120136
// takes all x/y/z pts on that plane except those on the edges
121-
// to generate "well-defined" tubes
122-
var sy0 = sceneLayout.yaxis.d2l(trace._ybnds[0]) * dataScale[1];
123-
var sx, sz;
124-
if(valsx.length > 2 && valsz.length > 2) {
125-
sx = valsx.slice(1, valsx.length - 1);
126-
sz = valsz.slice(1, valsy.length - 1);
127-
} else {
128-
// use all pts on 2x2 and 1x1 planes
129-
sx = valsx.slice();
130-
sz = valsz.slice();
131-
}
132-
137+
// to generate "well-defined" tubes,
138+
//
139+
// if len=2, take position halfway between two the pts,
140+
//
141+
// if len=1, take that pt
142+
var sy0 = meshy[0];
143+
var sx = getDfltStartingPositions(meshx);
144+
var sz = getDfltStartingPositions(meshz);
133145
var startingPositions = new Array(sx.length * sz.length);
134146
var m = 0;
135147

136148
for(var i = 0; i < sx.length; i++) {
137149
for(var k = 0; k < sz.length; k++) {
138-
startingPositions[m++] = [
139-
sceneLayout.xaxis.d2l(sx[i]) * dataScale[0],
140-
sy0,
141-
sceneLayout.zaxis.d2l(sz[k]) * dataScale[2]
142-
];
150+
startingPositions[m++] = [sx[i], sy0, sz[k]];
143151
}
144152
}
145153
tubeOpts.startingPositions = startingPositions;

Diff for: test/jasmine/tests/streamtube_test.js

+76
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,82 @@ describe('@gl Test streamtube autorange', function() {
105105
});
106106
});
107107

108+
describe('@gl Test streamtube starting positions defaults:', function() {
109+
var gd;
110+
111+
beforeEach(function() {
112+
gd = createGraphDiv();
113+
});
114+
115+
afterEach(function() {
116+
Plotly.purge(gd);
117+
destroyGraphDiv();
118+
});
119+
120+
function makeFigure(nx, ny, nz) {
121+
var trace = {
122+
type: 'streamtube',
123+
x: [], y: [], z: [],
124+
u: [], v: [], w: []
125+
};
126+
127+
for(var i = 0; i < nx; i++) {
128+
for(var j = 0; j < ny; j++) {
129+
for(var k = 0; k < nz; k++) {
130+
trace.x.push(i);
131+
trace.y.push(j);
132+
trace.z.push(k);
133+
trace.u.push(1 + Math.sin(i));
134+
trace.v.push(Math.cos(j));
135+
trace.w.push(0.3 * Math.sin(k * 0.3));
136+
}
137+
}
138+
}
139+
140+
return {data: [trace]};
141+
}
142+
143+
function _assert(exp) {
144+
var scene = gd._fullLayout.scene._scene;
145+
var obj = scene.glplot.objects[0];
146+
expect(exp.positionsLength).toBe(obj.positions.length, 'positions length');
147+
expect(exp.cellsLength).toBe(obj.cells.length, 'cells length');
148+
}
149+
150+
it('should cut xz at min-y and take all x/y/z pts on that plane except those on the edges', function(done) {
151+
Plotly.plot(gd, makeFigure(3, 3, 3)).then(function() {
152+
_assert({
153+
positionsLength: 1536,
154+
cellsLength: 512
155+
});
156+
})
157+
.catch(failTest)
158+
.then(done);
159+
});
160+
161+
it('should take middle pt if mesh vector has length 2', function(done) {
162+
Plotly.plot(gd, makeFigure(3, 3, 2)).then(function() {
163+
_assert({
164+
positionsLength: 1200,
165+
cellsLength: 400
166+
});
167+
})
168+
.catch(failTest)
169+
.then(done);
170+
});
171+
172+
it('should take pt if mesh vector has length 1', function(done) {
173+
Plotly.plot(gd, makeFigure(1, 3, 2)).then(function() {
174+
_assert({
175+
positionsLength: 720,
176+
cellsLength: 240
177+
});
178+
})
179+
.catch(failTest)
180+
.then(done);
181+
});
182+
});
183+
108184
describe('@gl Test streamtube interactions', function() {
109185
var gd;
110186

0 commit comments

Comments
 (0)