Skip to content
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

Make surface contour highlights on hover toggleable #459

Merged
merged 10 commits into from
Apr 26, 2016
35 changes: 28 additions & 7 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -659,25 +659,25 @@ function cleanAxRef(container, attr) {
}
}

// Make a few changes to the data right away
// before it gets used for anything
function cleanData(data, existingData) {
// make a few changes to the data right away
// before it gets used for anything

/*
* Enforce unique IDs
*/
// Enforce unique IDs
var suids = [], // seen uids --- so we can weed out incoming repeats
uids = data.concat(Array.isArray(existingData) ? existingData : [])
.filter(function(trace) { return 'uid' in trace; })
.map(function(trace) { return trace.uid; });

for(var tracei = 0; tracei < data.length; tracei++) {
var trace = data[tracei];
var i;

// assign uids to each trace and detect collisions.
if(!('uid' in trace) || suids.indexOf(trace.uid) !== -1) {
var newUid, i;
for(i=0; i<100; i++) {
var newUid;

for(i = 0; i < 100; i++) {
newUid = Lib.randstr(uids);
if(suids.indexOf(newUid)===-1) break;
}
Expand Down Expand Up @@ -765,6 +765,27 @@ function cleanData(data, existingData) {
if(cont.colorscale === 'YIOrRd') cont.colorscale = 'YlOrRd';
}

// fix typo in surface 'highlight*' definitions
if(trace.type === 'surface' && Lib.isPlainObject(trace.contours)) {
var dims = ['x', 'y', 'z'];

for(i = 0; i < dims.length; i++) {
var opts = trace.contours[dims[i]];

if(!Lib.isPlainObject(opts)) continue;

if(opts.highlightColor) {
opts.highlightcolor = opts.highlightColor;
delete opts.highlightColor;
}

if(opts.highlightWidth) {
opts.highlightwidth = opts.highlightWidth;
delete opts.highlightWidth;
}
}
}

// prune empty containers made before the new nestedProperty
if(emptyContainer(trace, 'line')) delete trace.line;
if('marker' in trace) {
Expand Down
4 changes: 2 additions & 2 deletions src/plots/gl3d/layout/axis_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

'use strict';


var Color = require('../../../components/color');
var axesAttrs = require('../../cartesian/layout_attributes');
var extendFlat = require('../../../lib/extend').extendFlat;

Expand Down Expand Up @@ -43,7 +43,7 @@ module.exports = {
spikecolor: {
valType: 'color',
role: 'style',
dflt: 'rgb(0,0,0)',
dflt: Color.defaultLine,
description: 'Sets the color of the spikes.'
},
showbackground: {
Expand Down
1 change: 1 addition & 0 deletions src/plots/gl3d/layout/axis_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@


'use strict';

var colorMix = require('tinycolor2').mix;

var Lib = require('../../../lib');
Expand Down
56 changes: 42 additions & 14 deletions src/traces/surface/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

'use strict';

var Color = require('../../components/color');
var colorscaleAttrs = require('../../components/colorscale/attributes');
var extendFlat = require('../../lib/extend').extendFlat;

Expand All @@ -19,8 +20,12 @@ function makeContourProjAttr(axLetter) {
role: 'info',
dflt: false,
description: [
'Sets whether or not the dynamic contours are projected',
'along the', axLetter, 'axis.'
'Determines whether or not these contour lines are projected',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cldougl (or someone else from the doc team) could you review ⬇️ ?

Copy link
Member

Choose a reason for hiding this comment

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

Clear to me!

'on the', axLetter, 'axis walls.',
'If `highlight` is set to *true* (the default), the projected',
'lines are shown on hover.',
'If `show` is set to *true*, the projected lines are shown',
'in permanence.'
].join(' ')
};
}
Expand All @@ -32,8 +37,8 @@ function makeContourAttr(axLetter) {
role: 'info',
dflt: false,
description: [
'Sets whether or not dynamic contours are shown along the',
axLetter, 'axis'
'Determines whether or not contour lines about the', axLetter,
'dimension are drawn.'
].join(' ')
},
project: {
Expand All @@ -44,36 +49,49 @@ function makeContourAttr(axLetter) {
color: {
valType: 'color',
role: 'style',
dflt: '#000'
dflt: Color.defaultLine,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This required updating on baseline image ⬇️.

description: 'Sets the color of the contour lines.'
},
usecolormap: {
valType: 'boolean',
role: 'info',
dflt: false
dflt: false,
description: [
'An alternate to *color*.',
'Determines whether or not the contour lines are colored using',
'the trace *colorscale*.'
].join(' ')
},
width: {
valType: 'number',
role: 'style',
min: 1,
max: 16,
dflt: 2
dflt: 2,
description: 'Sets the width of the contour lines.'
},
highlight: {
valType: 'boolean',
role: 'info',
dflt: false
dflt: true,
description: [
'Determines whether or not contour lines about the', axLetter,
'dimension are highlighted on hover.'
].join(' ')
},
highlightColor: {
highlightcolor: {
valType: 'color',
role: 'style',
dflt: '#000'
dflt: Color.defaultLine,
description: 'Sets the color of the highlighted contour lines.'
},
highlightWidth: {
highlightwidth: {
valType: 'number',
role: 'style',
min: 1,
max: 16,
dflt: 2
dflt: 2,
description: 'Sets the width of the highlighted contour lines.'
}
};
}
Expand Down Expand Up @@ -102,6 +120,7 @@ module.exports = {
'used for setting a color scale independent of `z`.'
].join(' ')
},

cauto: colorscaleAttrs.zauto,
cmin: colorscaleAttrs.zmin,
cmax: colorscaleAttrs.zmax,
Expand All @@ -110,6 +129,7 @@ module.exports = {
{dflt: false}),
reversescale: colorscaleAttrs.reversescale,
showscale: colorscaleAttrs.showscale,

contours: {
x: makeContourAttr('x'),
y: makeContourAttr('y'),
Expand All @@ -118,8 +138,15 @@ module.exports = {
hidesurface: {
valType: 'boolean',
role: 'info',
dflt: false
dflt: false,
description: [
'Determines whether or not a surface is drawn.',
'For example, set `hidesurface` to *false*',
'`contours.x.show` to *true* and',
'`contours.y.show` to *true* to draw a wire frame plot.'
].join(' ')
Copy link
Member

Choose a reason for hiding this comment

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

💎 description--thanks for adding that!

},

lighting: {
ambient: {
valType: 'number',
Expand Down Expand Up @@ -163,7 +190,8 @@ module.exports = {
role: 'style',
min: 0,
max: 1,
dflt: 1
dflt: 1,
description: 'Sets the opacity of the surface.'
},

_nestedModules: { // nested module coupling
Expand Down
10 changes: 4 additions & 6 deletions src/traces/surface/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,11 @@ proto.update = function(data) {
}

var highlightEnable = [true, true, true];
var contourEnable = [true, true, true];
var axis = ['x', 'y', 'z'];

for(i = 0; i < 3; ++i) {
var contourParams = data.contours[axis[i]];
highlightEnable[i] = contourParams.highlight;
contourEnable[i] = contourParams.show;

params.showContour[i] = contourParams.show || contourParams.highlight;
if(!params.showContour[i]) continue;
Expand All @@ -301,6 +299,7 @@ proto.update = function(data) {
this.showContour[i] = true;
params.levels[i] = contourLevels[i];
surface.highlightColor[i] = params.contourColor[i] = str2RgbaArray(contourParams.color);

if(contourParams.usecolormap) {
surface.highlightTint[i] = params.contourTint[i] = 0;
}
Expand All @@ -313,18 +312,17 @@ proto.update = function(data) {
}

if(contourParams.highlight) {
params.dynamicColor[i] = str2RgbaArray(contourParams.highlightColor);
params.dynamicWidth[i] = contourParams.highlightWidth;
params.dynamicColor[i] = str2RgbaArray(contourParams.highlightcolor);
params.dynamicWidth[i] = contourParams.highlightwidth;
}
}

params.coords = coords;

surface.update(params);

surface.highlightEnable = highlightEnable;
surface.contourEnable = contourEnable;
surface.visible = data.visible;
surface.enableDynamic = highlightEnable;

surface.snapToData = true;

Expand Down
7 changes: 5 additions & 2 deletions src/traces/surface/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
}

if(highlight) {
coerce(contourDim + '.highlightColor');
coerce(contourDim + '.highlightWidth');
coerce(contourDim + '.highlightcolor');
coerce(contourDim + '.highlightwidth');
}
}

Expand All @@ -94,6 +94,9 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
mapLegacy(traceIn, 'zauto', 'cauto');
}

// TODO if contours.?.usecolormap are false and hidesurface is true
// the colorbar shouldn't be shown by default

colorscaleDefaults(
traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'c'}
);
Expand Down
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.
66 changes: 66 additions & 0 deletions test/jasmine/tests/plot_api_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -689,5 +689,71 @@ describe('Test plot api', function() {
Plotly.plot(gd, data);
expect(gd.data[0].marker.colorscale).toBe('YlOrRd');
});

it('should rename \'highlightColor\' to \'highlightcolor\')', function() {
var data = [{
type: 'surface',
contours: {
x: { highlightColor: 'red' },
y: { highlightcolor: 'blue' }
}
}, {
type: 'surface'
}, {
type: 'surface',
contours: false
}, {
type: 'surface',
contours: {
stuff: {},
x: false,
y: []
}
}];

spyOn(Plots.subplotsRegistry.gl3d, 'plot');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

fyi @mdtusz @monfera quick and dirty trick to test Plotly.plot with gl traces in a way that works on CircleCI.


Plotly.plot(gd, data);

expect(Plots.subplotsRegistry.gl3d.plot).toHaveBeenCalled();

var contours = gd.data[0].contours;

expect(contours.x.highlightColor).toBeUndefined();
expect(contours.x.highlightcolor).toEqual('red');
expect(contours.y.highlightcolor).toEqual('blue');
expect(contours.z).toBeUndefined();

expect(gd.data[1].contours).toBeUndefined();
expect(gd.data[2].contours).toBe(false);
expect(gd.data[3].contours).toEqual({ stuff: {}, x: false, y: [] });
});

it('should rename \'highlightWidth\' to \'highlightwidth\')', function() {
var data = [{
type: 'surface',
contours: {
z: { highlightwidth: 'red' },
y: { highlightWidth: 'blue' }
}
}, {
type: 'surface'
}];

spyOn(Plots.subplotsRegistry.gl3d, 'plot');

Plotly.plot(gd, data);

expect(Plots.subplotsRegistry.gl3d.plot).toHaveBeenCalled();

var contours = gd.data[0].contours;

expect(contours.x).toBeUndefined();
expect(contours.y.highlightwidth).toEqual('blue');
expect(contours.z.highlightWidth).toBeUndefined();
expect(contours.z.highlightwidth).toEqual('red');

expect(gd.data[1].contours).toBeUndefined();
});
});
});
Loading