diff --git a/draftlogs/5512_add.md b/draftlogs/5512_add.md
new file mode 100644
index 00000000000..880c848b135
--- /dev/null
+++ b/draftlogs/5512_add.md
@@ -0,0 +1 @@
+ - Provide bounding box positions in hover event data [[#5512](https://github.com/plotly/plotly.js/pull/5512)]
diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js
index 7ea1d78e4aa..eff1e1a2c4e 100644
--- a/src/components/fx/hover.js
+++ b/src/components/fx/hover.js
@@ -126,7 +126,48 @@ exports.loneHover = function loneHover(hoverItems, opts) {
hoverItems = [hoverItems];
}
+ var gd = opts.gd;
+ var gTop = getTopOffset(gd);
+ var gLeft = getLeftOffset(gd);
+
var pointsData = hoverItems.map(function(hoverItem) {
+ var _x0 = hoverItem._x0 || hoverItem.x0 || hoverItem.x || 0;
+ var _x1 = hoverItem._x1 || hoverItem.x1 || hoverItem.x || 0;
+ var _y0 = hoverItem._y0 || hoverItem.y0 || hoverItem.y || 0;
+ var _y1 = hoverItem._y1 || hoverItem.y1 || hoverItem.y || 0;
+
+ var eventData = hoverItem.eventData;
+ if(eventData) {
+ var x0 = Math.min(_x0, _x1);
+ var x1 = Math.max(_x0, _x1);
+ var y0 = Math.min(_y0, _y1);
+ var y1 = Math.max(_y0, _y1);
+
+ var trace = hoverItem.trace;
+ if(Registry.traceIs(trace, 'gl3d')) {
+ var container = gd._fullLayout[trace.scene]._scene.container;
+ var dx = container.offsetLeft;
+ var dy = container.offsetTop;
+ x0 += dx;
+ x1 += dx;
+ y0 += dy;
+ y1 += dy;
+ } // TODO: handle heatmapgl
+
+ eventData.bbox = {
+ x0: x0 + gLeft,
+ x1: x1 + gLeft,
+ y0: y0 + gTop,
+ y1: y1 + gTop
+ };
+
+ if(opts.inOut_bbox) {
+ opts.inOut_bbox.push(eventData.bbox);
+ }
+ } else {
+ eventData = false;
+ }
+
return {
color: hoverItem.color || Color.defaultLine,
x0: hoverItem.x0 || hoverItem.x || 0,
@@ -158,8 +199,9 @@ exports.loneHover = function loneHover(hoverItems, opts) {
index: 0,
hovertemplate: hoverItem.hovertemplate || false,
- eventData: hoverItem.eventData || false,
hovertemplateLabels: hoverItem.hovertemplateLabels || false,
+
+ eventData: eventData
};
});
@@ -174,7 +216,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
outerContainer: outerContainer3
};
- var hoverLabel = createHoverText(pointsData, fullOpts, opts.gd);
+ var hoverLabel = createHoverText(pointsData, fullOpts, gd);
// Fix vertical overlap
var tooltipSpacing = 5;
@@ -199,8 +241,8 @@ exports.loneHover = function loneHover(hoverItems, opts) {
d.offset -= anchor;
});
- var scaleX = opts.gd._fullLayout._invScaleX;
- var scaleY = opts.gd._fullLayout._invScaleY;
+ var scaleX = gd._fullLayout._invScaleX;
+ var scaleY = gd._fullLayout._invScaleY;
alignHoverText(hoverLabel, fullOpts.rotateLabels, scaleX, scaleY);
return multiHover ? hoverLabel : hoverLabel.node();
@@ -732,6 +774,9 @@ function _hover(gd, evt, subplot, noHoverEvent) {
var oldhoverdata = gd._hoverdata;
var newhoverdata = [];
+ var gTop = getTopOffset(gd);
+ var gLeft = getLeftOffset(gd);
+
// pull out just the data that's useful to
// other people and send it to the event
for(itemnum = 0; itemnum < hoverData.length; itemnum++) {
@@ -746,6 +791,25 @@ function _hover(gd, evt, subplot, noHoverEvent) {
pt.hovertemplate = ht || pt.trace.hovertemplate || false;
}
+ if(pt.xa && pt.ya) {
+ var _x0 = pt.x0 + pt.xa._offset;
+ var _x1 = pt.x1 + pt.xa._offset;
+ var _y0 = pt.y0 + pt.ya._offset;
+ var _y1 = pt.y1 + pt.ya._offset;
+
+ var x0 = Math.min(_x0, _x1);
+ var x1 = Math.max(_x0, _x1);
+ var y0 = Math.min(_y0, _y1);
+ var y1 = Math.max(_y0, _y1);
+
+ eventData.bbox = {
+ x0: x0 + gLeft,
+ x1: x1 + gLeft,
+ y0: y0 + gTop,
+ y1: y1 + gTop
+ };
+ }
+
pt.eventData = [eventData];
newhoverdata.push(eventData);
}
@@ -2033,3 +2097,9 @@ function getCoord(axLetter, winningPoint, fullLayout) {
return val;
}
+
+// Top/left hover offsets relative to graph div. As long as hover content is
+// a sibling of the graph div, it will be positioned correctly relative to
+// the offset parent, whatever that may be.
+function getTopOffset(gd) { return gd.offsetTop + gd.clientTop; }
+function getLeftOffset(gd) { return gd.offsetLeft + gd.clientLeft; }
diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js
index b7ee3871218..174d1b30d52 100644
--- a/src/plots/gl3d/scene.js
+++ b/src/plots/gl3d/scene.js
@@ -421,6 +421,7 @@ proto.render = function() {
var eventData = {points: [pointData]};
if(scene.fullSceneLayout.hovermode) {
+ var bbox = [];
Fx.loneHover({
trace: traceNow,
x: (0.5 + 0.5 * pdata[0] / pdata[3]) * width,
@@ -442,8 +443,11 @@ proto.render = function() {
eventData: [pointData]
}, {
container: svgContainer,
- gd: gd
+ gd: gd,
+ inOut_bbox: bbox
});
+
+ pointData.bbox = bbox[0];
}
if(selection.buttons && selection.distance < 5) {
diff --git a/src/traces/icicle/draw_descendants.js b/src/traces/icicle/draw_descendants.js
index b742438ea24..feec1ce4386 100644
--- a/src/traces/icicle/draw_descendants.js
+++ b/src/traces/icicle/draw_descendants.js
@@ -116,6 +116,12 @@ module.exports = function drawDescendants(gd, cd, entry, slices, opts) {
}
updateSlices.each(function(pt) {
+ // for bbox
+ pt._x0 = viewX(pt.x0);
+ pt._x1 = viewX(pt.x1);
+ pt._y0 = viewY(pt.y0);
+ pt._y1 = viewY(pt.y1);
+
pt._hoverX = viewX(pt.x1 - trace.tiling.pad),
pt._hoverY = hasBottom ?
viewY(pt.y1 - trace.tiling.pad / 2) :
diff --git a/src/traces/pie/event_data.js b/src/traces/pie/event_data.js
index 3393f0353dd..cb738f450a1 100644
--- a/src/traces/pie/event_data.js
+++ b/src/traces/pie/event_data.js
@@ -16,6 +16,7 @@ module.exports = function eventData(pt, trace) {
value: pt.v,
percent: pt.percent,
text: pt.text,
+ bbox: pt.bbox,
// pt.v (and pt.i below) for backward compatibility
v: pt.v
diff --git a/src/traces/pie/plot.js b/src/traces/pie/plot.js
index cca8694817d..8d2cd2d39ee 100644
--- a/src/traces/pie/plot.js
+++ b/src/traces/pie/plot.js
@@ -344,9 +344,10 @@ function plotTextLines(slices, trace) {
function attachFxHandlers(sliceTop, gd, cd) {
var cd0 = cd[0];
- var trace = cd0.trace;
var cx = cd0.cx;
var cy = cd0.cy;
+ var trace = cd0.trace;
+ var isFunnelArea = trace.type === 'funnelarea';
// hover state vars
// have we drawn a hover label, so it should be cleared later
@@ -404,11 +405,16 @@ function attachFxHandlers(sliceTop, gd, cd) {
var hoverLabel = trace2.hoverlabel;
var hoverFont = hoverLabel.font;
+ var bbox = [];
Fx.loneHover({
trace: trace,
x0: hoverCenterX - rInscribed * cd0.r,
x1: hoverCenterX + rInscribed * cd0.r,
y: hoverCenterY,
+ _x0: isFunnelArea ? cx + pt.TL[0] : hoverCenterX - rInscribed * cd0.r,
+ _x1: isFunnelArea ? cx + pt.TR[0] : hoverCenterX + rInscribed * cd0.r,
+ _y0: isFunnelArea ? cy + pt.TL[1] : hoverCenterY - rInscribed * cd0.r,
+ _y1: isFunnelArea ? cy + pt.BL[1] : hoverCenterY + rInscribed * cd0.r,
text: text.join('
'),
name: (trace2.hovertemplate || hoverinfo.indexOf('name') !== -1) ? trace2.name : undefined,
idealAlign: pt.pxmid[0] < 0 ? 'left' : 'right',
@@ -425,8 +431,10 @@ function attachFxHandlers(sliceTop, gd, cd) {
}, {
container: fullLayout2._hoverlayer.node(),
outerContainer: fullLayout2._paper.node(),
- gd: gd
+ gd: gd,
+ inOut_bbox: bbox
});
+ pt.bbox = bbox[0];
trace._hasHoverLabel = true;
}
diff --git a/src/traces/sunburst/fx.js b/src/traces/sunburst/fx.js
index 66f2cec6d27..931541b3929 100644
--- a/src/traces/sunburst/fx.js
+++ b/src/traces/sunburst/fx.js
@@ -52,6 +52,8 @@ module.exports = function attachFxHandlers(sliceTop, entry, gd, cd, opts) {
var hoverinfo = Fx.castHoverinfo(traceNow, fullLayoutNow, ptNumber);
var separators = fullLayoutNow.separators;
+ var eventData;
+
if(hovertemplate || (hoverinfo && hoverinfo !== 'none' && hoverinfo !== 'skip')) {
var hoverCenterX;
var hoverCenterY;
@@ -125,9 +127,15 @@ module.exports = function attachFxHandlers(sliceTop, entry, gd, cd, opts) {
if(Lib.isValidTextValue(tx)) thisText.push(tx);
}
+ eventData = [makeEventData(pt, traceNow, opts.eventDataKeys)];
+
var hoverItems = {
trace: traceNow,
y: hoverCenterY,
+ _x0: pt._x0,
+ _x1: pt._x1,
+ _y0: pt._y0,
+ _y1: pt._y1,
text: thisText.join('
'),
name: (hovertemplate || hasFlag('name')) ? traceNow.name : undefined,
color: _cast('hoverlabel.bgcolor') || cdi.color,
@@ -139,7 +147,7 @@ module.exports = function attachFxHandlers(sliceTop, entry, gd, cd, opts) {
textAlign: _cast('hoverlabel.align'),
hovertemplate: hovertemplate,
hovertemplateLabels: hoverPt,
- eventData: [makeEventData(pt, traceNow, opts.eventDataKeys)]
+ eventData: eventData
};
if(isSunburst) {
@@ -152,11 +160,14 @@ module.exports = function attachFxHandlers(sliceTop, entry, gd, cd, opts) {
hoverItems.idealAlign = hoverCenterX < 0 ? 'left' : 'right';
}
+ var bbox = [];
Fx.loneHover(hoverItems, {
container: fullLayoutNow._hoverlayer.node(),
outerContainer: fullLayoutNow._paper.node(),
- gd: gd
+ gd: gd,
+ inOut_bbox: bbox
});
+ eventData[0].bbox = bbox[0];
trace._hasHoverLabel = true;
}
@@ -170,7 +181,7 @@ module.exports = function attachFxHandlers(sliceTop, entry, gd, cd, opts) {
trace._hasHoverEvent = true;
gd.emit('plotly_hover', {
- points: [makeEventData(pt, traceNow, opts.eventDataKeys)],
+ points: eventData || [makeEventData(pt, traceNow, opts.eventDataKeys)],
event: d3.event
});
};
diff --git a/src/traces/treemap/draw_ancestors.js b/src/traces/treemap/draw_ancestors.js
index 294af2fc624..a25bcfea236 100644
--- a/src/traces/treemap/draw_ancestors.js
+++ b/src/traces/treemap/draw_ancestors.js
@@ -89,6 +89,12 @@ module.exports = function drawAncestors(gd, cd, entry, slices, opts) {
}
updateSlices.each(function(pt) {
+ // for bbox
+ pt._x0 = viewX(pt.x0);
+ pt._x1 = viewX(pt.x1);
+ pt._y0 = viewY(pt.y0);
+ pt._y1 = viewY(pt.y1);
+
pt._hoverX = viewX(pt.x1 - Math.min(width, height) / 2);
pt._hoverY = viewY(pt.y1 - height / 2);
diff --git a/src/traces/treemap/draw_descendants.js b/src/traces/treemap/draw_descendants.js
index 4e1fe8062be..d34296e8d05 100644
--- a/src/traces/treemap/draw_descendants.js
+++ b/src/traces/treemap/draw_descendants.js
@@ -124,6 +124,12 @@ module.exports = function drawDescendants(gd, cd, entry, slices, opts) {
updateSlices.each(function(pt) {
var isHeader = helpers.isHeader(pt, trace);
+ // for bbox
+ pt._x0 = viewX(pt.x0);
+ pt._x1 = viewX(pt.x1);
+ pt._y0 = viewY(pt.y0);
+ pt._y1 = viewY(pt.y1);
+
pt._hoverX = viewX(pt.x1 - trace.marker.pad.r),
pt._hoverY = hasBottom ?
viewY(pt.y1 - trace.marker.pad.b / 2) :
diff --git a/test/jasmine/tests/cartesian_interact_test.js b/test/jasmine/tests/cartesian_interact_test.js
index 9c972bee260..12c6ebd3254 100644
--- a/test/jasmine/tests/cartesian_interact_test.js
+++ b/test/jasmine/tests/cartesian_interact_test.js
@@ -2422,6 +2422,12 @@ describe('Cartesian plots with css transforms', function() {
}
};
+ var bbox = {
+ one: { x0: 20, x1: 180, y0: 273.33, y1: 273.33 },
+ two: { x0: 220, x1: 380, y0: 146.67, y1: 146.67 },
+ three: { x0: 420, x1: 580, y0: 20, y1: 20 }
+ };
+
[{
transform: 'scaleX(0.5)',
hovered: 1,
@@ -2436,12 +2442,14 @@ describe('Cartesian plots with css transforms', function() {
selected: {numPoints: 3, selectedLabels: ['one', 'two', 'three']}
}].forEach(function(t) {
var transform = t.transform;
-
it('hover behaves correctly after css transform: ' + transform, function(done) {
+ var _bboxRecordings = {};
+
function _hoverAndAssertEventOccurred(point, label) {
return _hover(point)
.then(function() {
expect(eventRecordings[label]).toBe(t.hovered);
+ expect(_bboxRecordings[label]).toEqual(bbox[label]);
})
.then(function() {
_unhover(point);
@@ -2454,6 +2462,7 @@ describe('Cartesian plots with css transforms', function() {
gd.on('plotly_hover', function(d) {
eventRecordings[d.points[0].x] = 1;
+ _bboxRecordings[d.points[0].x] = d.points[0].bbox;
});
})
.then(function() {_hoverAndAssertEventOccurred(points[0], xLabels[0]);})
diff --git a/test/jasmine/tests/click_test.js b/test/jasmine/tests/click_test.js
index e2b0ca81c6a..10e1d03d515 100644
--- a/test/jasmine/tests/click_test.js
+++ b/test/jasmine/tests/click_test.js
@@ -115,10 +115,11 @@ describe('Test click interactions:', function() {
expect(contextPassthroughs).toBe(0);
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
+ expect(Object.keys(pt).sort()).toEqual([
'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ 'bbox',
'x', 'y', 'xaxis', 'yaxis'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0);
expect(pt.pointNumber).toEqual(11);
expect(pt.x).toEqual(0.125);
@@ -148,10 +149,11 @@ describe('Test click interactions:', function() {
expect(contextPassthroughs).toBe(0);
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
+ expect(Object.keys(pt).sort()).toEqual([
'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ 'bbox',
'x', 'y', 'xaxis', 'yaxis'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0);
expect(pt.pointNumber).toEqual(11);
expect(pt.x).toEqual(0.125);
@@ -219,10 +221,11 @@ describe('Test click interactions:', function() {
expect(contextPassthroughs).toBe(0, i);
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
+ expect(Object.keys(pt).sort()).toEqual([
'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ 'bbox',
'x', 'y', 'xaxis', 'yaxis'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0);
expect(pt.pointNumber).toEqual(11);
expect(pt.x).toEqual(0.125);
@@ -308,10 +311,11 @@ describe('Test click interactions:', function() {
expect(futureData.points.length).toEqual(1);
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
+ expect(Object.keys(pt).sort()).toEqual([
'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ 'bbox',
'x', 'y', 'xaxis', 'yaxis'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0);
expect(pt.pointNumber).toEqual(11);
expect(pt.x).toEqual(0.125);
@@ -341,10 +345,11 @@ describe('Test click interactions:', function() {
expect(futureData.points.length).toEqual(1);
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
+ expect(Object.keys(pt).sort()).toEqual([
'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ 'bbox',
'x', 'y', 'xaxis', 'yaxis'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0);
expect(pt.pointNumber).toEqual(11);
expect(pt.x).toEqual(0.125);
@@ -378,10 +383,11 @@ describe('Test click interactions:', function() {
expect(futureData.points.length).toEqual(1);
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
+ expect(Object.keys(pt).sort()).toEqual([
'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ 'bbox',
'x', 'y', 'xaxis', 'yaxis'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0);
expect(pt.pointNumber).toEqual(11);
expect(pt.x).toEqual(0.125);
diff --git a/test/jasmine/tests/funnelarea_test.js b/test/jasmine/tests/funnelarea_test.js
index 2afb934e434..d898be597f1 100644
--- a/test/jasmine/tests/funnelarea_test.js
+++ b/test/jasmine/tests/funnelarea_test.js
@@ -765,9 +765,16 @@ describe('funnelarea hovering', function() {
'curveNumber', 'pointNumber', 'pointNumbers',
'data', 'fullData',
'label', 'color', 'value',
- 'percent', 'text'
+ 'percent', 'text',
+ 'bbox'
];
+ expect(typeof hoverData.points[0].bbox).toEqual('object');
+ expect(typeof hoverData.points[0].bbox.x0).toEqual('number');
+ expect(typeof hoverData.points[0].bbox.x1).toEqual('number');
+ expect(typeof hoverData.points[0].bbox.y0).toEqual('number');
+ expect(typeof hoverData.points[0].bbox.y1).toEqual('number');
+
expect(Object.keys(hoverData.points[0]).sort()).toEqual(fields.sort());
expect(hoverData.points[0].pointNumber).toEqual(3);
diff --git a/test/jasmine/tests/geo_test.js b/test/jasmine/tests/geo_test.js
index 335bcf990e4..f28ff0e7d70 100644
--- a/test/jasmine/tests/geo_test.js
+++ b/test/jasmine/tests/geo_test.js
@@ -882,10 +882,10 @@ describe('Test geo interactions', function() {
});
it('should contain the correct fields', function() {
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(ptData).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'lon', 'lat', 'location', 'marker.size'
- ]);
+ ].sort());
expect(cnt).toEqual(1);
});
@@ -947,10 +947,10 @@ describe('Test geo interactions', function() {
});
it('should contain the correct fields', function() {
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(ptData).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'lon', 'lat', 'location', 'marker.size'
- ]);
+ ].sort());
});
it('should show the correct point data', function() {
@@ -979,10 +979,10 @@ describe('Test geo interactions', function() {
});
it('should contain the correct fields', function() {
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(ptData).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'lon', 'lat', 'location', 'marker.size'
- ]);
+ ].sort());
});
it('should show the correct point data', function() {
@@ -1008,10 +1008,10 @@ describe('Test geo interactions', function() {
});
it('should contain the correct fields', function() {
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(ptData).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'location', 'z', 'ct'
- ]);
+ ].sort());
});
it('should show the correct point data', function() {
@@ -1036,10 +1036,10 @@ describe('Test geo interactions', function() {
});
it('should contain the correct fields', function() {
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(ptData).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'location', 'z', 'ct'
- ]);
+ ].sort());
});
it('should show the correct point data', function() {
@@ -1068,10 +1068,10 @@ describe('Test geo interactions', function() {
});
it('should contain the correct fields', function() {
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(ptData).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'location', 'z', 'ct'
- ]);
+ ].sort());
});
it('should show the correct point data', function() {
@@ -1789,11 +1789,11 @@ describe('Test event property of interactions on a geo plot:', function() {
var pt = futureData.points[0];
var evt = futureData.event;
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'lon', 'lat',
'location', 'text', 'marker.size'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1847,11 +1847,11 @@ describe('Test event property of interactions on a geo plot:', function() {
// var pt = futureData.points[0],
// evt = futureData.event;
- // expect(Object.keys(pt)).toEqual([
- // 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ // expect(Object.keys(pt).sort()).toEqual([
+ // 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
// 'lon', 'lat',
// 'location', 'text', 'marker.size'
- // ]);
+ // ].sort());
// expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
// expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1893,11 +1893,11 @@ describe('Test event property of interactions on a geo plot:', function() {
var pt = futureData.points[0];
var evt = futureData.event;
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'lon', 'lat',
'location', 'text', 'marker.size'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1934,11 +1934,11 @@ describe('Test event property of interactions on a geo plot:', function() {
var pt = futureData.points[0];
var evt = futureData.event;
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'bbox',
'lon', 'lat',
'location', 'text', 'marker.size'
- ]);
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
diff --git a/test/jasmine/tests/gl3d_hover_click_test.js b/test/jasmine/tests/gl3d_hover_click_test.js
index 3fbb56edeaa..9359edd2f28 100644
--- a/test/jasmine/tests/gl3d_hover_click_test.js
+++ b/test/jasmine/tests/gl3d_hover_click_test.js
@@ -58,7 +58,8 @@ describe('Test gl3d trace click/hover:', function() {
function assertEventData(x, y, z, curveNumber, pointNumber, extra) {
expect(Object.keys(ptData)).toEqual(jasmine.arrayContaining([
'x', 'y', 'z',
- 'data', 'fullData', 'curveNumber', 'pointNumber'
+ 'data', 'fullData', 'curveNumber', 'pointNumber',
+ 'bbox'
]), 'correct hover data fields');
expect(ptData.x).toEqual(x, 'x val');
@@ -67,6 +68,12 @@ describe('Test gl3d trace click/hover:', function() {
expect(ptData.curveNumber).toEqual(curveNumber, 'curveNumber');
expect(ptData.pointNumber).toEqual(pointNumber, 'pointNumber');
+ expect(typeof ptData.bbox).toEqual('object');
+ expect(typeof ptData.bbox.x0).toEqual('number');
+ expect(typeof ptData.bbox.x1).toEqual('number');
+ expect(typeof ptData.bbox.y0).toEqual('number');
+ expect(typeof ptData.bbox.y1).toEqual('number');
+
Object.keys(extra || {}).forEach(function(k) {
expect(ptData[k]).toEqual(extra[k], k + ' val');
});
diff --git a/test/jasmine/tests/icicle_test.js b/test/jasmine/tests/icicle_test.js
index 143165feb80..339e3ce4928 100644
--- a/test/jasmine/tests/icicle_test.js
+++ b/test/jasmine/tests/icicle_test.js
@@ -526,6 +526,12 @@ describe('Test icicle hover:', function() {
expect(ptData[k]).toBe(exp.ptData[k], 'pt event data key ' + k);
}
+ expect(typeof ptData.bbox).toEqual('object');
+ expect(typeof ptData.bbox.x0).toEqual('number');
+ expect(typeof ptData.bbox.x1).toEqual('number');
+ expect(typeof ptData.bbox.y0).toEqual('number');
+ expect(typeof ptData.bbox.y1).toEqual('number');
+
if(exp.style) {
var gd3 = d3Select(gd);
assertHoverLabelStyle(gd3.select('.hovertext'), exp.style);
diff --git a/test/jasmine/tests/mapbox_test.js b/test/jasmine/tests/mapbox_test.js
index d39400f70f3..ef4f4d1f53a 100644
--- a/test/jasmine/tests/mapbox_test.js
+++ b/test/jasmine/tests/mapbox_test.js
@@ -19,6 +19,12 @@ var customAssertions = require('../assets/custom_assertions');
var assertHoverLabelStyle = customAssertions.assertHoverLabelStyle;
var assertHoverLabelContent = customAssertions.assertHoverLabelContent;
+var SORTED_EVENT_KEYS = [
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ 'lon', 'lat',
+ 'bbox'
+].sort();
+
var MAPBOX_ACCESS_TOKEN = require('@build/credentials.json').MAPBOX_ACCESS_TOKEN;
var TRANSITION_DELAY = 500;
var MOUSE_DELAY = 100;
@@ -1243,9 +1249,7 @@ describe('mapbox plots', function() {
.then(function() {
return _mouseEvent('mousemove', pointPos, function() {
expect(hoverData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(hoverData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ], 'returning the correct event data keys');
+ expect(Object.keys(hoverData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(hoverData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(hoverData.pointNumber).toEqual(0, 'returning the correct point number');
});
@@ -1253,9 +1257,7 @@ describe('mapbox plots', function() {
.then(function() {
return _mouseEvent('mousemove', blankPos, function() {
expect(unhoverData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(unhoverData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ], 'returning the correct event data keys');
+ expect(Object.keys(unhoverData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(unhoverData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(unhoverData.pointNumber).toEqual(0, 'returning the correct point number');
});
@@ -1400,9 +1402,7 @@ describe('mapbox plots', function() {
.then(function() { return click(pointPos[0], pointPos[1]); })
.then(function() {
expect(ptData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ], 'returning the correct event data keys');
+ expect(Object.keys(ptData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(ptData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(ptData.pointNumber).toEqual(0, 'returning the correct point number');
})
diff --git a/test/jasmine/tests/pie_test.js b/test/jasmine/tests/pie_test.js
index eedb6974d26..f70d80e44bb 100644
--- a/test/jasmine/tests/pie_test.js
+++ b/test/jasmine/tests/pie_test.js
@@ -1103,9 +1103,16 @@ describe('pie hovering', function() {
'curveNumber', 'pointNumber', 'pointNumbers',
'data', 'fullData',
'label', 'color', 'value',
- 'i', 'v', 'percent', 'text'
+ 'i', 'v', 'percent', 'text',
+ 'bbox'
];
+ expect(typeof hoverData.points[0].bbox).toEqual('object');
+ expect(typeof hoverData.points[0].bbox.x0).toEqual('number');
+ expect(typeof hoverData.points[0].bbox.x1).toEqual('number');
+ expect(typeof hoverData.points[0].bbox.y0).toEqual('number');
+ expect(typeof hoverData.points[0].bbox.y1).toEqual('number');
+
expect(Object.keys(hoverData.points[0]).sort()).toEqual(fields.sort());
expect(hoverData.points[0].pointNumber).toEqual(3);
diff --git a/test/jasmine/tests/scattermapbox_test.js b/test/jasmine/tests/scattermapbox_test.js
index 89c7955851b..aaeb28d0a4e 100644
--- a/test/jasmine/tests/scattermapbox_test.js
+++ b/test/jasmine/tests/scattermapbox_test.js
@@ -952,9 +952,9 @@ describe('Test plotly events on a scattermapbox plot:', function() {
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ]);
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat', 'bbox'
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -999,9 +999,9 @@ describe('Test plotly events on a scattermapbox plot:', function() {
// var pt = futureData.points[0],
// evt = futureData.event;
- // expect(Object.keys(pt)).toEqual([
- // 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- // ]);
+ // expect(Object.keys(pt).sort()).toEqual([
+ // 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat', 'bbox'
+ // ].sort());
// expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
// expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1033,9 +1033,9 @@ describe('Test plotly events on a scattermapbox plot:', function() {
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ]);
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat', 'bbox'
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1061,9 +1061,9 @@ describe('Test plotly events on a scattermapbox plot:', function() {
move(pointPos[0], pointPos[1], nearPos[0], nearPos[1], HOVERMINTIME + 10).then(function() {
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ]);
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat', 'bbox'
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1133,9 +1133,9 @@ describe('Test plotly events on a scattermapbox plot when css transform is prese
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ]);
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat', 'bbox'
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1163,9 +1163,9 @@ describe('Test plotly events on a scattermapbox plot when css transform is prese
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ]);
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat', 'bbox'
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1191,9 +1191,9 @@ describe('Test plotly events on a scattermapbox plot when css transform is prese
move(pointPos[0], pointPos[1], nearPos[0], nearPos[1], HOVERMINTIME + 10).then(function() {
var pt = futureData.points[0];
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat'
- ]);
+ expect(Object.keys(pt).sort()).toEqual([
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat', 'bbox'
+ ].sort());
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
diff --git a/test/jasmine/tests/streamtube_test.js b/test/jasmine/tests/streamtube_test.js
index deb9322b428..2eb6088be01 100644
--- a/test/jasmine/tests/streamtube_test.js
+++ b/test/jasmine/tests/streamtube_test.js
@@ -593,7 +593,7 @@ describe('Test streamtube hover', function() {
.then(delay(20))
.then(function() {
if(ptData) {
- expect(Object.keys(ptData).length).toBe(12, 'key cnt');
+ expect(Object.keys(ptData).length).toBe(13, 'key cnt');
expect(ptData.tubex).toBeCloseTo(2.19, TOL, 'tubex');
expect(ptData.tubey).toBeCloseTo(0.55, TOL, 'tubey');
diff --git a/test/jasmine/tests/sunburst_test.js b/test/jasmine/tests/sunburst_test.js
index 28876802534..019eca82be6 100644
--- a/test/jasmine/tests/sunburst_test.js
+++ b/test/jasmine/tests/sunburst_test.js
@@ -539,6 +539,12 @@ describe('Test sunburst hover:', function() {
expect(ptData[k]).toBe(exp.ptData[k], 'pt event data key ' + k);
}
+ expect(typeof ptData.bbox).toEqual('object');
+ expect(typeof ptData.bbox.x0).toEqual('number');
+ expect(typeof ptData.bbox.x1).toEqual('number');
+ expect(typeof ptData.bbox.y0).toEqual('number');
+ expect(typeof ptData.bbox.y1).toEqual('number');
+
if(exp.style) {
var gd3 = d3Select(gd);
assertHoverLabelStyle(gd3.select('.hovertext'), exp.style);
diff --git a/test/jasmine/tests/ternary_test.js b/test/jasmine/tests/ternary_test.js
index 27f6136994d..151a818edab 100644
--- a/test/jasmine/tests/ternary_test.js
+++ b/test/jasmine/tests/ternary_test.js
@@ -19,6 +19,12 @@ var customAssertions = require('../assets/custom_assertions');
var assertHoverLabelStyle = customAssertions.assertHoverLabelStyle;
var assertHoverLabelContent = customAssertions.assertHoverLabelContent;
+var SORTED_EVENT_KEYS = [
+ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
+ 'xaxis', 'yaxis', 'a', 'b', 'c',
+ 'bbox'
+].sort();
+
describe('ternary plots', function() {
'use strict';
@@ -195,19 +201,13 @@ describe('ternary plots', function() {
mouseEvent('mousemove', pointPos[0], pointPos[1]);
expect(hoverData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(hoverData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ], 'returning the correct event data keys');
+ expect(Object.keys(hoverData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(hoverData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(hoverData.pointNumber).toEqual(0, 'returning the correct point number');
mouseEvent('mouseout', pointPos[0], pointPos[1]);
expect(unhoverData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(unhoverData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ], 'returning the correct event data keys');
+ expect(Object.keys(unhoverData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(unhoverData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(unhoverData.pointNumber).toEqual(0, 'returning the correct point number');
@@ -227,10 +227,7 @@ describe('ternary plots', function() {
click(pointPos[0], pointPos[1]);
expect(ptData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ], 'returning the correct event data keys');
+ expect(Object.keys(ptData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(ptData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(ptData.pointNumber).toEqual(0, 'returning the correct point number');
});
@@ -678,19 +675,13 @@ describe('ternary plots when css transform is present', function() {
mouseEvent('mousemove', pointPos[0], pointPos[1]);
expect(hoverData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(hoverData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ], 'returning the correct event data keys');
+ expect(Object.keys(hoverData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(hoverData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(hoverData.pointNumber).toEqual(0, 'returning the correct point number');
mouseEvent('mouseout', pointPos[0], pointPos[1]);
expect(unhoverData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(unhoverData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ], 'returning the correct event data keys');
+ expect(Object.keys(unhoverData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(unhoverData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(unhoverData.pointNumber).toEqual(0, 'returning the correct point number');
@@ -710,10 +701,7 @@ describe('ternary plots when css transform is present', function() {
click(pointPos[0], pointPos[1]);
expect(ptData).not.toBe(undefined, 'firing on data points');
- expect(Object.keys(ptData)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ], 'returning the correct event data keys');
+ expect(Object.keys(ptData).sort()).toEqual(SORTED_EVENT_KEYS, 'returning the correct event data keys');
expect(ptData.curveNumber).toEqual(0, 'returning the correct curve number');
expect(ptData.pointNumber).toEqual(0, 'returning the correct point number');
});
@@ -843,10 +831,7 @@ describe('Test event property of interactions on a ternary plot:', function() {
var pt = futureData.points[0];
var evt = futureData.event;
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ]);
+ expect(Object.keys(pt).sort()).toEqual(SORTED_EVENT_KEYS);
expect(pt.curveNumber).toBe(0, 'points[0].curveNumber');
expect(typeof pt.data).toBe(typeof {}, 'points[0].data');
@@ -912,10 +897,7 @@ describe('Test event property of interactions on a ternary plot:', function() {
var pt = futureData.points[0];
var evt = futureData.event;
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ]);
+ expect(Object.keys(pt).sort()).toEqual(SORTED_EVENT_KEYS);
expect(pt.curveNumber).toBe(0, 'points[0].curveNumber: ' + i);
expect(typeof pt.data).toBe(typeof {}, 'points[0].data: ' + i);
@@ -964,10 +946,7 @@ describe('Test event property of interactions on a ternary plot:', function() {
var yaxes0 = futureData.yaxes[0];
var yvals0 = futureData.yvals[0];
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ]);
+ expect(Object.keys(pt).sort()).toEqual(SORTED_EVENT_KEYS);
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
@@ -1012,10 +991,7 @@ describe('Test event property of interactions on a ternary plot:', function() {
var pt = futureData.points[0];
var evt = futureData.event;
- expect(Object.keys(pt)).toEqual([
- 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex',
- 'xaxis', 'yaxis', 'a', 'b', 'c'
- ]);
+ expect(Object.keys(pt).sort()).toEqual(SORTED_EVENT_KEYS);
expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber');
expect(typeof pt.data).toEqual(typeof {}, 'points[0].data');
diff --git a/test/jasmine/tests/treemap_test.js b/test/jasmine/tests/treemap_test.js
index 425a9fd528e..af3f5f098d5 100644
--- a/test/jasmine/tests/treemap_test.js
+++ b/test/jasmine/tests/treemap_test.js
@@ -628,6 +628,12 @@ describe('Test treemap hover:', function() {
expect(ptData[k]).toBe(exp.ptData[k], 'pt event data key ' + k);
}
+ expect(typeof ptData.bbox).toEqual('object');
+ expect(typeof ptData.bbox.x0).toEqual('number');
+ expect(typeof ptData.bbox.x1).toEqual('number');
+ expect(typeof ptData.bbox.y0).toEqual('number');
+ expect(typeof ptData.bbox.y1).toEqual('number');
+
if(exp.style) {
var gd3 = d3Select(gd);
assertHoverLabelStyle(gd3.select('.hovertext'), exp.style);