Skip to content

Commit 963f362

Browse files
authored
Merge pull request #5543 from plotly/fix5292-unified-hover
Fix hover filter to display close period points
2 parents 8f69805 + 4d831e2 commit 963f362

File tree

2 files changed

+272
-4
lines changed

2 files changed

+272
-4
lines changed

Diff for: src/components/fx/hover.js

+23-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ var Drawing = require('../drawing');
1414
var Color = require('../color');
1515
var dragElement = require('../dragelement');
1616
var Axes = require('../../plots/cartesian/axes');
17+
var alignPeriod = require('../../plots/cartesian/align_period');
1718
var Registry = require('../../registry');
1819

1920
var helpers = require('./helpers');
@@ -779,8 +780,9 @@ function createHoverText(hoverData, opts, gd) {
779780
var c0 = hoverData[0];
780781
var xa = c0.xa;
781782
var ya = c0.ya;
782-
var commonAttr = hovermode.charAt(0) === 'y' ? 'yLabel' : 'xLabel';
783-
var t0 = c0[commonAttr];
783+
var axLetter = hovermode.charAt(0);
784+
var v0 = c0[axLetter + 'LabelVal'];
785+
var t0 = c0[axLetter + 'Label'];
784786
var t00 = (String(t0) || '').split(' ')[0];
785787
var outerContainerBB = outerContainer.node().getBoundingClientRect();
786788
var outerTop = outerContainerBB.top;
@@ -978,8 +980,25 @@ function createHoverText(hoverData, opts, gd) {
978980

979981
function filterClosePoints(hoverData) {
980982
return hoverData.filter(function(d) {
981-
return (d.zLabelVal !== undefined) ||
982-
(d[commonAttr] || '').split(' ')[0] === t00;
983+
if(d.zLabelVal !== undefined) return true;
984+
if((d[axLetter + 'Label'] || '').split(' ')[0] === t00) return true;
985+
if(d.trace[axLetter + 'period']) {
986+
var v = d[axLetter + 'LabelVal'];
987+
var ax = d[axLetter + 'a'];
988+
var trace = {};
989+
trace[axLetter + 'period'] = d.trace[axLetter + 'period'];
990+
trace[axLetter + 'period0'] = d.trace[axLetter + 'period0'];
991+
992+
trace[axLetter + 'periodalignment'] = 'start';
993+
var start = alignPeriod(trace, ax, axLetter, [v])[0];
994+
995+
trace[axLetter + 'periodalignment'] = 'end';
996+
var end = alignPeriod(trace, ax, axLetter, [v])[0];
997+
998+
if(v0 >= start && v0 < end) return true;
999+
}
1000+
1001+
return false;
9831002
});
9841003
}
9851004

Diff for: test/jasmine/tests/hover_label_test.js

+249
Original file line numberDiff line numberDiff line change
@@ -4749,6 +4749,255 @@ describe('hovermode: (x|y)unified', function() {
47494749
.then(done, done.fail);
47504750
});
47514751

4752+
it('case of scatter points on period bars', function(done) {
4753+
Plotly.newPlot(gd, {
4754+
data: [
4755+
{
4756+
type: 'bar',
4757+
name: 'bar',
4758+
x: [
4759+
'2017-04',
4760+
'2017-07',
4761+
'2017-10',
4762+
'2018-01'
4763+
],
4764+
xperiod: 'M3',
4765+
y: [10, 5, 10, 5]
4766+
},
4767+
{
4768+
type: 'scatter',
4769+
name: 'scatter',
4770+
x: [
4771+
'2017-01-01',
4772+
'2017-02-01',
4773+
'2017-03-01',
4774+
'2017-04-01',
4775+
'2017-05-01',
4776+
'2017-06-01',
4777+
'2017-07-01',
4778+
'2017-08-01',
4779+
'2017-09-01',
4780+
'2017-10-01',
4781+
'2017-11-01',
4782+
'2017-12-01'
4783+
],
4784+
y: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
4785+
}
4786+
],
4787+
layout: {
4788+
hovermode: 'x unified',
4789+
showlegend: false,
4790+
width: 500,
4791+
height: 500,
4792+
margin: {
4793+
t: 50,
4794+
b: 50,
4795+
l: 50,
4796+
r: 50
4797+
}
4798+
}
4799+
})
4800+
.then(function(gd) {
4801+
_hover(gd, { xpx: 50, ypx: 250 });
4802+
assertLabel({title: 'Feb 1, 2017', items: [
4803+
'scatter : 2'
4804+
]});
4805+
4806+
_hover(gd, { xpx: 75, ypx: 250 });
4807+
assertLabel({title: 'Mar 1, 2017', items: [
4808+
'scatter : 3'
4809+
]});
4810+
4811+
_hover(gd, { xpx: 100, ypx: 250 });
4812+
assertLabel({title: 'Apr 1, 2017', items: [
4813+
'bar : 10',
4814+
'scatter : 4'
4815+
]});
4816+
4817+
_hover(gd, { xpx: 125, ypx: 250 });
4818+
assertLabel({title: 'May 1, 2017', items: [
4819+
'bar : (Apr 1, 2017, 10)',
4820+
'scatter : 5'
4821+
]});
4822+
4823+
_hover(gd, { xpx: 150, ypx: 250 });
4824+
assertLabel({title: 'Jun 1, 2017', items: [
4825+
'bar : (Apr 1, 2017, 10)',
4826+
'scatter : 6'
4827+
]});
4828+
4829+
_hover(gd, { xpx: 175, ypx: 250 });
4830+
assertLabel({title: 'Jul 1, 2017', items: [
4831+
'bar : 5',
4832+
'scatter : 7'
4833+
]});
4834+
4835+
_hover(gd, { xpx: 200, ypx: 250 });
4836+
assertLabel({title: 'Aug 1, 2017', items: [
4837+
'bar : (Jul 1, 2017, 5)',
4838+
'scatter : 8'
4839+
]});
4840+
4841+
_hover(gd, { xpx: 225, ypx: 250 });
4842+
assertLabel({title: 'Sep 1, 2017', items: [
4843+
'bar : (Jul 1, 2017, 5)',
4844+
'scatter : 9'
4845+
]});
4846+
4847+
_hover(gd, { xpx: 250, ypx: 250 });
4848+
assertLabel({title: 'Oct 1, 2017', items: [
4849+
'bar : 10',
4850+
'scatter : 10'
4851+
]});
4852+
4853+
_hover(gd, { xpx: 275, ypx: 250 });
4854+
assertLabel({title: 'Nov 1, 2017', items: [
4855+
'bar : (Oct 1, 2017, 10)',
4856+
'scatter : 11'
4857+
]});
4858+
4859+
_hover(gd, { xpx: 300, ypx: 250 });
4860+
assertLabel({title: 'Dec 1, 2017', items: [
4861+
'bar : (Oct 1, 2017, 10)',
4862+
'scatter : 12'
4863+
]});
4864+
4865+
_hover(gd, { xpx: 350, ypx: 250 });
4866+
assertLabel({title: 'Jan 1, 2018', items: [
4867+
'bar : 5'
4868+
]});
4869+
})
4870+
.then(done, done.fail);
4871+
});
4872+
4873+
it('case of M1 period bars overlaid on M3 period bars', function(done) {
4874+
Plotly.newPlot(gd, {
4875+
data: [
4876+
{
4877+
type: 'bar',
4878+
name: 'M3',
4879+
xperiod: 'M3',
4880+
x: [
4881+
'2017-04',
4882+
'2017-07',
4883+
'2017-10',
4884+
'2018-01'
4885+
],
4886+
y: [10, 5, 10, 5]
4887+
},
4888+
{
4889+
type: 'bar',
4890+
name: 'M1',
4891+
xperiod: 'M1',
4892+
x: [
4893+
'2017-01',
4894+
'2017-02',
4895+
'2017-03',
4896+
'2017-04',
4897+
'2017-05',
4898+
'2017-06',
4899+
'2017-07',
4900+
'2017-08',
4901+
'2017-09',
4902+
'2017-10',
4903+
'2017-11',
4904+
'2017-12'
4905+
],
4906+
y: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
4907+
}
4908+
],
4909+
layout: {
4910+
barmode: 'overlay',
4911+
hovermode: 'x unified',
4912+
showlegend: false,
4913+
width: 500,
4914+
height: 500,
4915+
margin: {
4916+
t: 50,
4917+
b: 50,
4918+
l: 50,
4919+
r: 50
4920+
}
4921+
}
4922+
})
4923+
.then(function(gd) {
4924+
_hover(gd, { xpx: 25, ypx: 250 });
4925+
assertLabel({title: 'Jan 1, 2017', items: [
4926+
'M1 : 1'
4927+
]});
4928+
4929+
_hover(gd, { xpx: 50, ypx: 250 });
4930+
assertLabel({title: 'Feb 1, 2017', items: [
4931+
'M1 : 2'
4932+
]});
4933+
4934+
_hover(gd, { xpx: 75, ypx: 250 });
4935+
assertLabel({title: 'Mar 1, 2017', items: [
4936+
'M1 : 3'
4937+
]});
4938+
4939+
_hover(gd, { xpx: 100, ypx: 250 });
4940+
assertLabel({title: 'Apr 1, 2017', items: [
4941+
'M3 : 10',
4942+
'M1 : 4'
4943+
]});
4944+
4945+
_hover(gd, { xpx: 125, ypx: 250 });
4946+
assertLabel({title: 'May 1, 2017', items: [
4947+
'M3 : (Apr 1, 2017, 10)',
4948+
'M1 : 5'
4949+
]});
4950+
4951+
_hover(gd, { xpx: 150, ypx: 250 });
4952+
assertLabel({title: 'Jun 1, 2017', items: [
4953+
'M3 : (Apr 1, 2017, 10)',
4954+
'M1 : 6'
4955+
]});
4956+
4957+
_hover(gd, { xpx: 175, ypx: 250 });
4958+
assertLabel({title: 'Jul 1, 2017', items: [
4959+
'M3 : 5',
4960+
'M1 : 7'
4961+
]});
4962+
4963+
_hover(gd, { xpx: 200, ypx: 250 });
4964+
assertLabel({title: 'Aug 1, 2017', items: [
4965+
'M3 : (Jul 1, 2017, 5)',
4966+
'M1 : 8'
4967+
]});
4968+
4969+
_hover(gd, { xpx: 225, ypx: 250 });
4970+
assertLabel({title: 'Sep 1, 2017', items: [
4971+
'M3 : (Jul 1, 2017, 5)',
4972+
'M1 : 9'
4973+
]});
4974+
4975+
_hover(gd, { xpx: 250, ypx: 250 });
4976+
assertLabel({title: 'Oct 1, 2017', items: [
4977+
'M3 : 10',
4978+
'M1 : 10'
4979+
]});
4980+
4981+
_hover(gd, { xpx: 275, ypx: 250 });
4982+
assertLabel({title: 'Nov 1, 2017', items: [
4983+
'M3 : (Oct 1, 2017, 10)',
4984+
'M1 : 11'
4985+
]});
4986+
4987+
_hover(gd, { xpx: 300, ypx: 250 });
4988+
assertLabel({title: 'Dec 1, 2017', items: [
4989+
'M3 : (Oct 1, 2017, 10)',
4990+
'M1 : 12'
4991+
]});
4992+
4993+
_hover(gd, { xpx: 350, ypx: 250 });
4994+
assertLabel({title: 'Jan 1, 2018', items: [
4995+
'M3 : 5'
4996+
]});
4997+
})
4998+
.then(done, done.fail);
4999+
});
5000+
47525001
it('should have the same traceorder as the legend', function(done) {
47535002
var mock = require('@mocks/stacked_area.json');
47545003
var mockCopy = Lib.extendDeep({}, mock);

0 commit comments

Comments
 (0)