Skip to content

Commit ad9ebda

Browse files
authored
Merge pull request #3469 from plotly/fix0548-surface-contour-all-points
Make surface contour levels configurable
2 parents 866a149 + 1ac97ac commit ad9ebda

File tree

6 files changed

+235
-15
lines changed

6 files changed

+235
-15
lines changed

src/traces/isosurface/attributes.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function makeSliceAttr(axLetter) {
3434
role: 'info',
3535
description: [
3636
'Specifies the location(s) of slices on the axis.',
37-
'When not locations specified slices would be created for',
37+
'When not specified slices would be created for',
3838
'all points of the axis', axLetter, 'except start and end.'
3939
].join(' ')
4040
},

src/traces/surface/attributes.js

+34
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,40 @@ function makeContourAttr(axLetter) {
4444
'dimension are drawn.'
4545
].join(' ')
4646
},
47+
start: {
48+
valType: 'number',
49+
dflt: null,
50+
role: 'style',
51+
editType: 'plot',
52+
// impliedEdits: {'^autocontour': false},
53+
description: [
54+
'Sets the starting contour level value.',
55+
'Must be less than `contours.end`'
56+
].join(' ')
57+
},
58+
end: {
59+
valType: 'number',
60+
dflt: null,
61+
role: 'style',
62+
editType: 'plot',
63+
// impliedEdits: {'^autocontour': false},
64+
description: [
65+
'Sets the end contour level value.',
66+
'Must be more than `contours.start`'
67+
].join(' ')
68+
},
69+
size: {
70+
valType: 'number',
71+
dflt: null,
72+
min: 0,
73+
role: 'style',
74+
editType: 'plot',
75+
// impliedEdits: {'^autocontour': false},
76+
description: [
77+
'Sets the step between each contour level.',
78+
'Must be positive.'
79+
].join(' ')
80+
},
4781
project: {
4882
x: makeContourProjAttr('x'),
4983
y: makeContourProjAttr('y'),

src/traces/surface/convert.js

+54-12
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,15 @@ function SurfaceTrace(scene, surface, uid) {
2828
this.surface = surface;
2929
this.data = null;
3030
this.showContour = [false, false, false];
31+
this.contourStart = [null, null, null];
32+
this.contourEnd = [null, null, null];
33+
this.contourSize = [0, 0, 0];
3134
this.minValues = [Infinity, Infinity, Infinity];
3235
this.maxValues = [-Infinity, -Infinity, -Infinity];
3336
this.dataScaleX = 1.0;
3437
this.dataScaleY = 1.0;
3538
this.refineData = true;
36-
this._interpolatedZ = false;
39+
this.objectOffset = [0, 0, 0];
3740
}
3841

3942
var proto = SurfaceTrace.prototype;
@@ -346,19 +349,54 @@ proto.refineCoords = function(coords) {
346349
}
347350
};
348351

352+
function insertIfNewLevel(arr, newValue) {
353+
var found = false;
354+
for(var k = 0; k < arr.length; k++) {
355+
if(newValue === arr[k]) {
356+
found = true;
357+
break;
358+
}
359+
}
360+
if(found === false) arr.push(newValue);
361+
}
362+
349363
proto.setContourLevels = function() {
350-
var nlevels = [[], [], []];
364+
var newLevels = [[], [], []];
365+
var useNewLevels = [false, false, false];
351366
var needsUpdate = false;
352367

353-
for(var i = 0; i < 3; ++i) {
368+
var i, j, value;
369+
370+
for(i = 0; i < 3; ++i) {
354371
if(this.showContour[i]) {
355372
needsUpdate = true;
356-
nlevels[i] = this.scene.contourLevels[i];
373+
374+
if(
375+
this.contourSize[i] > 0 &&
376+
this.contourStart[i] !== null &&
377+
this.contourEnd[i] !== null &&
378+
this.contourEnd[i] > this.contourStart[i]
379+
) {
380+
useNewLevels[i] = true;
381+
382+
for(j = this.contourStart[i]; j < this.contourEnd[i]; j += this.contourSize[i]) {
383+
value = j * this.scene.dataScale[i];
384+
385+
insertIfNewLevel(newLevels[i], value);
386+
}
387+
}
388+
357389
}
358390
}
359391

360392
if(needsUpdate) {
361-
this.surface.update({ levels: nlevels });
393+
var allLevels = [[], [], []];
394+
for(i = 0; i < 3; ++i) {
395+
if(this.showContour[i]) {
396+
allLevels[i] = useNewLevels[i] ? newLevels[i] : this.scene.contourLevels[i];
397+
}
398+
}
399+
this.surface.update({ levels: allLevels });
362400
}
363401
};
364402

@@ -453,15 +491,15 @@ proto.update = function(data) {
453491
}
454492

455493
for(i = 0; i < 3; i++) {
456-
data._objectOffset[i] = 0.5 * (this.minValues[i] + this.maxValues[i]);
494+
this.objectOffset[i] = 0.5 * (this.minValues[i] + this.maxValues[i]);
457495
}
458496

459497
for(i = 0; i < 3; i++) {
460498
for(j = 0; j < xlen; j++) {
461499
for(k = 0; k < ylen; k++) {
462500
v = rawCoords[i][j][k];
463501
if(v !== null && v !== undefined) {
464-
rawCoords[i][j][k] -= data._objectOffset[i];
502+
rawCoords[i][j][k] -= this.objectOffset[i];
465503
}
466504
}
467505
}
@@ -561,8 +599,16 @@ proto.update = function(data) {
561599
surface.highlightTint[i] = params.contourTint[i] = 1;
562600
}
563601
params.contourWidth[i] = contourParams.width;
602+
603+
this.contourStart[i] = contourParams.start;
604+
this.contourEnd[i] = contourParams.end;
605+
this.contourSize[i] = contourParams.size;
564606
} else {
565607
this.showContour[i] = false;
608+
609+
this.contourStart[i] = null;
610+
this.contourEnd[i] = null;
611+
this.contourSize[i] = 0;
566612
}
567613

568614
if(contourParams.highlight) {
@@ -576,11 +622,7 @@ proto.update = function(data) {
576622
params.vertexColor = true;
577623
}
578624

579-
params.objectOffset = [
580-
data._objectOffset[0],
581-
data._objectOffset[1],
582-
data._objectOffset[2]
583-
];
625+
params.objectOffset = this.objectOffset;
584626

585627
params.coords = coords;
586628
surface.update(params);

src/traces/surface/defaults.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3636
traceOut._xlength = (Array.isArray(x) && Lib.isArrayOrTypedArray(x[0])) ? z.length : z[0].length;
3737
traceOut._ylength = z.length;
3838

39-
traceOut._objectOffset = [0, 0, 0];
40-
4139
var handleCalendarDefaults = Registry.getComponentMethod('calendars', 'handleTraceDefaults');
4240
handleCalendarDefaults(traceIn, traceOut, ['x', 'y', 'z'], layout);
4341

@@ -84,6 +82,10 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
8482
coerce(contourDim + '.highlightcolor');
8583
coerce(contourDim + '.highlightwidth');
8684
}
85+
86+
coerce(contourDim + '.start');
87+
coerce(contourDim + '.end');
88+
coerce(contourDim + '.size');
8789
}
8890

8991
// backward compatibility block
Loading

0 commit comments

Comments
 (0)