diff --git a/devtools/test_dashboard/test_gl3d.js b/devtools/test_dashboard/test_gl3d.js index dce47915ce0..4cb2ed9bd48 100644 --- a/devtools/test_dashboard/test_gl3d.js +++ b/devtools/test_dashboard/test_gl3d.js @@ -36,5 +36,6 @@ 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['surface-intensity'] = require('@mocks/gl3d_surface_intensity.json'); plotButtons(plots, figDir); diff --git a/package.json b/package.json index 8fd5469086b..85b0109351a 100644 --- a/package.json +++ b/package.json @@ -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.2", "mouse-change": "^1.1.1", "mouse-wheel": "^1.0.2", "ndarray": "^1.0.16", diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index 1753264abf2..60c34ffecb9 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -761,6 +761,11 @@ function cleanData(data, existingData) { if(cont.colorscale === 'YIGnBu') cont.colorscale = 'YlGnBu'; if(cont.colorscale === 'YIOrRd') cont.colorscale = 'YlOrRd'; } + if(Plots.traceIs(trace, 'surface')) { + if('zmin' in trace) trace.cmin = trace.zmin; + if('zmax' in trace) trace.cmax = trace.zmax; + if('zauto' in trace) trace.cauto = trace.zauto; + } // prune empty containers made before the new nestedProperty if(emptyContainer(trace, 'line')) delete trace.line; diff --git a/src/traces/surface/attributes.js b/src/traces/surface/attributes.js index b8af834d412..479f9f71e09 100644 --- a/src/traces/surface/attributes.js +++ b/src/traces/surface/attributes.js @@ -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: [ + 'Sets the surface intensity 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}), @@ -161,5 +168,11 @@ module.exports = { _nestedModules: { // nested module coupling 'colorbar': 'Colorbar' + }, + + _deprecated: { + zauto: colorscaleAttrs.zauto, + zmin: colorscaleAttrs.zmin, + zmax: colorscaleAttrs.zmax } }; diff --git a/src/traces/surface/calc.js b/src/traces/surface/calc.js index d6137f6d5fb..4ac8bc03d2d 100644 --- a/src/traces/surface/calc.js +++ b/src/traces/surface/calc.js @@ -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'); + } }; diff --git a/src/traces/surface/colorbar.js b/src/traces/surface/colorbar.js new file mode 100644 index 00000000000..26d1fd475f5 --- /dev/null +++ b/src/traces/surface/colorbar.js @@ -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'); +}; diff --git a/src/traces/surface/convert.js b/src/traces/surface/convert.js index 3097561dc2b..290657f370b 100644 --- a/src/traces/surface/convert.js +++ b/src/traces/surface/convert.js @@ -20,7 +20,6 @@ var str2RgbaArray = require('../../lib/str2rgbarray'); var MIN_RESOLUTION = 128; - function SurfaceTrace(scene, surface, uid) { this.scene = scene; this.uid = uid; @@ -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, @@ -230,9 +229,6 @@ proto.update = function(data) { }); } - //Refine if necessary - this.dataScale = refine(coords); - var params = { colormap: colormap, levels: [[], [], []], @@ -249,10 +245,24 @@ 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 }; + //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); + } + + this.dataScale = refine(coords); + + if(data.surfacecolor) { + params.intensity = coords.pop(); + } if('opacity' in data) { if(data.opacity < 1) { @@ -300,6 +310,7 @@ proto.update = function(data) { } params.coords = coords; + surface.update(params); surface.highlightEnable = highlightEnable; diff --git a/src/traces/surface/defaults.js b/src/traces/surface/defaults.js index 653b9df5638..7894eb46d02 100644 --- a/src/traces/surface/defaults.js +++ b/src/traces/surface/defaults.js @@ -58,6 +58,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout coerce('hidesurface'); coerce('opacity'); + coerce('surfacecolor'); + coerce('colorscale'); var dims = ['x', 'y', 'z']; @@ -86,6 +88,6 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout } colorscaleDefaults( - traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'} + traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'} ); }; diff --git a/src/traces/surface/index.js b/src/traces/surface/index.js index 9a3c5795f16..11cfbc6bd20 100644 --- a/src/traces/surface/index.js +++ b/src/traces/surface/index.js @@ -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'); diff --git a/test/image/baselines/gl3d_surface_intensity.png b/test/image/baselines/gl3d_surface_intensity.png new file mode 100644 index 00000000000..cc7797b85cb Binary files /dev/null and b/test/image/baselines/gl3d_surface_intensity.png differ diff --git a/test/image/mocks/gl3d_autocolorscale.json b/test/image/mocks/gl3d_autocolorscale.json index 743cb6149a5..491b0ffe1dc 100644 --- a/test/image/mocks/gl3d_autocolorscale.json +++ b/test/image/mocks/gl3d_autocolorscale.json @@ -25,8 +25,8 @@ ["zero two", "one two", "two two"] ], "autocolorscale": true, - "zmin": 0, - "zmax": "50" + "cmin": 0, + "cmax": "50" } ], "layout": { diff --git a/test/image/mocks/gl3d_autocolorscale.png b/test/image/mocks/gl3d_autocolorscale.png new file mode 100644 index 00000000000..6fc121e7845 Binary files /dev/null and b/test/image/mocks/gl3d_autocolorscale.png differ diff --git a/test/image/mocks/gl3d_chrisp-nan-1.png b/test/image/mocks/gl3d_chrisp-nan-1.png new file mode 100644 index 00000000000..e394d258779 Binary files /dev/null and b/test/image/mocks/gl3d_chrisp-nan-1.png differ diff --git a/test/image/mocks/gl3d_contour-lines.png b/test/image/mocks/gl3d_contour-lines.png new file mode 100644 index 00000000000..a33f8bb82c0 Binary files /dev/null and b/test/image/mocks/gl3d_contour-lines.png differ diff --git a/test/image/mocks/gl3d_cufflinks.png b/test/image/mocks/gl3d_cufflinks.png new file mode 100644 index 00000000000..25e3f05ead3 Binary files /dev/null and b/test/image/mocks/gl3d_cufflinks.png differ diff --git a/test/image/mocks/gl3d_surface-lighting.png b/test/image/mocks/gl3d_surface-lighting.png new file mode 100644 index 00000000000..2def5a05890 Binary files /dev/null and b/test/image/mocks/gl3d_surface-lighting.png differ diff --git a/test/image/mocks/gl3d_surface_intensity.json b/test/image/mocks/gl3d_surface_intensity.json new file mode 100644 index 00000000000..83f22028b9d --- /dev/null +++ b/test/image/mocks/gl3d_surface_intensity.json @@ -0,0 +1,254 @@ +{ + "data": [ + { + "z": [ + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1 + ], + [ + 0.955336489125606, + 0.955336489125606, + 0.955336489125606, + 0.955336489125606, + 0.955336489125606, + 0.955336489125606, + 0.955336489125606, + 0.955336489125606, + 0.955336489125606, + 0.955336489125606 + ], + [ + 0.8253356149096783, + 0.8253356149096783, + 0.8253356149096783, + 0.8253356149096783, + 0.8253356149096783, + 0.8253356149096783, + 0.8253356149096783, + 0.8253356149096783, + 0.8253356149096783, + 0.8253356149096783 + ], + [ + 0.6216099682706645, + 0.6216099682706645, + 0.6216099682706645, + 0.6216099682706645, + 0.6216099682706645, + 0.6216099682706645, + 0.6216099682706645, + 0.6216099682706645, + 0.6216099682706645, + 0.6216099682706645 + ], + [ + 0.3623577544766736, + 0.3623577544766736, + 0.3623577544766736, + 0.3623577544766736, + 0.3623577544766736, + 0.3623577544766736, + 0.3623577544766736, + 0.3623577544766736, + 0.3623577544766736, + 0.3623577544766736 + ], + [ + 0.0707372016677029, + 0.0707372016677029, + 0.0707372016677029, + 0.0707372016677029, + 0.0707372016677029, + 0.0707372016677029, + 0.0707372016677029, + 0.0707372016677029, + 0.0707372016677029, + 0.0707372016677029 + ], + [ + -0.2272020946930869, + -0.2272020946930869, + -0.2272020946930869, + -0.2272020946930869, + -0.2272020946930869, + -0.2272020946930869, + -0.2272020946930869, + -0.2272020946930869, + -0.2272020946930869, + -0.2272020946930869 + ], + [ + -0.5048461045998576, + -0.5048461045998576, + -0.5048461045998576, + -0.5048461045998576, + -0.5048461045998576, + -0.5048461045998576, + -0.5048461045998576, + -0.5048461045998576, + -0.5048461045998576, + -0.5048461045998576 + ], + [ + -0.7373937155412454, + -0.7373937155412454, + -0.7373937155412454, + -0.7373937155412454, + -0.7373937155412454, + -0.7373937155412454, + -0.7373937155412454, + -0.7373937155412454, + -0.7373937155412454, + -0.7373937155412454 + ], + [ + -0.904072142017061, + -0.904072142017061, + -0.904072142017061, + -0.904072142017061, + -0.904072142017061, + -0.904072142017061, + -0.904072142017061, + -0.904072142017061, + -0.904072142017061, + -0.904072142017061 + ] + ], + "surfacecolor": [ + [ + 10, + 9, + 8, + 7, + 6, + 5, + 6, + 7, + 8, + 9 + ], + [ + 9, + 8, + 7, + 6, + 5, + 4, + 5, + 6, + 7, + 8 + ], + [ + 8, + 7, + 6, + 5, + 4, + 3, + 4, + 5, + 6, + 7 + ], + [ + 7, + 6, + 5, + 4, + 3, + 2, + 3, + 4, + 5, + 6 + ], + [ + 6, + 5, + 4, + 3, + 2, + 1, + 2, + 3, + 4, + 5 + ], + [ + 5, + 4, + 3, + 2, + 1, + 0, + 1, + 2, + 3, + 4 + ], + [ + 6, + 5, + 4, + 3, + 2, + 1, + 2, + 3, + 4, + 5 + ], + [ + 7, + 6, + 5, + 4, + 3, + 2, + 3, + 4, + 5, + 6 + ], + [ + 8, + 7, + 6, + 5, + 4, + 3, + 4, + 5, + 6, + 7 + ], + [ + 9, + 8, + 7, + 6, + 5, + 4, + 5, + 6, + 7, + 8 + ] + ], + "type": "surface" + } + ], + "layout": { + "title": "Surface intensity test" + } +} diff --git a/test/image/mocks/gl3d_surface_intensity.png b/test/image/mocks/gl3d_surface_intensity.png new file mode 100644 index 00000000000..b52332217b0 Binary files /dev/null and b/test/image/mocks/gl3d_surface_intensity.png differ diff --git a/test/image/mocks/gl3d_xy-defined-ticks.png b/test/image/mocks/gl3d_xy-defined-ticks.png new file mode 100644 index 00000000000..f2d2c1f0008 Binary files /dev/null and b/test/image/mocks/gl3d_xy-defined-ticks.png differ