Skip to content

Commit eeef0ed

Browse files
authored
Merge pull request #2327 from plotly/mesh3d-text
Add support for (hover) 'text' in mesh3d traces
2 parents d3a7eab + 13a3ecf commit eeef0ed

File tree

7 files changed

+133
-8
lines changed

7 files changed

+133
-8
lines changed

src/traces/mesh3d/attributes.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ var colorAttrs = require('../../components/colorscale/color_attributes');
1212
var colorscaleAttrs = require('../../components/colorscale/attributes');
1313
var colorbarAttrs = require('../../components/colorbar/attributes');
1414
var surfaceAtts = require('../surface/attributes');
15+
var baseAttrs = require('../../plots/attributes');
1516

1617
var extendFlat = require('../../lib/extend').extendFlat;
1718

18-
1919
module.exports = extendFlat(colorAttrs('', 'calc', false), {
2020
x: {
2121
valType: 'data_array',
@@ -78,6 +78,19 @@ module.exports = extendFlat(colorAttrs('', 'calc', false), {
7878

7979
},
8080

81+
text: {
82+
valType: 'string',
83+
role: 'info',
84+
dflt: '',
85+
arrayOk: true,
86+
editType: 'calc',
87+
description: [
88+
'Sets the text elements associated with the vertices.',
89+
'If trace `hoverinfo` contains a *text* flag and *hovertext* is not set,',
90+
'these elements will be seen in the hover labels.'
91+
].join(' ')
92+
},
93+
8194
delaunayaxis: {
8295
valType: 'enumerated',
8396
role: 'info',
@@ -209,5 +222,7 @@ module.exports = extendFlat(colorAttrs('', 'calc', false), {
209222
description: 'Epsilon for face normals calculation avoids math issues arising from degenerate geometry.'
210223
},
211224
editType: 'calc'
212-
}, surfaceAtts.lighting)
225+
}, surfaceAtts.lighting),
226+
227+
hoverinfo: extendFlat({}, baseAttrs.hoverinfo, {editType: 'calc'})
213228
});

src/traces/mesh3d/convert.js

+7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ proto.handlePick = function(selection) {
4040
this.data.z[selectIndex]
4141
];
4242

43+
var text = this.data.text;
44+
if(Array.isArray(text) && text[selectIndex] !== undefined) {
45+
selection.textLabel = text[selectIndex];
46+
} else if(text) {
47+
selection.textLabel = text;
48+
}
49+
4350
return true;
4451
}
4552
};

src/traces/mesh3d/defaults.js

+2
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,6 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
8484
else if('vertexcolor' in traceIn) coerce('vertexcolor');
8585
else coerce('color', defaultColor);
8686
}
87+
88+
coerce('text');
8789
};

src/traces/scatter3d/attributes.js

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
var scatterAttrs = require('../scatter/attributes');
1212
var colorAttributes = require('../../components/colorscale/color_attributes');
1313
var errorBarAttrs = require('../../components/errorbars/attributes');
14+
var baseAttrs = require('../../plots/attributes');
1415
var DASHES = require('../../constants/gl3d_dashes');
1516

1617
var MARKER_SYMBOLS = require('../../constants/gl3d_markers');
@@ -171,6 +172,8 @@ var attrs = module.exports = overrideAll({
171172
error_x: errorBarAttrs,
172173
error_y: errorBarAttrs,
173174
error_z: errorBarAttrs,
175+
176+
hoverinfo: extendFlat({}, baseAttrs.hoverinfo)
174177
}, 'calc', 'nested');
175178

176179
attrs.x.editType = attrs.y.editType = attrs.z.editType = 'calc+clearAxisTypes';

src/traces/surface/attributes.js

+14-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
var Color = require('../../components/color');
1212
var colorscaleAttrs = require('../../components/colorscale/attributes');
1313
var colorbarAttrs = require('../../components/colorbar/attributes');
14+
var baseAttrs = require('../../plots/attributes');
1415

1516
var extendFlat = require('../../lib/extend').extendFlat;
1617
var overrideAll = require('../../plot_api/edit_types').overrideAll;
@@ -112,9 +113,17 @@ var attrs = module.exports = overrideAll({
112113
},
113114

114115
text: {
115-
valType: 'data_array',
116-
description: 'Sets the text elements associated with each z value.'
116+
valType: 'string',
117+
role: 'info',
118+
dflt: '',
119+
arrayOk: true,
120+
description: [
121+
'Sets the text elements associated with each z value.',
122+
'If trace `hoverinfo` contains a *text* flag and *hovertext* is not set,',
123+
'these elements will be seen in the hover labels.'
124+
].join(' ')
117125
},
126+
118127
surfacecolor: {
119128
valType: 'data_array',
120129
description: [
@@ -242,7 +251,9 @@ var attrs = module.exports = overrideAll({
242251
zmax: extendFlat({}, colorscaleAttrs.zmax, {
243252
description: 'Obsolete. Use `cmax` instead.'
244253
})
245-
}
254+
},
255+
256+
hoverinfo: extendFlat({}, baseAttrs.hoverinfo)
246257
}, 'calc', 'nested');
247258

248259
attrs.x.editType = attrs.y.editType = attrs.z.editType = 'calc+clearAxisTypes';

src/traces/surface/convert.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,13 @@ proto.handlePick = function(selection) {
6767
];
6868

6969
var text = this.data.text;
70-
if(text && text[selectIndex[1]] && text[selectIndex[1]][selectIndex[0]] !== undefined) {
70+
if(Array.isArray(text) && text[selectIndex[1]] && text[selectIndex[1]][selectIndex[0]] !== undefined) {
7171
selection.textLabel = text[selectIndex[1]][selectIndex[0]];
72+
} else if(text) {
73+
selection.textLabel = text;
74+
} else {
75+
selection.textLabel = '';
7276
}
73-
else selection.textLabel = '';
7477

7578
selection.data.dataCoordinate = selection.dataCoordinate.slice();
7679

test/jasmine/tests/gl3d_plot_interact_test.js

+85-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ describe('@gl Test gl3d plots', function() {
3737
var mock3 = require('@mocks/gl3d_autocolorscale');
3838

3939
function assertHoverText(xLabel, yLabel, zLabel, textLabel) {
40-
var content = [xLabel, yLabel, zLabel];
40+
var content = [];
41+
if(xLabel) content.push(xLabel);
42+
if(yLabel) content.push(yLabel);
43+
if(zLabel) content.push(zLabel);
4144
if(textLabel) content.push(textLabel);
4245
assertHoverLabelContent({nums: content.join('\n')});
4346
}
@@ -194,6 +197,16 @@ describe('@gl Test gl3d plots', function() {
194197
.then(_hover)
195198
.then(function() {
196199
assertHoverText('x: 二 6, 2017', 'y: c', 'z: 100k', 'Clementine');
200+
201+
return Plotly.restyle(gd, 'hoverinfo', 'text');
202+
})
203+
.then(function() {
204+
assertHoverText(null, null, null, 'Clementine');
205+
206+
return Plotly.restyle(gd, 'hoverinfo', 'z');
207+
})
208+
.then(function() {
209+
assertHoverText(null, null, '100k');
197210
})
198211
.catch(fail)
199212
.then(done);
@@ -274,6 +287,23 @@ describe('@gl Test gl3d plots', function() {
274287
'colorbar.tickvals': undefined,
275288
'colorbar.ticktext': undefined
276289
});
290+
291+
return Plotly.restyle(gd, 'hoverinfo', 'z');
292+
})
293+
.then(_hover)
294+
.then(function() {
295+
assertHoverText(null, null, '43');
296+
297+
return Plotly.restyle(gd, 'hoverinfo', 'text');
298+
})
299+
.then(_hover)
300+
.then(function() {
301+
assertHoverText(null, null, null, 'one two');
302+
303+
return Plotly.restyle(gd, 'text', 'yo!');
304+
})
305+
.then(function() {
306+
assertHoverText(null, null, null, 'yo!');
277307
})
278308
.then(done);
279309
});
@@ -303,6 +333,60 @@ describe('@gl Test gl3d plots', function() {
303333
.then(done);
304334
});
305335

336+
it('should display correct hover labels (mesh3d case)', function(done) {
337+
var x = [1, 1, 2, 3, 4, 2];
338+
var y = [2, 1, 3, 4, 5, 3];
339+
var z = [3, 7, 4, 5, 3.5, 2];
340+
var text = x.map(function(_, i) {
341+
return [
342+
'ts: ' + x[i],
343+
'hz: ' + y[i],
344+
'ftt:' + z[i]
345+
].join('<br>');
346+
});
347+
348+
function _hover() {
349+
mouseEvent('mouseover', 250, 250);
350+
return delay(20)();
351+
}
352+
353+
Plotly.newPlot(gd, [{
354+
type: 'mesh3d',
355+
x: x,
356+
y: y,
357+
z: z,
358+
text: text
359+
}], {
360+
width: 500,
361+
height: 500
362+
})
363+
.then(delay(20))
364+
.then(_hover)
365+
.then(function() {
366+
assertHoverText('x: 3', 'y: 4', 'z: 5', 'ts: 3\nhz: 4\nftt:5');
367+
})
368+
.then(function() {
369+
return Plotly.restyle(gd, 'hoverinfo', 'x+y');
370+
})
371+
.then(function() {
372+
assertHoverText('(3, 4)');
373+
})
374+
.then(function() {
375+
return Plotly.restyle(gd, 'hoverinfo', 'text');
376+
})
377+
.then(function() {
378+
assertHoverText('ts: 3\nhz: 4\nftt:5');
379+
})
380+
.then(function() {
381+
return Plotly.restyle(gd, 'text', 'yo!');
382+
})
383+
.then(function() {
384+
assertHoverText(null, null, null, 'yo!');
385+
})
386+
.catch(fail)
387+
.then(done);
388+
});
389+
306390
it('should be able to reversibly change trace type', function(done) {
307391
var _mock = Lib.extendDeep({}, mock2);
308392
var sceneLayout = { aspectratio: { x: 1, y: 1, z: 1 } };

0 commit comments

Comments
 (0)