Skip to content

Commit c73e84b

Browse files
authored
Merge pull request #3638 from plotly/fix2812-surface-connectgaps
Implementation of connectgaps for the surface trace
2 parents a24fea7 + afe36a6 commit c73e84b

File tree

6 files changed

+87
-3
lines changed

6 files changed

+87
-3
lines changed

src/traces/surface/attributes.js

+12
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,18 @@ var attrs = module.exports = overrideAll(extendFlat({
133133
},
134134
hovertemplate: hovertemplateAttrs(),
135135

136+
connectgaps: {
137+
valType: 'boolean',
138+
dflt: false,
139+
role: 'info',
140+
editType: 'calc',
141+
description: [
142+
'Determines whether or not gaps',
143+
'(i.e. {nan} or missing values)',
144+
'in the `z` data are filled in.'
145+
].join(' ')
146+
},
147+
136148
surfacecolor: {
137149
valType: 'data_array',
138150
description: [

src/traces/surface/convert.js

+22-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ var isArrayOrTypedArray = require('../../lib').isArrayOrTypedArray;
1919
var parseColorScale = require('../../lib/gl_format_color').parseColorScale;
2020
var str2RgbaArray = require('../../lib/str2rgbarray');
2121

22+
var interp2d = require('../heatmap/interp2d');
23+
var findEmpties = require('../heatmap/find_empties');
24+
2225
function SurfaceTrace(scene, surface, uid) {
2326
this.scene = scene;
2427
this.uid = uid;
@@ -30,6 +33,7 @@ function SurfaceTrace(scene, surface, uid) {
3033
this.dataScaleX = 1.0;
3134
this.dataScaleY = 1.0;
3235
this.refineData = true;
36+
this._interpolatedZ = false;
3337
}
3438

3539
var proto = SurfaceTrace.prototype;
@@ -59,9 +63,11 @@ proto.getYat = function(a, b, calendar, axis) {
5963
};
6064

6165
proto.getZat = function(a, b, calendar, axis) {
62-
var v = (
63-
this.data.z[b][a]
64-
);
66+
var v = this.data.z[b][a];
67+
68+
if(v === null && this.data.connectgaps && this.data._interpolatedZ) {
69+
v = this.data._interpolatedZ[b][a];
70+
}
6571

6672
return (calendar === undefined) ? v : axis.d2l(v, 0, calendar);
6773
};
@@ -404,6 +410,19 @@ proto.update = function(data) {
404410
}
405411
}
406412

413+
if(data.connectgaps) {
414+
data._emptypoints = findEmpties(rawCoords[2]);
415+
interp2d(rawCoords[2], data._emptypoints);
416+
417+
data._interpolatedZ = [];
418+
for(j = 0; j < xlen; j++) {
419+
data._interpolatedZ[j] = [];
420+
for(k = 0; k < ylen; k++) {
421+
data._interpolatedZ[j][k] = rawCoords[2][j][k];
422+
}
423+
}
424+
}
425+
407426
// Note: log axes are not defined in surfaces yet.
408427
// but they could be defined here...
409428

src/traces/surface/defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
5656
'lightposition.y',
5757
'lightposition.z',
5858
'hidesurface',
59+
'connectgaps',
5960
'opacity'
6061
].forEach(function(x) { coerce(x); });
6162

Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"data": [
3+
{
4+
"type": "surface",
5+
"connectgaps": true,
6+
"x": [0.1, 0.2, 0.3, 0.4],
7+
"y": [0, 1, 2, 3, 4],
8+
"z": [
9+
[1001, 1002, 1001, null, null],
10+
[1002, 1001, null, 1002, null],
11+
[1002, null, 1001, 1001],
12+
[null, null, 1000, null]
13+
]
14+
}
15+
],
16+
"layout": {
17+
"title": "Surface plot with interpolated gaps<br>(connectgaps: true)",
18+
"width": 600,
19+
"height": 400
20+
}
21+
}

test/jasmine/tests/gl3d_plot_interact_test.js

+31
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,37 @@ describe('Test gl3d plots', function() {
378378
.then(done);
379379
});
380380

381+
it('@gl should display correct hover labels and emit correct event data (surface case with connectgaps enabled)', function(done) {
382+
var surfaceConnectgaps = require('@mocks/gl3d_surface_connectgaps');
383+
var _mock = Lib.extendDeep({}, surfaceConnectgaps);
384+
385+
function _hover() {
386+
mouseEvent('mouseover', 300, 200);
387+
return delay(20)();
388+
}
389+
390+
Plotly.plot(gd, _mock)
391+
.then(delay(20))
392+
.then(function() {
393+
gd.on('plotly_hover', function(eventData) {
394+
ptData = eventData.points[0];
395+
});
396+
})
397+
.then(_hover)
398+
.then(function() {
399+
assertHoverText('x: 0.2', 'y: 2', 'z: 1,001.25');
400+
assertEventData(0.2, 2, 1001.25, 0, [1, 2]);
401+
assertHoverLabelStyle(d3.selectAll('g.hovertext'), {
402+
bgcolor: 'rgb(68, 68, 68)',
403+
bordercolor: 'rgb(255, 255, 255)',
404+
fontSize: 13,
405+
fontFamily: 'Arial',
406+
fontColor: 'rgb(255, 255, 255)'
407+
}, 'initial');
408+
})
409+
.then(done);
410+
});
411+
381412
it('@gl should display correct hover labels and emit correct event data (surface case)', function(done) {
382413
var _mock = Lib.extendDeep({}, mock3);
383414

0 commit comments

Comments
 (0)