Skip to content

Commit 4c3b4b4

Browse files
committed
make finance trace coord to gd.caldata[i] match 1-to-1
.. so that pointing to a particular item using Fx.hover can be done using eventData 'pointNumber'. Tag the empty (or null) items using `calcdata[i][j].empty`
1 parent 2e1bb3c commit 4c3b4b4

File tree

6 files changed

+73
-4
lines changed

6 files changed

+73
-4
lines changed

src/traces/box/plot.js

+2
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ function plotBoxAndWhiskers(sel, axes, trace, t) {
100100
paths.exit().remove();
101101

102102
paths.each(function(d) {
103+
if(d.empty) return 'M0,0Z';
104+
103105
var pos = d.pos;
104106
var posc = posAxis.c2p(pos + bPos, true) + bPosPxOffset;
105107
var pos0 = posAxis.c2p(pos + bPos - bdPos0, true) + bPosPxOffset;

src/traces/box/style.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,15 @@ function style(gd, cd) {
3232

3333
if(trace.type === 'candlestick') {
3434
allBoxes.each(function(boxData) {
35+
if(boxData.empty) return;
36+
3537
var thisBox = d3.select(this);
3638
var container = trace[boxData.dir]; // dir = 'increasing' or 'decreasing'
3739
styleBox(thisBox, container.line.width, container.line.color, container.fillcolor);
3840
// TODO: custom selection style for candlesticks
3941
thisBox.style('opacity', trace.selectedpoints && !boxData.selected ? 0.3 : 1);
4042
});
41-
}
42-
else {
43+
} else {
4344
styleBox(allBoxes, lineWidth, trace.line.color, trace.fillcolor);
4445
el.selectAll('path.mean')
4546
.style({

src/traces/ohlc/calc.js

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ function calcCommon(gd, trace, x, ya, ptFunc) {
8989
if(hasTextArray) pt.tx = trace.text[i];
9090

9191
cd.push(pt);
92+
} else {
93+
cd.push({empty: true});
9294
}
9395
}
9496

src/traces/ohlc/plot.js

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ module.exports = function plot(gd, plotinfo, cdOHLC, ohlcLayer) {
3737
paths.exit().remove();
3838

3939
paths.attr('d', function(d) {
40+
if(d.empty) return 'M0,0Z';
41+
4042
var x = xa.c2p(d.pos, true);
4143
var xo = xa.c2p(d.pos - tickLen, true);
4244
var xc = xa.c2p(d.pos + tickLen, true);

src/traces/ohlc/style.js

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ module.exports = function style(gd, cd) {
2323
var trace = d[0].trace;
2424

2525
d3.select(this).selectAll('path').each(function(di) {
26+
if(di.empty) return;
27+
2628
var dirLine = trace[di.dir].line;
2729
d3.select(this)
2830
.style('fill', 'none')

test/jasmine/tests/finance_test.js

+62-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ var d3 = require('d3');
66
var createGraphDiv = require('../assets/create_graph_div');
77
var destroyGraphDiv = require('../assets/destroy_graph_div');
88
var supplyAllDefaults = require('../assets/supply_defaults');
9+
var hover = require('../assets/hover');
10+
var assertHoverLabelContent = require('../assets/custom_assertions').assertHoverLabelContent;
911
var failTest = require('../assets/fail_test');
1012

1113
var mock0 = {
@@ -426,15 +428,22 @@ describe('finance charts calc', function() {
426428
addJunk(trace1);
427429

428430
var out = _calcRaw([trace0, trace1]);
429-
var indices = [0, 1, 2, 3, 4, 5, 6, 7];
431+
var indices = [0, 1, 2, 3, 4, 5, 6, 7, undefined, undefined, undefined, undefined];
430432
var i = 'increasing';
431433
var d = 'decreasing';
432-
var directions = [i, d, d, i, d, i, d, i];
434+
var directions = [i, d, d, i, d, i, d, i, undefined, undefined, undefined, undefined];
435+
var empties = [
436+
undefined, undefined, undefined, undefined,
437+
undefined, undefined, undefined, undefined,
438+
true, true, true, true
439+
];
433440

434441
expect(mapGet(out[0], 'pos')).toEqual(indices);
435442
expect(mapGet(out[0], 'dir')).toEqual(directions);
436443
expect(mapGet(out[1], 'pos')).toEqual(indices);
437444
expect(mapGet(out[1], 'dir')).toEqual(directions);
445+
expect(mapGet(out[0], 'empty')).toEqual(empties);
446+
expect(mapGet(out[1], 'empty')).toEqual(empties);
438447
});
439448

440449
it('should work with *filter* transforms', function() {
@@ -1186,3 +1195,54 @@ describe('finance trace hover:', function() {
11861195
});
11871196
});
11881197
});
1198+
1199+
describe('finance trace hover via Fx.hover():', function() {
1200+
var gd;
1201+
1202+
beforeEach(function() { gd = createGraphDiv(); });
1203+
1204+
afterEach(destroyGraphDiv);
1205+
1206+
['candlestick', 'ohlc'].forEach(function(type) {
1207+
it('should pick correct ' + type + ' item', function(done) {
1208+
var x = ['hover ok!', 'time2', 'hover off by 1', 'time4'];
1209+
1210+
Plotly.newPlot(gd, [{
1211+
x: x,
1212+
high: [6, null, 7, 8],
1213+
close: [4, null, 7, 8],
1214+
low: [5, null, 7, 8],
1215+
open: [3, null, 7, 8],
1216+
type: type
1217+
}, {
1218+
x: x,
1219+
y: [1, null, 2, 3],
1220+
type: 'bar'
1221+
}], {
1222+
xaxis: { rangeslider: {visible: false} },
1223+
width: 500,
1224+
height: 500
1225+
})
1226+
.then(function() {
1227+
gd.on('plotly_hover', function(d) {
1228+
Plotly.Fx.hover(gd, [
1229+
{curveNumber: 0, pointNumber: d.points[0].pointNumber},
1230+
{curveNumber: 1, pointNumber: d.points[0].pointNumber}
1231+
]);
1232+
});
1233+
})
1234+
.then(function() { hover(281, 252); })
1235+
.then(function() {
1236+
assertHoverLabelContent({
1237+
nums: [
1238+
'hover off by 1\nopen: 7\nhigh: 7\nlow: 7\nclose: 7 ▲',
1239+
'(hover off by 1, 2)'
1240+
],
1241+
name: ['trace 0', 'trace 1']
1242+
}, 'hover over 3rd items (aka 2nd visible items)');
1243+
})
1244+
.catch(failTest)
1245+
.then(done);
1246+
});
1247+
});
1248+
});

0 commit comments

Comments
 (0)