Skip to content

Commit f0d7961

Browse files
authored
Merge pull request #7619 from plotly/add-hovertemplate-for-candlestick
Implement `hovertemplate` for `candlestick` and `ohlc` traces
2 parents 1a52bbc + fb6e114 commit f0d7961

File tree

9 files changed

+827
-641
lines changed

9 files changed

+827
-641
lines changed

draftlogs/7619_add.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Add `hovertemplate` for `candlestick` and `ohlc` traces [[#7619](https://github.com/plotly/plotly.js/pull/7619)]

src/components/fx/hover.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,11 @@ function getHoverLabelText(d, showCommonLabel, hovermode, fullLayout, t0, g) {
16621662
text = name;
16631663
}
16641664

1665-
// hovertemplate
1665+
// Ignore hovertemplate if hoverlabel.split is set
1666+
// This ensures correct behavior of hoverlabel.split for candlestick and OHLC traces
1667+
// Not very elegant but it works
1668+
if (d.trace?.hoverlabel?.split) d.hovertemplate = '';
1669+
16661670
const { hovertemplate = false } = d;
16671671
if (hovertemplate) {
16681672
const labels = d.hovertemplateLabels || d;

src/traces/candlestick/attributes.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var boxAttrs = require('../box/attributes');
88
function directionAttrs(lineColorDefault) {
99
return {
1010
line: {
11-
color: extendFlat({}, boxAttrs.line.color, {dflt: lineColorDefault}),
11+
color: extendFlat({}, boxAttrs.line.color, { dflt: lineColorDefault }),
1212
width: boxAttrs.line.width,
1313
editType: 'style'
1414
},
@@ -49,6 +49,8 @@ module.exports = {
4949

5050
text: OHLCattrs.text,
5151
hovertext: OHLCattrs.hovertext,
52+
hovertemplate: OHLCattrs.hovertemplate,
53+
hovertemplatefallback: OHLCattrs.hovertemplatefallback,
5254

5355
whiskerwidth: extendFlat({}, boxAttrs.whiskerwidth, { dflt: 0 }),
5456

src/traces/candlestick/defaults.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
1212
}
1313

1414
var len = handleOHLC(traceIn, traceOut, coerce, layout);
15-
if(!len) {
15+
if (!len) {
1616
traceOut.visible = false;
1717
return;
1818
}
1919

20-
handlePeriodDefaults(traceIn, traceOut, layout, coerce, {x: true});
20+
handlePeriodDefaults(traceIn, traceOut, layout, coerce, { x: true });
2121
coerce('xhoverformat');
2222
coerce('yhoverformat');
2323

@@ -28,6 +28,9 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
2828

2929
coerce('text');
3030
coerce('hovertext');
31+
coerce('hovertemplate');
32+
coerce('hovertemplatefallback');
33+
3134
coerce('whiskerwidth');
3235

3336
layout._requestRangeslider[traceOut.xaxis] = true;

src/traces/ohlc/attributes.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
var extendFlat = require('../../lib').extendFlat;
44
var scatterAttrs = require('../scatter/attributes');
55
var axisHoverFormat = require('../../plots/cartesian/axis_format_attributes').axisHoverFormat;
6+
const { hovertemplateAttrs, templatefallbackAttrs } = require('../../plots/template_attributes');
67
var dash = require('../../components/drawing/attributes').dash;
78
var fxAttrs = require('../../components/fx/attributes');
89
var delta = require('../../constants/delta.js');
@@ -15,7 +16,7 @@ var lineAttrs = scatterAttrs.line;
1516
function directionAttrs(lineColorDefault) {
1617
return {
1718
line: {
18-
color: extendFlat({}, lineAttrs.color, {dflt: lineColorDefault}),
19+
color: extendFlat({}, lineAttrs.color, { dflt: lineColorDefault }),
1920
width: lineAttrs.width,
2021
dash: dash,
2122
editType: 'style'
@@ -25,7 +26,6 @@ function directionAttrs(lineColorDefault) {
2526
}
2627

2728
module.exports = {
28-
2929
xperiod: scatterAttrs.xperiod,
3030
xperiod0: scatterAttrs.xperiod0,
3131
xperiodalignment: scatterAttrs.xperiodalignment,
@@ -35,10 +35,7 @@ module.exports = {
3535
x: {
3636
valType: 'data_array',
3737
editType: 'calc+clearAxisTypes',
38-
description: [
39-
'Sets the x coordinates.',
40-
'If absent, linear coordinate will be generated.'
41-
].join(' ')
38+
description: 'Sets the x coordinates. If absent, linear coordinate will be generated.'
4239
},
4340

4441
open: {
@@ -99,7 +96,7 @@ module.exports = {
9996
'If a single string, the same string appears over',
10097
'all the data points.',
10198
'If an array of string, the items are mapped in order to',
102-
'this trace\'s sample points.'
99+
"this trace's sample points."
103100
].join(' ')
104101
},
105102
hovertext: {
@@ -109,17 +106,20 @@ module.exports = {
109106
editType: 'calc',
110107
description: 'Same as `text`.'
111108
},
112-
109+
hovertemplate: hovertemplateAttrs(
110+
{},
111+
{
112+
keys: ['open', 'high', 'low', 'close']
113+
}
114+
),
115+
hovertemplatefallback: templatefallbackAttrs(),
113116
tickwidth: {
114117
valType: 'number',
115118
min: 0,
116119
max: 0.5,
117120
dflt: 0.3,
118121
editType: 'calc',
119-
description: [
120-
'Sets the width of the open/close tick marks',
121-
'relative to the *x* minimal interval.'
122-
].join(' ')
122+
description: 'Sets the width of the open/close tick marks relative to the *x* minimal interval.'
123123
},
124124

125125
hoverlabel: extendFlat({}, fxAttrs.hoverlabel, {
@@ -128,8 +128,8 @@ module.exports = {
128128
dflt: false,
129129
editType: 'style',
130130
description: [
131-
'Show hover information (open, close, high, low) in',
132-
'separate labels.'
131+
'Show hover information (open, close, high, low) in separate labels, rather than a single unified label.',
132+
'Default: *false*. When set to *true*, `hovertemplate` is ignored.'
133133
].join(' ')
134134
}
135135
}),

src/traces/ohlc/defaults.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
1111
}
1212

1313
var len = handleOHLC(traceIn, traceOut, coerce, layout);
14-
if(!len) {
14+
if (!len) {
1515
traceOut.visible = false;
1616
return;
1717
}
1818

19-
handlePeriodDefaults(traceIn, traceOut, layout, coerce, {x: true});
19+
handlePeriodDefaults(traceIn, traceOut, layout, coerce, { x: true });
2020
coerce('xhoverformat');
2121
coerce('yhoverformat');
2222

@@ -28,6 +28,9 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
2828

2929
coerce('text');
3030
coerce('hovertext');
31+
coerce('hovertemplate');
32+
coerce('hovertemplatefallback');
33+
3134
coerce('tickwidth');
3235

3336
layout._requestRangeslider[traceOut.xaxis] = true;

src/traces/ohlc/hover.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,11 @@ function hoverSplit(pointData, xval, yval, hovermode) {
9999
// skip the rest (for this trace) if we didn't find a close point
100100
if(!closestPoint) return [];
101101

102-
var cdIndex = closestPoint.index;
103-
var di = cd[cdIndex];
104-
var hoverinfo = di.hi || trace.hoverinfo;
105-
var hoverParts = hoverinfo.split('+');
106-
var isAll = hoverinfo === 'all';
107-
var hasY = isAll || hoverParts.indexOf('y') !== -1;
102+
var di = cd[closestPoint.index];
103+
var hoverinfo = di.hi || trace.hoverinfo || '';
108104

109-
// similar to hoverOnPoints, we return nothing
110-
// if all or y is not present.
111-
if(!hasY) return [];
105+
// If hoverinfo is 'none' or 'skip', we don't show any hover labels
106+
if (hoverinfo === 'none' || hoverinfo === 'skip') return [];
112107

113108
var attrs = ['high', 'open', 'close', 'low'];
114109

@@ -165,7 +160,7 @@ function hoverOnPoints(pointData, xval, yval, hovermode) {
165160
return t.labels[attr] + Axes.hoverLabelText(ya, trace[attr][i], trace.yhoverformat);
166161
}
167162

168-
var hoverinfo = di.hi || trace.hoverinfo;
163+
var hoverinfo = di.hi || trace.hoverinfo || '';
169164
var hoverParts = hoverinfo.split('+');
170165
var isAll = hoverinfo === 'all';
171166
var hasY = isAll || hoverParts.indexOf('y') !== -1;

0 commit comments

Comments
 (0)