Skip to content

Commit 1690cd7

Browse files
committed
implement opacityscale for surface & bug fix for issue 4478
- new gl-surface3d that supports opacityscale - move opacityscale logic from volume to surface in plotly.js - add new image tests for surface with opacityscale and opacity - update old surface baselines i.e. remove extra transparency issue 4478
1 parent f89a5ae commit 1690cd7

18 files changed

+1727
-72
lines changed

package-lock.json

+2-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"gl-select-box": "^1.0.3",
8989
"gl-spikes2d": "^1.0.2",
9090
"gl-streamtube3d": "^1.4.0",
91-
"gl-surface3d": "^1.4.6",
91+
"gl-surface3d": "git://github.com/gl-vis/gl-surface3d.git#f42163793d1ef167358363f2264c5318bac8ceaa",
9292
"gl-text": "^1.1.8",
9393
"glslify": "^7.0.0",
9494
"has-hover": "^1.0.1",

src/traces/surface/attributes.js

+18
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,24 @@ colorScaleAttrs('', {
298298
].join(' ')
299299
},
300300

301+
opacityscale: {
302+
valType: 'any',
303+
role: 'style',
304+
editType: 'calc',
305+
description: [
306+
'Sets the opacityscale.',
307+
' The opacityscale must be an array containing',
308+
' arrays mapping a normalized value to an opacity value.',
309+
' At minimum, a mapping for the lowest (0) and highest (1)',
310+
' values are required. For example,',
311+
' `[[0, 1], [0.5, 0.2], [1, 1]]` means that higher/lower values would have',
312+
' higher opacity values and those in the middle would be more transparent',
313+
' Alternatively, `opacityscale` may be a palette name string',
314+
' of the following list: \'min\', \'max\', \'extremes\' and \'uniform\'.',
315+
' The default is \'uniform\'.'
316+
].join('')
317+
},
318+
301319
_deprecated: {
302320
zauto: extendFlat({}, colorScaleAttrs.zauto, {
303321
description: 'Obsolete. Use `cauto` instead.'

src/traces/surface/convert.js

+1
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ proto.update = function(data) {
532532
dynamicColor: [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]],
533533
dynamicWidth: [1, 1, 1],
534534
dynamicTint: [1, 1, 1],
535+
opacityscale: data.opacityscale,
535536
opacity: data.opacity
536537
};
537538

src/traces/surface/defaults.js

+60-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,45 @@ var Lib = require('../../lib');
1414
var colorscaleDefaults = require('../../components/colorscale/defaults');
1515
var attributes = require('./attributes');
1616

17-
module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
17+
var MIN = 0.1; // Note: often we don't want the data cube to be disappeared
18+
19+
function createWave(n, minOpacity) {
20+
var arr = [];
21+
var steps = 32; // Max: 256
22+
for(var i = 0; i < steps; i++) {
23+
var u = i / (steps - 1);
24+
var v = minOpacity + (1 - minOpacity) * (1 - Math.pow(Math.sin(n * u * Math.PI), 2));
25+
arr.push([
26+
u,
27+
Math.max(1, Math.min(0, v))
28+
]);
29+
}
30+
return arr;
31+
}
32+
33+
function isValidScaleArray(scl) {
34+
var highestVal = 0;
35+
36+
if(!Array.isArray(scl) || scl.length < 2) return false;
37+
38+
if(!scl[0] || !scl[scl.length - 1]) return false;
39+
40+
if(+scl[0][0] !== 0 || +scl[scl.length - 1][0] !== 1) return false;
41+
42+
for(var i = 0; i < scl.length; i++) {
43+
var si = scl[i];
44+
45+
if(si.length !== 2 || +si[0] < highestVal) {
46+
return false;
47+
}
48+
49+
highestVal = +si[0];
50+
}
51+
52+
return true;
53+
}
54+
55+
function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
1856
var i, j;
1957

2058
function coerce(attr, dflt) {
@@ -102,13 +140,33 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
102140
traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'}
103141
);
104142

143+
opacityscaleDefaults(traceIn, traceOut, layout, coerce);
144+
105145
// disable 1D transforms - currently surface does NOT support column data like heatmap does
106146
// you can use mesh3d for this use case, but not surface
107147
traceOut._length = null;
108-
};
148+
}
149+
150+
function opacityscaleDefaults(traceIn, traceOut, layout, coerce) {
151+
var opacityscale = coerce('opacityscale');
152+
if(opacityscale === 'max') {
153+
traceOut.opacityscale = [[0, MIN], [1, 1]];
154+
} else if(opacityscale === 'min') {
155+
traceOut.opacityscale = [[0, 1], [1, MIN]];
156+
} else if(opacityscale === 'extremes') {
157+
traceOut.opacityscale = createWave(1, MIN);
158+
} else if(!isValidScaleArray(opacityscale)) {
159+
traceOut.opacityscale = undefined;
160+
}
161+
}
109162

110163
function mapLegacy(traceIn, oldAttr, newAttr) {
111164
if(oldAttr in traceIn && !(newAttr in traceIn)) {
112165
traceIn[newAttr] = traceIn[oldAttr];
113166
}
114167
}
168+
169+
module.exports = {
170+
supplyDefaults: supplyDefaults,
171+
opacityscaleDefaults: opacityscaleDefaults
172+
};

src/traces/surface/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
module.exports = {
1212
attributes: require('./attributes'),
13-
supplyDefaults: require('./defaults'),
13+
supplyDefaults: require('./defaults').supplyDefaults,
1414
colorbar: {
1515
min: 'cmin',
1616
max: 'cmax'

src/traces/volume/attributes.js

+2-17
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
var colorScaleAttrs = require('../../components/colorscale/attributes');
1212
var isosurfaceAttrs = require('../isosurface/attributes');
13+
var surfaceAttrs = require('../surface/attributes');
1314
var baseAttrs = require('../../plots/attributes');
1415

1516
var extendFlat = require('../../lib/extend').extendFlat;
@@ -63,23 +64,7 @@ colorScaleAttrs('', {
6364

6465
colorbar: isosurfaceAttrs.colorbar,
6566
opacity: isosurfaceAttrs.opacity,
66-
opacityscale: {
67-
valType: 'any',
68-
role: 'style',
69-
editType: 'calc',
70-
description: [
71-
'Sets the opacityscale.',
72-
' The opacityscale must be an array containing',
73-
' arrays mapping a normalized value to an opacity value.',
74-
' At minimum, a mapping for the lowest (0) and highest (1)',
75-
' values are required. For example,',
76-
' `[[0, 1], [0.5, 0.2], [1, 1]]` means that higher/lower values would have',
77-
' higher opacity values and those in the middle would be more transparent',
78-
' Alternatively, `opacityscale` may be a palette name string',
79-
' of the following list: \'min\', \'max\', \'extremes\' and \'uniform\'.',
80-
' The default is \'uniform\'.'
81-
].join('')
82-
},
67+
opacityscale: surfaceAttrs.opacityscale,
8368

8469
lightposition: isosurfaceAttrs.lightposition,
8570
lighting: isosurfaceAttrs.lighting,

src/traces/volume/defaults.js

+2-48
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,7 @@
1111
var Lib = require('../../lib');
1212
var attributes = require('./attributes');
1313
var supplyIsoDefaults = require('../isosurface/defaults').supplyIsoDefaults;
14-
15-
var MIN = 0.1; // Note: often we don't want the data cube to be disappeared
16-
17-
function createWave(n, minOpacity) {
18-
var arr = [];
19-
var steps = 32; // Max: 256
20-
for(var i = 0; i < steps; i++) {
21-
var u = i / (steps - 1);
22-
var v = minOpacity + (1 - minOpacity) * (1 - Math.pow(Math.sin(n * u * Math.PI), 2));
23-
arr.push([
24-
u,
25-
Math.max(1, Math.min(0, v))
26-
]);
27-
}
28-
return arr;
29-
}
14+
var opacityscaleDefaults = require('../surface/defaults').opacityscaleDefaults;
3015

3116
module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
3217
function coerce(attr, dflt) {
@@ -35,36 +20,5 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3520

3621
supplyIsoDefaults(traceIn, traceOut, defaultColor, layout, coerce);
3722

38-
var opacityscale = coerce('opacityscale');
39-
if(opacityscale === 'max') {
40-
traceOut.opacityscale = [[0, MIN], [1, 1]];
41-
} else if(opacityscale === 'min') {
42-
traceOut.opacityscale = [[0, 1], [1, MIN]];
43-
} else if(opacityscale === 'extremes') {
44-
traceOut.opacityscale = createWave(1, MIN);
45-
} else if(!isValidScaleArray(opacityscale)) {
46-
traceOut.opacityscale = undefined;
47-
}
23+
opacityscaleDefaults(traceIn, traceOut, layout, coerce);
4824
};
49-
50-
function isValidScaleArray(scl) {
51-
var highestVal = 0;
52-
53-
if(!Array.isArray(scl) || scl.length < 2) return false;
54-
55-
if(!scl[0] || !scl[scl.length - 1]) return false;
56-
57-
if(+scl[0][0] !== 0 || +scl[scl.length - 1][0] !== 1) return false;
58-
59-
for(var i = 0; i < scl.length; i++) {
60-
var si = scl[i];
61-
62-
if(si.length !== 2 || +si[0] < highestVal) {
63-
return false;
64-
}
65-
66-
highestVal = +si[0];
67-
}
68-
69-
return true;
70-
}
-2.4 KB
Loading
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)