diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js
index a32ad3f0922..b8161b52bf8 100644
--- a/src/components/fx/hover.js
+++ b/src/components/fx/hover.js
@@ -896,11 +896,15 @@ function createHoverText(hoverData, opts, gd) {
if(d.zLabel !== undefined) {
if(d.xLabel !== undefined) text += 'x: ' + d.xLabel + '
';
if(d.yLabel !== undefined) text += 'y: ' + d.yLabel + '
';
- text += (text ? 'z: ' : '') + d.zLabel;
+ if(d.trace.type !== 'choropleth') {
+ text += (text ? 'z: ' : '') + d.zLabel;
+ }
} else if(showCommonLabel && d[hovermode + 'Label'] === t0) {
text = d[(hovermode === 'x' ? 'y' : 'x') + 'Label'] || '';
} else if(d.xLabel === undefined) {
- if(d.yLabel !== undefined && d.trace.type !== 'scattercarpet') text = d.yLabel;
+ if(d.yLabel !== undefined && d.trace.type !== 'scattercarpet') {
+ text = d.yLabel;
+ }
} else if(d.yLabel === undefined) text = d.xLabel;
else text = '(' + d.xLabel + ', ' + d.yLabel + ')';
diff --git a/src/traces/choropleth/hover.js b/src/traces/choropleth/hover.js
index 1071adbcecb..ca19552ea50 100644
--- a/src/traces/choropleth/hover.js
+++ b/src/traces/choropleth/hover.js
@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
-
'use strict';
var Axes = require('../../plots/cartesian/axes');
@@ -47,6 +46,7 @@ module.exports = function hoverPoints(pointData, xval, yval) {
pointData.index = pt.index;
pointData.location = pt.loc;
pointData.z = pt.z;
+ pointData.zLabel = Axes.tickText(geo.mockAxis, geo.mockAxis.c2l(pt.z), 'hover').text;
pointData.hovertemplate = pt.hovertemplate;
makeHoverInfo(pointData, trace, pt, geo.mockAxis);
@@ -54,10 +54,8 @@ module.exports = function hoverPoints(pointData, xval, yval) {
return [pointData];
};
-function makeHoverInfo(pointData, trace, pt, axis) {
- if(trace.hovertemplate) {
- return;
- }
+function makeHoverInfo(pointData, trace, pt) {
+ if(trace.hovertemplate) return;
var hoverinfo = pt.hi || trace.hoverinfo;
@@ -73,10 +71,6 @@ function makeHoverInfo(pointData, trace, pt, axis) {
var text = [];
- function formatter(val) {
- return Axes.tickText(axis, axis.c2l(val), 'hover').text;
- }
-
if(hasIdAsNameLabel) {
pointData.nameOverride = pt.loc;
} else {
@@ -84,7 +78,9 @@ function makeHoverInfo(pointData, trace, pt, axis) {
if(hasLocation) text.push(pt.loc);
}
- if(hasZ) text.push(formatter(pt.z));
+ if(hasZ) {
+ text.push(pointData.zLabel);
+ }
if(hasText) {
fillText(pt, trace, text);
}
diff --git a/src/traces/scattergeo/hover.js b/src/traces/scattergeo/hover.js
index 37569731fe1..e925d4734f6 100644
--- a/src/traces/scattergeo/hover.js
+++ b/src/traces/scattergeo/hover.js
@@ -6,7 +6,6 @@
* LICENSE file in the root directory of this source tree.
*/
-
'use strict';
var Fx = require('../../components/fx');
@@ -64,17 +63,19 @@ module.exports = function hoverPoints(pointData, xval, yval) {
pointData.lon = lonlat[0];
pointData.lat = lonlat[1];
+ var ax = geo.mockAxis;
+ pointData.lonLabel = Axes.tickText(ax, ax.c2l(pointData.lon), 'hover').text;
+ pointData.latLabel = Axes.tickText(ax, ax.c2l(pointData.lat), 'hover').text;
+
pointData.color = getTraceColor(trace, di);
- pointData.extraText = getExtraText(trace, di, geo.mockAxis, cd[0].t.labels);
+ pointData.extraText = getExtraText(trace, di, pointData, cd[0].t.labels);
pointData.hovertemplate = trace.hovertemplate;
return [pointData];
};
-function getExtraText(trace, pt, axis, labels) {
- if(trace.hovertemplate) {
- return;
- }
+function getExtraText(trace, pt, pointData, labels) {
+ if(trace.hovertemplate) return;
var hoverinfo = pt.hi || trace.hoverinfo;
@@ -88,18 +89,16 @@ function getExtraText(trace, pt, axis, labels) {
var hasText = (parts.indexOf('text') !== -1);
var text = [];
- function format(val) {
- return Axes.tickText(axis, axis.c2l(val), 'hover').text + '\u00B0';
- }
+ function format(val) { return val + '\u00B0'; }
if(hasLocation) {
text.push(pt.loc);
} else if(hasLon && hasLat) {
- text.push('(' + format(pt.lonlat[0]) + ', ' + format(pt.lonlat[1]) + ')');
+ text.push('(' + format(pointData.lonLabel) + ', ' + format(pointData.latLabel) + ')');
} else if(hasLon) {
- text.push(labels.lon + format(pt.lonlat[0]));
+ text.push(labels.lon + format(pointData.lonLabel));
} else if(hasLat) {
- text.push(labels.lat + format(pt.lonlat[1]));
+ text.push(labels.lat + format(pointData.latLabel));
}
if(hasText) {
diff --git a/src/traces/scatterpolar/hover.js b/src/traces/scatterpolar/hover.js
index 7e1afa92116..fbe073e7f26 100644
--- a/src/traces/scatterpolar/hover.js
+++ b/src/traces/scatterpolar/hover.js
@@ -42,26 +42,26 @@ function makeHoverPointText(cdi, trace, subplot, pointData) {
radialAxis._hovertitle = 'r';
angularAxis._hovertitle = 'θ';
+ var rVal = radialAxis.c2l(cdi.r);
+ pointData.rLabel = Axes.tickText(radialAxis, rVal, 'hover').text;
+
+ // N.B here the ° sign is part of the formatted value for thetaunit:'degrees'
+ var thetaVal = angularAxis.thetaunit === 'degrees' ? Lib.rad2deg(cdi.theta) : cdi.theta;
+ pointData.thetaLabel = Axes.tickText(angularAxis, thetaVal, 'hover').text;
+
var hoverinfo = cdi.hi || trace.hoverinfo;
var text = [];
function textPart(ax, val) {
- text.push(ax._hovertitle + ': ' + Axes.tickText(ax, val, 'hover').text);
+ text.push(ax._hovertitle + ': ' + val);
}
if(!trace.hovertemplate) {
var parts = hoverinfo.split('+');
if(parts.indexOf('all') !== -1) parts = ['r', 'theta', 'text'];
- if(parts.indexOf('r') !== -1) {
- textPart(radialAxis, radialAxis.c2l(cdi.r));
- }
- if(parts.indexOf('theta') !== -1) {
- var theta = cdi.theta;
- textPart(
- angularAxis,
- angularAxis.thetaunit === 'degrees' ? Lib.rad2deg(theta) : theta
- );
- }
+ if(parts.indexOf('r') !== -1) textPart(radialAxis, pointData.rLabel);
+ if(parts.indexOf('theta') !== -1) textPart(angularAxis, pointData.thetaLabel);
+
if(parts.indexOf('text') !== -1 && pointData.text) {
text.push(pointData.text);
delete pointData.text;
diff --git a/src/traces/scatterternary/hover.js b/src/traces/scatterternary/hover.js
index eaf0ad26421..49079833597 100644
--- a/src/traces/scatterternary/hover.js
+++ b/src/traces/scatterternary/hover.js
@@ -47,21 +47,24 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
newPointData.xLabelVal = undefined;
newPointData.yLabelVal = undefined;
- // TODO: nice formatting, and label by axis title, for a, b, and c?
- var trace = newPointData.trace;
var ternary = newPointData.subplot;
+ newPointData.aLabel = Axes.tickText(ternary.aaxis, cdi.a, 'hover').text;
+ newPointData.bLabel = Axes.tickText(ternary.baxis, cdi.b, 'hover').text;
+ newPointData.cLabel = Axes.tickText(ternary.caxis, cdi.c, 'hover').text;
+
+ var trace = newPointData.trace;
var hoverinfo = cdi.hi || trace.hoverinfo;
var text = [];
function textPart(ax, val) {
- text.push(ax._hovertitle + ': ' + Axes.tickText(ax, val, 'hover').text);
+ text.push(ax._hovertitle + ': ' + val);
}
if(!trace.hovertemplate) {
var parts = hoverinfo.split('+');
if(parts.indexOf('all') !== -1) parts = ['a', 'b', 'c'];
- if(parts.indexOf('a') !== -1) textPart(ternary.aaxis, cdi.a);
- if(parts.indexOf('b') !== -1) textPart(ternary.baxis, cdi.b);
- if(parts.indexOf('c') !== -1) textPart(ternary.caxis, cdi.c);
+ if(parts.indexOf('a') !== -1) textPart(ternary.aaxis, newPointData.aLabel);
+ if(parts.indexOf('b') !== -1) textPart(ternary.baxis, newPointData.bLabel);
+ if(parts.indexOf('c') !== -1) textPart(ternary.caxis, newPointData.cLabel);
}
newPointData.extraText = text.join('
');
newPointData.hovertemplate = trace.hovertemplate;
diff --git a/test/jasmine/tests/barpolar_test.js b/test/jasmine/tests/barpolar_test.js
index 8de6bd291fc..76c97c9e13a 100644
--- a/test/jasmine/tests/barpolar_test.js
+++ b/test/jasmine/tests/barpolar_test.js
@@ -128,6 +128,8 @@ describe('Test barpolar hover:', function() {
index: 0,
x: 263.33,
y: 200,
+ rLabel: '1',
+ thetaLabel: '0°',
hovertemplate: 'tpl',
color: '#1f77b4'
}
diff --git a/test/jasmine/tests/choropleth_test.js b/test/jasmine/tests/choropleth_test.js
index ba745b55d2c..83860838215 100644
--- a/test/jasmine/tests/choropleth_test.js
+++ b/test/jasmine/tests/choropleth_test.js
@@ -200,6 +200,31 @@ describe('Test choropleth hover:', function() {
)
.then(done);
});
+
+ describe('should preserve z formatting hovetemplate equivalence', function() {
+ var base = function() {
+ return {
+ data: [{
+ type: 'choropleth',
+ locations: ['RUS'],
+ z: [10.02132132143214321]
+ }]
+ };
+ };
+
+ var pos = [400, 160];
+ var exp = ['10.02132', 'RUS'];
+
+ it('- base case (truncate z decimals)', function(done) {
+ run(pos, base(), exp).then(done);
+ });
+
+ it('- hovertemplate case (same z truncation)', function(done) {
+ var fig = base();
+ fig.hovertemplate = '%{z}%{location}';
+ run(pos, fig, exp).then(done);
+ });
+ });
});
describe('choropleth drawing', function() {
diff --git a/test/jasmine/tests/scattergeo_test.js b/test/jasmine/tests/scattergeo_test.js
index f92f63ddc5a..d8b7c659479 100644
--- a/test/jasmine/tests/scattergeo_test.js
+++ b/test/jasmine/tests/scattergeo_test.js
@@ -358,6 +358,32 @@ describe('Test scattergeo hover', function() {
.catch(failTest)
.then(done);
});
+
+ describe('should preserve lon/lat formatting hovetemplate equivalence', function() {
+ var pos = [381, 221];
+ var exp = ['(10.00012°, 10.00088°)\nA'];
+
+ it('- base case (truncate z decimals)', function(done) {
+ Plotly.restyle(gd, {
+ lon: [[10.0001221321]],
+ lat: [[10.00087683]]
+ })
+ .then(function() { check(pos, exp); })
+ .catch(failTest)
+ .then(done);
+ });
+
+ it('- hovertemplate case (same lon/lat truncation)', function(done) {
+ Plotly.restyle(gd, {
+ lon: [[10.0001221321]],
+ lat: [[10.00087683]],
+ hovertemplate: '(%{lon}°, %{lat}°)
%{text}'
+ })
+ .then(function() { check(pos, exp); })
+ .catch(failTest)
+ .then(done);
+ });
+ });
});
describe('scattergeo drawing', function() {
diff --git a/test/jasmine/tests/scatterpolar_test.js b/test/jasmine/tests/scatterpolar_test.js
index 43045b15398..69d26588719 100644
--- a/test/jasmine/tests/scatterpolar_test.js
+++ b/test/jasmine/tests/scatterpolar_test.js
@@ -115,7 +115,7 @@ describe('Test scatterpolar hover:', function() {
fig.data[2].hovertemplate = 'template %{r} %{theta}';
return fig;
},
- nums: 'template 4.02289202968 128.342009045',
+ nums: 'template 4.022892 128.342°',
name: 'Trial 3'
}, {
desc: 'with hovertemplate and empty trace name',
@@ -124,7 +124,7 @@ describe('Test scatterpolar hover:', function() {
fig.data[2].name = '';
return fig;
},
- nums: 'template 4.02289202968 128.342009045',
+ nums: 'template 4.022892 128.342°',
name: ''
}, {
desc: '(no labels - out of sector)',
diff --git a/test/jasmine/tests/scatterpolargl_test.js b/test/jasmine/tests/scatterpolargl_test.js
index be878adece3..5e6d2f2866e 100644
--- a/test/jasmine/tests/scatterpolargl_test.js
+++ b/test/jasmine/tests/scatterpolargl_test.js
@@ -50,7 +50,7 @@ describe('Test scatterpolargl hover:', function() {
fig.data[2].hovertemplate = 'template %{r} %{theta}';
return fig;
},
- nums: 'template 3.88601339194 125.282157112',
+ nums: 'template 3.886013 125.2822°',
name: 'Trial 3'
}, {
desc: '(no labels - out of sector)',
diff --git a/test/jasmine/tests/scatterternary_test.js b/test/jasmine/tests/scatterternary_test.js
index 7a45fa2a4a1..0cabd822e5d 100644
--- a/test/jasmine/tests/scatterternary_test.js
+++ b/test/jasmine/tests/scatterternary_test.js
@@ -422,6 +422,9 @@ describe('scatterternary hover', function() {
.then(function() {
scatterPointData = _hover(gd, xval, yval, hovermode);
expect(scatterPointData[0].hovertemplate).toEqual('tpl');
+ expect(scatterPointData[0].aLabel).toBe('0.3333333');
+ expect(scatterPointData[0].bLabel).toBe('0.1111111');
+ expect(scatterPointData[0].cLabel).toBe('0.5555556');
})
.catch(failTest)
.then(done);