Skip to content

Commit 138291e

Browse files
authored
Merge pull request #4291 from plotly/hover-on-missing-data
Add hoverongaps to heatmap and contour for suppressing hovers on missing data
2 parents 8c5f66d + 9269352 commit 138291e

File tree

7 files changed

+106
-3
lines changed

7 files changed

+106
-3
lines changed

src/traces/contour/attributes.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ module.exports = extendFlat({
3838
ytype: heatmapAttrs.ytype,
3939
zhoverformat: heatmapAttrs.zhoverformat,
4040
hovertemplate: heatmapAttrs.hovertemplate,
41-
41+
hoverongaps: heatmapAttrs.hoverongaps,
4242
connectgaps: extendFlat({}, heatmapAttrs.connectgaps, {
4343
description: [
4444
'Determines whether or not gaps',

src/traces/contour/defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3535
coerce('text');
3636
coerce('hovertext');
3737
coerce('hovertemplate');
38+
coerce('hoverongaps');
3839

3940
var isConstraint = (coerce('contours.type') === 'constraint');
4041
coerce('connectgaps', Lib.isArray1D(traceOut.z));

src/traces/heatmap/attributes.js

+11
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,17 @@ module.exports = extendFlat({
7979
'Picks a smoothing algorithm use to smooth `z` data.'
8080
].join(' ')
8181
},
82+
hoverongaps: {
83+
valType: 'boolean',
84+
dflt: true,
85+
role: 'style',
86+
editType: 'none',
87+
description: [
88+
'Determines whether or not gaps',
89+
'(i.e. {nan} or missing values)',
90+
'in the `z` data have hover labels associated with them.'
91+
].join(' ')
92+
},
8293
connectgaps: {
8394
valType: 'boolean',
8495
role: 'info',

src/traces/heatmap/defaults.js

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3434

3535
handleStyleDefaults(traceIn, traceOut, coerce, layout);
3636

37+
coerce('hoverongaps');
3738
coerce('connectgaps', Lib.isArray1D(traceOut.z) && (traceOut.zsmooth !== false));
3839

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

src/traces/heatmap/hover.js

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLay
9191
var zVal = z[ny][nx];
9292
if(zmask && !zmask[ny][nx]) zVal = undefined;
9393

94+
if(zVal === undefined && !trace.hoverongaps) return;
95+
9496
var text;
9597
if(Array.isArray(cd0.hovertext) && Array.isArray(cd0.hovertext[ny])) {
9698
text = cd0.hovertext[ny][nx];

test/jasmine/tests/contour_test.js

+60-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ describe('contour defaults', function() {
6666

6767
it('should default connectgaps to false if `z` is not a one dimensional array', function() {
6868
traceIn = {
69-
type: 'heatmap',
69+
type: 'contour',
7070
z: [[0, null], [1, 2]]
7171
};
7272

@@ -76,7 +76,7 @@ describe('contour defaults', function() {
7676

7777
it('should default connectgaps to true if `z` is a one dimensional array', function() {
7878
traceIn = {
79-
type: 'heatmap',
79+
type: 'contour',
8080
x: [0, 1, 0, 1],
8181
y: [0, 0, 1, 1],
8282
z: [0, null, 1, 2]
@@ -591,3 +591,61 @@ describe('contour plotting and editing', function() {
591591
.then(done);
592592
});
593593
});
594+
595+
describe('contour hover', function() {
596+
'use strict';
597+
598+
var gd;
599+
600+
function _hover(gd, xval, yval) {
601+
var fullLayout = gd._fullLayout;
602+
var calcData = gd.calcdata;
603+
var hoverData = [];
604+
605+
for(var i = 0; i < calcData.length; i++) {
606+
var pointData = {
607+
index: false,
608+
distance: 20,
609+
cd: calcData[i],
610+
trace: calcData[i][0].trace,
611+
xa: fullLayout.xaxis,
612+
ya: fullLayout.yaxis
613+
};
614+
615+
var hoverPoint = Contour.hoverPoints(pointData, xval, yval);
616+
if(hoverPoint) hoverData.push(hoverPoint[0]);
617+
}
618+
619+
return hoverData;
620+
}
621+
622+
describe('missing data', function() {
623+
beforeAll(function(done) {
624+
gd = createGraphDiv();
625+
626+
Plotly.plot(gd, {
627+
data: [{
628+
type: 'contour',
629+
x: [10, 11, 10, 11],
630+
y: [100, 100, 101, 101],
631+
z: [null, 1, 2, 3],
632+
connectgaps: false,
633+
hoverongaps: false
634+
}]
635+
}).then(done);
636+
});
637+
afterAll(destroyGraphDiv);
638+
639+
it('should not display hover on missing data and hoverongaps is disabled', function() {
640+
var pt = _hover(gd, 10, 100)[0];
641+
642+
var hoverData;
643+
gd.on('plotly_hover', function(data) {
644+
hoverData = data;
645+
});
646+
647+
expect(hoverData).toEqual(undefined);
648+
expect(pt).toEqual(undefined);
649+
});
650+
});
651+
});

test/jasmine/tests/heatmap_test.js

+30
Original file line numberDiff line numberDiff line change
@@ -976,4 +976,34 @@ describe('heatmap hover', function() {
976976
.then(done);
977977
});
978978
});
979+
980+
describe('missing data', function() {
981+
beforeAll(function(done) {
982+
gd = createGraphDiv();
983+
984+
Plotly.plot(gd, {
985+
data: [{
986+
type: 'heatmap',
987+
x: [10, 11, 10, 11],
988+
y: [100, 100, 101, 101],
989+
z: [null, 1, 2, 3],
990+
connectgaps: false,
991+
hoverongaps: false
992+
}]
993+
}).then(done);
994+
});
995+
afterAll(destroyGraphDiv);
996+
997+
it('should not display hover on missing data and hoverongaps is disabled', function() {
998+
var pt = _hover(gd, 10, 100)[0];
999+
1000+
var hoverData;
1001+
gd.on('plotly_hover', function(data) {
1002+
hoverData = data;
1003+
});
1004+
1005+
expect(hoverData).toEqual(undefined);
1006+
expect(pt).toEqual(undefined);
1007+
});
1008+
});
9791009
});

0 commit comments

Comments
 (0)