Skip to content

Commit d0d7638

Browse files
authored
Merge pull request #7439 from plotly/unifiedhovertemplate
feat: Add `unifiedhovertitle` to format unified hover title
2 parents 0bc4794 + c99340d commit d0d7638

File tree

8 files changed

+126
-2
lines changed

8 files changed

+126
-2
lines changed

draftlogs/7439_add.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add `unifiedhovertitle.text` to format unified hover titles [[#7439](https://github.com/plotly/plotly.js/pull/7439)]

src/components/fx/hover.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1211,10 +1211,26 @@ function createHoverText(hoverData, opts) {
12111211
// mock legend
12121212
var hoverlabel = fullLayout.hoverlabel;
12131213
var font = hoverlabel.font;
1214+
1215+
var item0 = groupedHoverData[0];
1216+
1217+
var unifiedhovertitleText = ((
1218+
hovermode === 'x unified' ?
1219+
item0.xa :
1220+
item0.ya
1221+
).unifiedhovertitle || {}).text;
1222+
1223+
var mainText = !unifiedhovertitleText ? t0 :
1224+
Lib.hovertemplateString(unifiedhovertitleText, {}, fullLayout._d3locale,
1225+
hovermode === 'x unified' ?
1226+
{xa: item0.xa, x: item0.xVal} :
1227+
{ya: item0.ya, y: item0.yVal}
1228+
);
1229+
12141230
var mockLayoutIn = {
12151231
showlegend: true,
12161232
legend: {
1217-
title: {text: t0, font: font},
1233+
title: {text: mainText, font: font},
12181234
font: font,
12191235
bgcolor: hoverlabel.bgcolor,
12201236
bordercolor: hoverlabel.bordercolor,

src/plots/cartesian/axis_defaults.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,12 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce,
100100

101101
handleCategoryOrderDefaults(containerIn, containerOut, coerce, options);
102102

103-
if(axType !== 'category' && !options.noHover) coerce('hoverformat');
103+
if(!options.noHover) {
104+
if(axType !== 'category') coerce('hoverformat');
105+
if(!options.noUnifiedhovertitle) {
106+
coerce('unifiedhovertitle.text');
107+
}
108+
}
104109

105110
var dfltColor = coerce('color');
106111
// if axis.color was provided, use it for fonts too; otherwise,

src/plots/cartesian/layout_attributes.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ var colorAttrs = require('../../components/color/attributes');
55
var dash = require('../../components/drawing/attributes').dash;
66
var extendFlat = require('../../lib/extend').extendFlat;
77
var templatedArray = require('../../plot_api/plot_template').templatedArray;
8+
var templateFormatStringDescription = require('../../plots/template_attributes').templateFormatStringDescription;
89
var descriptionWithDates = require('../../plots/cartesian/axis_format_attributes').descriptionWithDates;
910

1011
var ONEDAY = require('../../constants/numerical').ONEDAY;
@@ -987,6 +988,18 @@ module.exports = {
987988
editType: 'none',
988989
description: descriptionWithDates('hover text')
989990
},
991+
unifiedhovertitle: {
992+
text : {
993+
valType: 'string',
994+
dflt: '',
995+
editType: 'none',
996+
description: [
997+
'Template string used for rendering the title that appear on x or y unified hover box.',
998+
templateFormatStringDescription()
999+
].join(' ')
1000+
},
1001+
editType: 'none'
1002+
},
9901003
// lines and grids
9911004
showline: {
9921005
valType: 'boolean',

src/plots/gl3d/layout/axis_defaults.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, options) {
5252
noTicklabelposition: true,
5353
noTicklabeloverflow: true,
5454
noInsiderange: true,
55+
noUnifiedhovertitle: true,
5556
bgColor: options.bgColor,
5657
calendar: options.calendar
5758
},

src/plots/template_attributes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function templateFormatStringDescription(opts) {
2222
'for details on the date formatting syntax.'
2323
].join(' ');
2424
}
25+
exports.templateFormatStringDescription = templateFormatStringDescription;
2526

2627
function shapeTemplateFormatStringDescription() {
2728
return [

test/jasmine/tests/hover_label_test.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6901,6 +6901,73 @@ describe('hovermode: (x|y)unified', function() {
69016901
})
69026902
.then(done, done.fail);
69036903
});
6904+
6905+
it('should format title of unified hover in respect to `unifiedhovertitle` linear axis', function(done) {
6906+
Plotly.newPlot(gd, [{
6907+
type: 'bar',
6908+
y: [1, 2, 3]
6909+
}, {
6910+
type: 'scatter',
6911+
y: [2, 3, 1]
6912+
}], {
6913+
xaxis: {
6914+
unifiedhovertitle: { text: 'X: %{x:.2f}' },
6915+
},
6916+
hovermode: 'x unified',
6917+
showlegend: false,
6918+
width: 500,
6919+
height: 500,
6920+
margin: {
6921+
t: 50,
6922+
b: 50,
6923+
l: 50,
6924+
r: 50
6925+
}
6926+
})
6927+
.then(function() {
6928+
_hover(gd, { xpx: 200, ypx: 200 });
6929+
assertLabel({title: 'X: 1.00', items: [
6930+
'trace 0 : 2',
6931+
'trace 1 : 3'
6932+
]});
6933+
})
6934+
.then(done, done.fail);
6935+
});
6936+
6937+
it('should format title of unified hover in respect to `unifiedhovertitle` date axis', function(done) {
6938+
Plotly.newPlot(gd, [{
6939+
type: 'bar',
6940+
x: ['2000-01-01', '2000-02-01', '2000-03-01'],
6941+
y: [1, 2, 3]
6942+
}, {
6943+
type: 'scatter',
6944+
x: ['2000-01-01', '2000-02-01', '2000-03-01'],
6945+
y: [2, 3, 1]
6946+
}], {
6947+
xaxis: {
6948+
type: 'date',
6949+
unifiedhovertitle: { text: 'X: %{x|%x %X}' },
6950+
},
6951+
hovermode: 'x unified',
6952+
showlegend: false,
6953+
width: 500,
6954+
height: 500,
6955+
margin: {
6956+
t: 50,
6957+
b: 50,
6958+
l: 50,
6959+
r: 50
6960+
}
6961+
})
6962+
.then(function() {
6963+
_hover(gd, { xpx: 200, ypx: 200 });
6964+
assertLabel({title: 'X: 02/01/2000 00:00:00', items: [
6965+
'trace 0 : 2',
6966+
'trace 1 : 3'
6967+
]});
6968+
})
6969+
.then(done, done.fail);
6970+
});
69046971
});
69056972

69066973
describe('hover on traces with (x|y)hoverformat', function() {

test/plot-schema.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14997,6 +14997,16 @@
1499714997
"editType": "none",
1499814998
"valType": "any"
1499914999
},
15000+
"unifiedhovertitle": {
15001+
"editType": "none",
15002+
"role": "object",
15003+
"text": {
15004+
"description": "Template string used for rendering the title that appear on x or y unified hover box. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax.",
15005+
"dflt": "",
15006+
"editType": "none",
15007+
"valType": "string"
15008+
}
15009+
},
1500015010
"visible": {
1500115011
"description": "A single toggle to hide the axis while preserving interaction like dragging. Default is true when a cheater plot is present on the axis, otherwise false",
1500215012
"editType": "plot",
@@ -16265,6 +16275,16 @@
1626516275
"editType": "none",
1626616276
"valType": "any"
1626716277
},
16278+
"unifiedhovertitle": {
16279+
"editType": "none",
16280+
"role": "object",
16281+
"text": {
16282+
"description": "Template string used for rendering the title that appear on x or y unified hover box. Variables are inserted using %{variable}, for example \"y: %{y}\". Numbers are formatted using d3-format's syntax %{variable:d3-format}, for example \"Price: %{y:$.2f}\". https://github.com/d3/d3-format/tree/v1.4.5#d3-format for details on the formatting syntax. Dates are formatted using d3-time-format's syntax %{variable|d3-time-format}, for example \"Day: %{2019-01-01|%A}\". https://github.com/d3/d3-time-format/tree/v2.2.3#locale_format for details on the date formatting syntax.",
16283+
"dflt": "",
16284+
"editType": "none",
16285+
"valType": "string"
16286+
}
16287+
},
1626816288
"visible": {
1626916289
"description": "A single toggle to hide the axis while preserving interaction like dragging. Default is true when a cheater plot is present on the axis, otherwise false",
1627016290
"editType": "plot",

0 commit comments

Comments
 (0)