Skip to content

Commit a892b26

Browse files
committed
olhc: add custom hover text
- by filling in a 'text' array in the generated traces
1 parent ea3c5a1 commit a892b26

File tree

2 files changed

+122
-14
lines changed

2 files changed

+122
-14
lines changed

src/traces/ohlc/transform.js

+70-14
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
var Lib = require('../../lib');
1313
var helpers = require('./helpers');
14+
var Axes = require('../../plots/cartesian/axes');
1415
var axisIds = require('../../plots/cartesian/axis_ids');
1516

1617
exports.moduleType = 'transform';
@@ -57,11 +58,11 @@ function makeTrace(traceIn, state, direction) {
5758
connectgaps: false,
5859

5960
visible: traceIn.visible,
60-
hoverinfo: traceIn.hoverinfo,
6161
opacity: traceIn.opacity,
6262
xaxis: traceIn.xaxis,
6363
yaxis: traceIn.yaxis,
6464

65+
hoverinfo: makeHoverInfo(traceIn),
6566
transforms: helpers.makeTransform(traceIn, state, direction)
6667
};
6768

@@ -94,43 +95,98 @@ function makeTrace(traceIn, state, direction) {
9495
return traceOut;
9596
}
9697

98+
// let scatter hoverPoint format 'x' coordinates, if desired
99+
function makeHoverInfo(traceIn) {
100+
var hoverinfo = traceIn.hoverinfo;
101+
102+
if(hoverinfo === 'all') return 'x+text';
103+
104+
var parts = hoverinfo.split('+'),
105+
hasX = parts.indexOf('x') !== -1,
106+
hasText = parts.indexOf('text') !== -1;
107+
108+
if(hasX) {
109+
if(hasText) return 'x+text';
110+
else return 'x';
111+
112+
}
113+
else return 'text';
114+
}
115+
97116
exports.calcTransform = function calcTransform(gd, trace, opts) {
98117
var direction = opts.direction,
99-
filterFn = helpers.getFilterFn(direction),
100-
ax = axisIds.getFromTrace(gd, trace, 'x'),
101-
tickWidth = convertTickWidth(trace.x, ax, trace._fullInput.tickwidth);
118+
filterFn = helpers.getFilterFn(direction);
119+
120+
var xa = axisIds.getFromTrace(gd, trace, 'x'),
121+
ya = axisIds.getFromTrace(gd, trace, 'y'),
122+
tickWidth = convertTickWidth(trace.x, xa, trace._fullInput.tickwidth);
102123

103124
var open = trace.open,
104125
high = trace.high,
105126
low = trace.low,
106-
close = trace.close;
127+
close = trace.close,
128+
textIn = trace.text;
107129

108130
var len = open.length,
109131
x = [],
110-
y = [];
132+
y = [],
133+
textOut = [];
134+
135+
var getXItem = trace._fullInput.x ?
136+
function(i) { return xa.d2c(trace.x[i]); } :
137+
function(i) { return i; };
111138

112-
var appendX = trace._fullInput.x ?
113-
function(i) {
114-
var v = ax.d2c(trace.x[i]);
115-
x.push(v - tickWidth, v, v, v, v, v + tickWidth, null);
116-
} :
117-
function(i) {
118-
x.push(i - tickWidth, i, i, i, i, i + tickWidth, null);
119-
};
139+
var getTextItem = Array.isArray(textIn) ?
140+
function(i) { return textIn[i] || ''; } :
141+
function() { return textIn; };
142+
143+
var appendX = function(i) {
144+
var v = getXItem(i);
145+
x.push(v - tickWidth, v, v, v, v, v + tickWidth, null);
146+
};
120147

121148
var appendY = function(o, h, l, c) {
122149
y.push(o, o, h, l, c, c, null);
123150
};
124151

152+
var format = function(ax, val) {
153+
return Axes.tickText(ax, ax.c2l(val), 'hover').text;
154+
};
155+
156+
var hoverinfo = trace._fullInput.hoverinfo,
157+
hoverParts = hoverinfo.split('+'),
158+
hasAll = hoverinfo === 'all',
159+
hasY = hasAll || hoverParts.indexOf('y') !== -1,
160+
hasText = hasAll || hoverParts.indexOf('text') !== -1;
161+
162+
var appendText = function(i, o, h, l, c) {
163+
var t = [];
164+
165+
if(hasY) {
166+
t.push('Open: ' + format(ya, o));
167+
t.push('High: ' + format(ya, h));
168+
t.push('Low: ' + format(ya, l));
169+
t.push('Close: ' + format(ya, c));
170+
}
171+
172+
if(hasText) t.push(getTextItem(i));
173+
174+
var _t = t.join('<br>');
175+
176+
textOut.push(_t, _t, _t, _t, _t, _t, null);
177+
};
178+
125179
for(var i = 0; i < len; i++) {
126180
if(filterFn(open[i], close[i])) {
127181
appendX(i);
128182
appendY(open[i], high[i], low[i], close[i]);
183+
appendText(i, open[i], high[i], low[i], close[i]);
129184
}
130185
}
131186

132187
trace.x = x;
133188
trace.y = y;
189+
trace.text = textOut;
134190
};
135191

136192
function convertTickWidth(coords, ax, tickWidth) {

test/jasmine/tests/finance_test.js

+52
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,58 @@ describe('finance charts calc transforms:', function() {
323323
]);
324324
});
325325

326+
it('should fill *text* for OHLC hover labels', function() {
327+
var trace0 = Lib.extendDeep({}, mock0, {
328+
type: 'ohlc',
329+
text: ['A', 'B', 'C', 'D']
330+
});
331+
332+
var trace1 = Lib.extendDeep({}, mock1, {
333+
type: 'ohlc',
334+
text: 'IMPORTANT',
335+
hoverinfo: 'x+text',
336+
xaxis: 'x2'
337+
});
338+
339+
var trace2 = Lib.extendDeep({}, mock1, {
340+
type: 'ohlc',
341+
hoverinfo: 'y',
342+
xaxis: 'x2'
343+
});
344+
345+
var trace3 = Lib.extendDeep({}, mock0, {
346+
type: 'ohlc',
347+
hoverinfo: 'x',
348+
});
349+
350+
var out = _calc([trace0, trace1, trace2, trace3]);
351+
352+
expect(out[0].hoverinfo).toEqual('x+text');
353+
expect(out[0].text[0])
354+
.toEqual('Open: 33.01<br>High: 34.2<br>Low: 31.7<br>Close: 34.1<br>A');
355+
expect(out[0].hoverinfo).toEqual('x+text');
356+
expect(out[1].text[0])
357+
.toEqual('Open: 33.31<br>High: 34.37<br>Low: 30.75<br>Close: 31.93<br>B');
358+
359+
expect(out[2].hoverinfo).toEqual('x+text');
360+
expect(out[2].text[0]).toEqual('IMPORTANT');
361+
362+
expect(out[3].hoverinfo).toEqual('x+text');
363+
expect(out[3].text[0]).toEqual('IMPORTANT');
364+
365+
expect(out[4].hoverinfo).toEqual('text');
366+
expect(out[4].text[0])
367+
.toEqual('Open: 33.01<br>High: 34.2<br>Low: 31.7<br>Close: 34.1');
368+
expect(out[5].hoverinfo).toEqual('text');
369+
expect(out[5].text[0])
370+
.toEqual('Open: 33.31<br>High: 34.37<br>Low: 30.75<br>Close: 31.93');
371+
372+
expect(out[6].hoverinfo).toEqual('x');
373+
expect(out[6].text[0]).toEqual('');
374+
expect(out[7].hoverinfo).toEqual('x');
375+
expect(out[7].text[0]).toEqual('');
376+
});
377+
326378
it('should work with *filter* transforms', function() {
327379
var trace0 = Lib.extendDeep({}, mock1, {
328380
type: 'ohlc',

0 commit comments

Comments
 (0)