Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/traces/contour/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ module.exports = extendFlat({
ytype: heatmapAttrs.ytype,
zhoverformat: heatmapAttrs.zhoverformat,
hovertemplate: heatmapAttrs.hovertemplate,

hovergaps: heatmapAttrs.hovergaps,
connectgaps: extendFlat({}, heatmapAttrs.connectgaps, {
description: [
'Determines whether or not gaps',
Expand Down
1 change: 1 addition & 0 deletions src/traces/contour/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
coerce('text');
coerce('hovertext');
coerce('hovertemplate');
coerce('hovergaps');

var isConstraint = (coerce('contours.type') === 'constraint');
coerce('connectgaps', Lib.isArray1D(traceOut.z));
Expand Down
11 changes: 11 additions & 0 deletions src/traces/heatmap/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ module.exports = extendFlat({
'Picks a smoothing algorithm use to smooth `z` data.'
].join(' ')
},
hovergaps: {
valType: 'boolean',
dflt: true,
role: 'style',
editType: 'none',
description: [
'Determines whether or not gaps',
'(i.e. {nan} or missing values)',
'in the `z` data are hovered on.'
].join(' ')
},
connectgaps: {
valType: 'boolean',
role: 'info',
Expand Down
1 change: 1 addition & 0 deletions src/traces/heatmap/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout

handleStyleDefaults(traceIn, traceOut, coerce, layout);

coerce('hovergaps');
coerce('connectgaps', Lib.isArray1D(traceOut.z) && (traceOut.zsmooth !== false));

colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'});
Expand Down
40 changes: 22 additions & 18 deletions src/traces/heatmap/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,14 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLay
}
}

var zVal = z[ny][nx];
if(zmask && !zmask[ny][nx]) zVal = undefined;

var text;
if(Array.isArray(cd0.hovertext) && Array.isArray(cd0.hovertext[ny])) {
text = cd0.hovertext[ny][nx];
} else if(Array.isArray(cd0.text) && Array.isArray(cd0.text[ny])) {
text = cd0.text[ny][nx];
}

// dummy axis for formatting the z value
var cOpts = extractOpts(trace);
var dummyAx = {
type: 'linear',
range: [cOpts.min, cOpts.max],
hoverformat: zhoverformat,
_separators: xa._separators,
_numFormat: xa._numFormat
};
var zLabel = Axes.tickText(dummyAx, zVal, 'hover').text;

return [Lib.extendFlat(pointData, {
var obj = {
index: [ny, nx],
// never let a 2D override 1D type as closest point
distance: pointData.maxHoverDistance,
Expand All @@ -120,8 +106,26 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLay
y1: y1,
xLabelVal: xl,
yLabelVal: yl,
zLabelVal: zVal,
zLabel: zLabel,
text: text
})];
};

var zVal = z[ny][nx];
if(zmask && !zmask[ny][nx]) zVal = undefined;

if(zVal !== undefined || trace.hovergaps) {
// dummy axis for formatting the z value
var cOpts = extractOpts(trace);
var dummyAx = {
type: 'linear',
range: [cOpts.min, cOpts.max],
hoverformat: zhoverformat,
_separators: xa._separators,
_numFormat: xa._numFormat
};

obj.zLabelVal = zVal;
obj.zLabel = Axes.tickText(dummyAx, zVal, 'hover').text;
}

return [Lib.extendFlat(pointData, obj)];
Copy link
Contributor

Choose a reason for hiding this comment

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

So this mean when hovergaps:false, zLabel and zLabelVal remain undefined, but we still pass pointData back to Fx.hover?

Does this mean that the hover label is suppressed, but the plotly_hover event is still getting triggered?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is a codepen displaying the current behaviour with hoverongaps disabled.
Please let me know if you prefer not to have hover effects at all.
cc: @emmanuelle

Copy link
Contributor

@etpinard etpinard Oct 22, 2019

Choose a reason for hiding this comment

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

I think the behaviour in @archmoj above codepen is incorrect. Under hoverongaps: false, there should be no hover labels shown and no plotly_hover event triggered.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Now fixed in 9269352.
new demo

Copy link
Contributor

Choose a reason for hiding this comment

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

Fantastic!!

};
64 changes: 62 additions & 2 deletions test/jasmine/tests/contour_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe('contour defaults', function() {

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

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

it('should default connectgaps to true if `z` is a one dimensional array', function() {
traceIn = {
type: 'heatmap',
type: 'contour',
x: [0, 1, 0, 1],
y: [0, 0, 1, 1],
z: [0, null, 1, 2]
Expand Down Expand Up @@ -591,3 +591,63 @@ describe('contour plotting and editing', function() {
.then(done);
});
});

describe('contour hover', function() {
'use strict';

var gd;

function _hover(gd, xval, yval) {
var fullLayout = gd._fullLayout;
var calcData = gd.calcdata;
var hoverData = [];

for(var i = 0; i < calcData.length; i++) {
var pointData = {
index: false,
distance: 20,
cd: calcData[i],
trace: calcData[i][0].trace,
xa: fullLayout.xaxis,
ya: fullLayout.yaxis
};

var hoverPoint = Contour.hoverPoints(pointData, xval, yval);
if(hoverPoint) hoverData.push(hoverPoint[0]);
}

return hoverData;
}

function assertLabels(hoverPoint, xLabel, yLabel, zLabel, text) {
expect(hoverPoint.xLabelVal).toBe(xLabel, 'have correct x label');
expect(hoverPoint.yLabelVal).toBe(yLabel, 'have correct y label');
expect(hoverPoint.zLabelVal).toBe(zLabel, 'have correct z label');
expect(hoverPoint.text).toBe(text, 'have correct text label');
}

describe('missing data', function() {
beforeAll(function(done) {
gd = createGraphDiv();

Plotly.plot(gd, {
data: [{
type: 'contour',
x: [10, 11, 10, 11],
y: [100, 100, 101, 101],
z: [null, 1, 2, 3],
connectgaps: false,
hovergaps: false
}]
}).then(done);
});
afterAll(destroyGraphDiv);

it('should not create zLabels when hovering on missing data and hovergaps is disabled', function() {
var pt = _hover(gd, 10, 100)[0];

expect(pt.index).toEqual([0, 0], 'have correct index');
assertLabels(pt, 10, 100, undefined);
});
});
});
25 changes: 25 additions & 0 deletions test/jasmine/tests/heatmap_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -976,4 +976,29 @@ describe('heatmap hover', function() {
.then(done);
});
});

describe('missing data', function() {
beforeAll(function(done) {
gd = createGraphDiv();

Plotly.plot(gd, {
data: [{
type: 'heatmap',
x: [10, 11, 10, 11],
y: [100, 100, 101, 101],
z: [null, 1, 2, 3],
connectgaps: false,
hovergaps: false
}]
}).then(done);
});
afterAll(destroyGraphDiv);

it('should not create zLabels when hovering on missing data and hovergaps is disabled', function() {
var pt = _hover(gd, 10, 100)[0];

expect(pt.index).toEqual([0, 0], 'have correct index');
assertLabels(pt, 10, 100, undefined);
});
});
});