Skip to content

Commit 0a4feb3

Browse files
committed
implement hovergaps false option for heatmap and contour traces
1 parent 6e9bafb commit 0a4feb3

File tree

7 files changed

+123
-21
lines changed

7 files changed

+123
-21
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+
hovergaps: heatmapAttrs.hovergaps,
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('hovergaps');
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+
hovergaps: {
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 are hovered on.'
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('hovergaps');
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

+22-18
Original file line numberDiff line numberDiff line change
@@ -88,28 +88,14 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLay
8888
}
8989
}
9090

91-
var zVal = z[ny][nx];
92-
if(zmask && !zmask[ny][nx]) zVal = undefined;
93-
9491
var text;
9592
if(Array.isArray(cd0.hovertext) && Array.isArray(cd0.hovertext[ny])) {
9693
text = cd0.hovertext[ny][nx];
9794
} else if(Array.isArray(cd0.text) && Array.isArray(cd0.text[ny])) {
9895
text = cd0.text[ny][nx];
9996
}
10097

101-
// dummy axis for formatting the z value
102-
var cOpts = extractOpts(trace);
103-
var dummyAx = {
104-
type: 'linear',
105-
range: [cOpts.min, cOpts.max],
106-
hoverformat: zhoverformat,
107-
_separators: xa._separators,
108-
_numFormat: xa._numFormat
109-
};
110-
var zLabel = Axes.tickText(dummyAx, zVal, 'hover').text;
111-
112-
return [Lib.extendFlat(pointData, {
98+
var obj = {
11399
index: [ny, nx],
114100
// never let a 2D override 1D type as closest point
115101
distance: pointData.maxHoverDistance,
@@ -120,8 +106,26 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLay
120106
y1: y1,
121107
xLabelVal: xl,
122108
yLabelVal: yl,
123-
zLabelVal: zVal,
124-
zLabel: zLabel,
125109
text: text
126-
})];
110+
};
111+
112+
var zVal = z[ny][nx];
113+
if(zmask && !zmask[ny][nx]) zVal = undefined;
114+
115+
if(zVal !== undefined || trace.hovergaps) {
116+
// dummy axis for formatting the z value
117+
var cOpts = extractOpts(trace);
118+
var dummyAx = {
119+
type: 'linear',
120+
range: [cOpts.min, cOpts.max],
121+
hoverformat: zhoverformat,
122+
_separators: xa._separators,
123+
_numFormat: xa._numFormat
124+
};
125+
126+
obj.zLabelVal = zVal;
127+
obj.zLabel = Axes.tickText(dummyAx, zVal, 'hover').text;
128+
}
129+
130+
return [Lib.extendFlat(pointData, obj)];
127131
};

test/jasmine/tests/contour_test.js

+62-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,63 @@ 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+
function assertLabels(hoverPoint, xLabel, yLabel, zLabel, text) {
623+
expect(hoverPoint.xLabelVal).toBe(xLabel, 'have correct x label');
624+
expect(hoverPoint.yLabelVal).toBe(yLabel, 'have correct y label');
625+
expect(hoverPoint.zLabelVal).toBe(zLabel, 'have correct z label');
626+
expect(hoverPoint.text).toBe(text, 'have correct text label');
627+
}
628+
629+
describe('missing data', function() {
630+
beforeAll(function(done) {
631+
gd = createGraphDiv();
632+
633+
Plotly.plot(gd, {
634+
data: [{
635+
type: 'contour',
636+
x: [10, 11, 10, 11],
637+
y: [100, 100, 101, 101],
638+
z: [null, 1, 2, 3],
639+
connectgaps: false,
640+
hovergaps: false
641+
}]
642+
}).then(done);
643+
});
644+
afterAll(destroyGraphDiv);
645+
646+
it('should not create zLabels when hovering on missing data and hovergaps is disabled', function() {
647+
var pt = _hover(gd, 10, 100)[0];
648+
649+
expect(pt.index).toEqual([0, 0], 'have correct index');
650+
assertLabels(pt, 10, 100, undefined);
651+
});
652+
});
653+
});

test/jasmine/tests/heatmap_test.js

+25
Original file line numberDiff line numberDiff line change
@@ -976,4 +976,29 @@ 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+
hovergaps: false
992+
}]
993+
}).then(done);
994+
});
995+
afterAll(destroyGraphDiv);
996+
997+
it('should not create zLabels when hovering on missing data and hovergaps is disabled', function() {
998+
var pt = _hover(gd, 10, 100)[0];
999+
1000+
expect(pt.index).toEqual([0, 0], 'have correct index');
1001+
assertLabels(pt, 10, 100, undefined);
1002+
});
1003+
});
9791004
});

0 commit comments

Comments
 (0)