Skip to content

Add surfacecolor functionality to surface traces #347

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Mar 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
93f1781
Merge remote-tracking branch 'upstream/master'
mikolalysenko Mar 3, 2016
00109fd
Add surface intensity parameter
mikolalysenko Mar 4, 2016
52ab89c
rename zmin,zmax,zauto,intensity to cmin,cmax,cauto,surfacecolor
mikolalysenko Mar 10, 2016
4c4db95
upgrade gl-surface3d
mikolalysenko Mar 10, 2016
cf23c09
fix linter errors
mikolalysenko Mar 10, 2016
7f1371e
add baseline image for surface intensity test
mikolalysenko Mar 11, 2016
d7a3fe1
Merge remote-tracking branch 'upstream/master'
mikolalysenko Mar 15, 2016
e8b944d
Merge branch 'master' into surface-intensity
mikolalysenko Mar 15, 2016
70b31cc
fix issue with color levels being computed incorrectly
mikolalysenko Mar 16, 2016
78600b9
add test images
mikolalysenko Mar 16, 2016
608a706
fix path to image in gl3d test dashboard
etpinard Mar 17, 2016
3c26428
create choropleth-only calc step (can no longer re-use surface's)
etpinard Mar 17, 2016
b6d2a15
mv zmin/zmax/zauto backward compat mappings in surface defaults:
etpinard Mar 17, 2016
9d03cbf
bring back old 'zmin'/'zmax' mock
etpinard Mar 17, 2016
04a7f47
add 'cmin' and 'cmax' to surface intensity mock
etpinard Mar 17, 2016
579dcb2
pass cmin and cmax to gl-surface3d:
etpinard Mar 17, 2016
76a627e
move png baselines to baselines/
etpinard Mar 17, 2016
861197b
bring old baselines
etpinard Mar 17, 2016
63ea534
lint
etpinard Mar 21, 2016
863a6f5
bump gl-surface3d requirement
etpinard Mar 21, 2016
b07c429
update baselines
etpinard Mar 21, 2016
bf2658a
add surface defaults tests
etpinard Mar 21, 2016
15354d2
improve surface attribute descriptions
etpinard Mar 22, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion devtools/test_dashboard/test_gl3d.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ plots['marker-arrays'] = require('@mocks/gl3d_marker-arrays.json');
plots['scatter3d-colorscale'] = require('@mocks/gl3d_scatter3d-colorscale.json');
plots['autocolorscale'] = require('@mocks/gl3d_autocolorscale.json');
plots['nan-holes'] = require('@mocks/gl3d_nan-holes.json');
plots['tetrahedra'] = require('@mocks/gl3d_tet.json');
plots['tet'] = require('@mocks/gl3d_tet.json');
plots['surface_intensity'] = require('@mocks/gl3d_surface_intensity.json');

plotButtons(plots, figDir);
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"gl-scatter3d": "^1.0.4",
"gl-select-box": "^1.0.1",
"gl-spikes2d": "^1.0.1",
"gl-surface3d": "^1.1.1",
"gl-surface3d": "^1.2.3",
"mouse-change": "^1.1.1",
"mouse-wheel": "^1.0.2",
"ndarray": "^1.0.16",
Expand Down
17 changes: 17 additions & 0 deletions src/traces/choropleth/calc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var colorscaleCalc = require('../../components/colorscale/calc');


module.exports = function calc(gd, trace) {
colorscaleCalc(trace, trace.z, '', 'z');
};
2 changes: 1 addition & 1 deletion src/traces/choropleth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var Choropleth = {};
Choropleth.attributes = require('./attributes');
Choropleth.supplyDefaults = require('./defaults');
Choropleth.colorbar = require('../heatmap/colorbar');
Choropleth.calc = require('../surface/calc');
Choropleth.calc = require('./calc');
Choropleth.plot = require('./plot').plot;

Choropleth.moduleType = 'trace';
Expand Down
25 changes: 22 additions & 3 deletions src/traces/surface/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,16 @@ module.exports = {
valType: 'data_array',
description: 'Sets the text elements associated with each z value.'
},
zauto: colorscaleAttrs.zauto,
zmin: colorscaleAttrs.zmin,
zmax: colorscaleAttrs.zmax,
surfacecolor: {
valType: 'data_array',
description: [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a more descriptive description? I'm still a little unclear on how this is used.

'Sets the surface color values,',
'used for setting a color scale independent of `z`.'
].join(' ')
},
cauto: colorscaleAttrs.zauto,
cmin: colorscaleAttrs.zmin,
cmax: colorscaleAttrs.zmax,
colorscale: colorscaleAttrs.colorscale,
autocolorscale: extendFlat({}, colorscaleAttrs.autocolorscale,
{dflt: false}),
Expand Down Expand Up @@ -161,5 +168,17 @@ module.exports = {

_nestedModules: { // nested module coupling
'colorbar': 'Colorbar'
},

_deprecated: {
zauto: extendFlat({}, colorscaleAttrs.zauto, {
description: 'Obsolete. Use `cauto` instead.'
}),
zmin: extendFlat({}, colorscaleAttrs.zmin, {
description: 'Obsolete. Use `cmin` instead.'
}),
zmax: extendFlat({}, colorscaleAttrs.zmax, {
description: 'Obsolete. Use `cmax` instead.'
})
}
};
6 changes: 5 additions & 1 deletion src/traces/surface/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ var colorscaleCalc = require('../../components/colorscale/calc');

// Compute auto-z and autocolorscale if applicable
module.exports = function calc(gd, trace) {
colorscaleCalc(trace, trace.z, '', 'z');
if(trace.surfacecolor) {
colorscaleCalc(trace, trace.surfacecolor, '', 'c');
} else {
colorscaleCalc(trace, trace.z, '', 'c');
}
};
47 changes: 47 additions & 0 deletions src/traces/surface/colorbar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var d3 = require('d3');
var isNumeric = require('fast-isnumeric');

var Lib = require('../../lib');
var Plots = require('../../plots/plots');
var getColorscale = require('../../components/colorscale/get_scale');
var drawColorbar = require('../../components/colorbar/draw');


module.exports = function colorbar(gd, cd) {
var trace = cd[0].trace,
cbId = 'cb' + trace.uid,
scl = getColorscale(trace.colorscale),
zmin = trace.cmin,
zmax = trace.cmax,
vals = trace.surfacecolor || trace.z;

if(!isNumeric(zmin)) zmin = Lib.aggNums(Math.min, null, vals);
if(!isNumeric(zmax)) zmax = Lib.aggNums(Math.max, null, vals);

gd._fullLayout._infolayer.selectAll('.' + cbId).remove();

if(!trace.showscale) {
Plots.autoMargin(gd, cbId);
return;
}

var cb = cd[0].t.cb = drawColorbar(gd, cbId);
cb.fillcolor(d3.scale.linear()
.domain(scl.map(function(v) { return zmin + v[0]*(zmax-zmin); }))
.range(scl.map(function(v) { return v[1]; })))
.filllevels({start: zmin, end: zmax, size: (zmax-zmin)/254})
.options(trace.colorbar)();

Lib.markTime('done colorbar');
};
34 changes: 27 additions & 7 deletions src/traces/surface/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ var str2RgbaArray = require('../../lib/str2rgbarray');

var MIN_RESOLUTION = 128;


function SurfaceTrace(scene, surface, uid) {
this.scene = scene;
this.uid = uid;
Expand Down Expand Up @@ -136,7 +135,7 @@ function refine(coords) {
Math.floor((coords[0].shape[1]) * scaleF+1)|0 ];
var nsize = nshape[0] * nshape[1];

for(var i = 0; i < 3; ++i) {
for(var i = 0; i < coords.length; ++i) {
var padImg = padField(coords[i]);
var scaledImg = ndarray(new Float32Array(nsize), nshape);
homography(scaledImg, padImg, [scaleF, 0, 0,
Expand Down Expand Up @@ -230,9 +229,6 @@ proto.update = function(data) {
});
}

//Refine if necessary
this.dataScale = refine(coords);

var params = {
colormap: colormap,
levels: [[], [], []],
Expand All @@ -249,10 +245,33 @@ proto.update = function(data) {
dynamicColor: [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]],
dynamicWidth: [1, 1, 1],
dynamicTint: [1, 1, 1],
opacity: 1,
colorBounds: [data.zmin * scaleFactor[2], data.zmax * scaleFactor[2]]
opacity: 1
};

params.intensityBounds = [data.cmin, data.cmax];

//Refine if necessary
if(data.surfacecolor) {
var intensity = ndarray(new Float32Array(xlen * ylen), [xlen, ylen]);

fill(intensity, function(row, col) {
return data.surfacecolor[col][row];
});

coords.push(intensity);
}
else {
// when 'z' is used as 'intensity',
// we must scale its value
params.intensityBounds[0] *= scaleFactor[2];
params.intensityBounds[1] *= scaleFactor[2];
}

this.dataScale = refine(coords);

if(data.surfacecolor) {
params.intensity = coords.pop();
}

if('opacity' in data) {
if(data.opacity < 1) {
Expand Down Expand Up @@ -300,6 +319,7 @@ proto.update = function(data) {
}

params.coords = coords;

surface.update(params);

surface.highlightEnable = highlightEnable;
Expand Down
17 changes: 16 additions & 1 deletion src/traces/surface/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
coerce('hidesurface');
coerce('opacity');

var surfaceColor = coerce('surfacecolor');

coerce('colorscale');

var dims = ['x', 'y', 'z'];
Expand Down Expand Up @@ -85,7 +87,20 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
}
}

// backward compatibility block
if(!surfaceColor) {
mapLegacy(traceIn, 'zmin', 'cmin');
mapLegacy(traceIn, 'zmax', 'cmax');
mapLegacy(traceIn, 'zauto', 'cauto');
}

colorscaleDefaults(
traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'}
traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'}
);
};

function mapLegacy(traceIn, oldAttr, newAttr) {
if(oldAttr in traceIn && !(newAttr in traceIn)) {
traceIn[newAttr] = traceIn[oldAttr];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdtusz @cldougl @chriddyp Are you ok with this way of preserving backward compatibility?

zmin, zmax and zauto are deprecated in favour of cmin, cmax and cauto for surface traces.

The deprecated z attributes are mapped to their corresponding c attributes in the defaults step so that both plot and restyle call update the trace objects to the c attributes.

If both a c and z attribute are present, only the c attribute is coerced.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep I'm ok with this. Ideally we would/should be able to remove the oldAttr from traceIn as well, but I imagine that may cause problems if there are other components that make use of it somewhere still.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I imagine that may cause problems if there are other components that make use of it somewhere still.

Exactly. That's why I took the conservative route here. We'll clean this up in v2.0.0 🎉 .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok for me

}
}
8 changes: 6 additions & 2 deletions src/traces/surface/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var Surface = {};

Surface.attributes = require('./attributes');
Surface.supplyDefaults = require('./defaults');
Surface.colorbar = require('../heatmap/colorbar');
Surface.colorbar = require('./colorbar');
Surface.calc = require('./calc');
Surface.plot = require('./convert');

Expand All @@ -30,7 +30,11 @@ Surface.meta = {
'or {2D arrays} (e.g. to graph parametric surfaces).',

'If not provided in `x` and `y`, the x and y coordinates are assumed',
'to be linear starting at 0 with a unit step.'
'to be linear starting at 0 with a unit step.',

'The color scale corresponds to the `z` values by default.',
'For custom color scales, use `surfacecolor` which should be a {2D array},',
'where its bounds can be controlled using `cmin` and `cmax`.'
].join(' ')
};

Expand Down
Binary file modified test/image/baselines/gl3d_autocolorscale.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/image/baselines/gl3d_contour-lines.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading