diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 566c47d368a..a13f701c47b 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -133,6 +133,16 @@ function setPositionOffset(traceType, gd, boxList, posAxis) { var edge = bPos + bdPos; var edgeplus; var edgeminus; + // value-space padding + var vpadplus; + var vpadminus; + // pixel-space padding + var ppadplus; + var ppadminus; + // do we add 5% of both sides (more logic for points beyond box/violin below) + var padded = Boolean(width); + // does this trace show points? + var hasPts = (trace.boxpoints || trace.points) && (shownPts > 0); if(side === 'positive') { pushplus = dPos * (width ? 1 : 0.5); @@ -147,17 +157,6 @@ function setPositionOffset(traceType, gd, boxList, posAxis) { edgeplus = edgeminus = edge; } - // value-space padding - var vpadplus; - var vpadminus; - // pixel-space padding - var ppadplus; - var ppadminus; - // do we add 5% of both sides (for points beyond box/violin) - var padded = false; - // does this trace show points? - var hasPts = (trace.boxpoints || trace.points) && (shownPts > 0); - if(hasPts) { var pointpos = trace.pointpos; var jitter = trace.jitter; diff --git a/src/traces/box/hover.js b/src/traces/box/hover.js index c97d040db43..f5dd7f3e722 100644 --- a/src/traces/box/hover.js +++ b/src/traces/box/hover.js @@ -58,6 +58,7 @@ function hoverOnBoxes(pointData, xval, yval, hovermode) { hoverPseudoDistance, spikePseudoDistance; var boxDelta = t.bdPos; + var boxDeltaPos, boxDeltaNeg; var posAcceptance = t.wHover; var shiftPos = function(di) { return di.pos + t.bPos - pVal; }; @@ -67,18 +68,23 @@ function hoverOnBoxes(pointData, xval, yval, hovermode) { var pos = shiftPos(di); return Fx.inbox(pos, pos + posAcceptance, hoverPseudoDistance); }; + boxDeltaPos = boxDelta; + boxDeltaNeg = 0; } if(trace.side === 'negative') { dPos = function(di) { var pos = shiftPos(di); return Fx.inbox(pos - posAcceptance, pos, hoverPseudoDistance); }; + boxDeltaPos = 0; + boxDeltaNeg = boxDelta; } } else { dPos = function(di) { var pos = shiftPos(di); return Fx.inbox(pos - posAcceptance, pos + posAcceptance, hoverPseudoDistance); }; + boxDeltaPos = boxDeltaNeg = boxDelta; } var dVal; @@ -134,8 +140,8 @@ function hoverOnBoxes(pointData, xval, yval, hovermode) { else if(Color.opacity(mc) && trace.boxpoints) pointData.color = mc; else pointData.color = trace.fillcolor; - pointData[pLetter + '0'] = pAxis.c2p(di.pos + t.bPos - boxDelta, true); - pointData[pLetter + '1'] = pAxis.c2p(di.pos + t.bPos + boxDelta, true); + pointData[pLetter + '0'] = pAxis.c2p(di.pos + t.bPos - boxDeltaNeg, true); + pointData[pLetter + '1'] = pAxis.c2p(di.pos + t.bPos + boxDeltaPos, true); pointData[pLetter + 'LabelVal'] = di.pos; diff --git a/test/image/baselines/violin_box_multiple_widths.png b/test/image/baselines/violin_box_multiple_widths.png index 64a88204221..e9e398567ca 100644 Binary files a/test/image/baselines/violin_box_multiple_widths.png and b/test/image/baselines/violin_box_multiple_widths.png differ diff --git a/test/image/baselines/violin_ridgeplot.png b/test/image/baselines/violin_ridgeplot.png new file mode 100644 index 00000000000..b463360a30e Binary files /dev/null and b/test/image/baselines/violin_ridgeplot.png differ diff --git a/test/image/mocks/violin_ridgeplot.json b/test/image/mocks/violin_ridgeplot.json new file mode 100644 index 00000000000..1cccf678e1b --- /dev/null +++ b/test/image/mocks/violin_ridgeplot.json @@ -0,0 +1,655 @@ +{ + "data": [ + { + "alignmentgroup": "True", + "box": { + "visible": false + }, + "hoverlabel": { + "namelength": 0 + }, + "hovertemplate": "day=%{y}
total_bill=%{x}", + "legendgroup": "day=Fri", + "marker": { + "color": "#636efa" + }, + "name": "day=Fri", + "offsetgroup": "day=Fri", + "orientation": "h", + "scalegroup": "True", + "showlegend": true, + "side": "positive", + "type": "violin", + "uid": "fd5eb9e2-17e5-4b44-ae2b-b4d98cb712cd", + "width": 1.5, + "x": [ + 28.97, + 22.49, + 5.75, + 16.32, + 22.75, + 40.17, + 27.28, + 12.03, + 21.01, + 12.46, + 11.35, + 15.38, + 12.16, + 13.42, + 8.58, + 15.98, + 13.42, + 16.27, + 10.09 + ], + "x0": " ", + "xaxis": "x", + "y": [ + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri", + "Fri" + ], + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "box": { + "visible": false + }, + "hoverlabel": { + "namelength": 0 + }, + "hovertemplate": "day=%{y}
total_bill=%{x}", + "legendgroup": "day=Sat", + "marker": { + "color": "#EF553B" + }, + "name": "day=Sat", + "offsetgroup": "day=Sat", + "orientation": "h", + "scalegroup": "True", + "showlegend": true, + "side": "positive", + "type": "violin", + "uid": "4ad69be3-ffdc-4f5d-ab5a-560d7e79da5a", + "width": 1.5, + "x": [ + 20.65, + 17.92, + 20.29, + 15.77, + 39.42, + 19.82, + 17.81, + 13.37, + 12.69, + 21.7, + 19.65, + 9.55, + 18.35, + 15.06, + 20.69, + 17.78, + 24.06, + 16.31, + 16.93, + 18.69, + 31.27, + 16.04, + 38.01, + 26.41, + 11.24, + 48.27, + 20.29, + 13.81, + 11.02, + 18.29, + 17.59, + 20.08, + 16.45, + 3.07, + 20.23, + 15.01, + 12.02, + 17.07, + 26.86, + 25.28, + 14.73, + 10.51, + 17.92, + 44.3, + 22.42, + 20.92, + 15.36, + 20.49, + 25.21, + 18.24, + 14.31, + 14, + 7.25, + 10.59, + 10.63, + 50.81, + 15.81, + 26.59, + 38.73, + 24.27, + 12.76, + 30.06, + 25.89, + 48.33, + 13.27, + 28.17, + 12.9, + 28.15, + 11.59, + 7.74, + 30.14, + 20.45, + 13.28, + 22.12, + 24.01, + 15.69, + 11.61, + 10.77, + 15.53, + 10.07, + 12.6, + 32.83, + 35.83, + 29.03, + 27.18, + 22.67, + 17.82 + ], + "x0": " ", + "xaxis": "x", + "y": [ + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat", + "Sat" + ], + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "box": { + "visible": false + }, + "hoverlabel": { + "namelength": 0 + }, + "hovertemplate": "day=%{y}
total_bill=%{x}", + "legendgroup": "day=Sun", + "marker": { + "color": "#00cc96" + }, + "name": "day=Sun", + "offsetgroup": "day=Sun", + "orientation": "h", + "scalegroup": "True", + "showlegend": true, + "side": "positive", + "type": "violin", + "uid": "d330e0bc-9124-41f9-8284-2d6798be84a6", + "width": 1.5, + "x": [ + 16.99, + 10.34, + 21.01, + 23.68, + 24.59, + 25.29, + 8.77, + 26.88, + 15.04, + 14.78, + 10.27, + 35.26, + 15.42, + 18.43, + 14.83, + 21.58, + 10.33, + 16.29, + 16.97, + 17.46, + 13.94, + 9.68, + 30.4, + 18.29, + 22.23, + 32.4, + 28.55, + 18.04, + 12.54, + 10.29, + 34.81, + 9.94, + 25.56, + 19.49, + 38.07, + 23.95, + 25.71, + 17.31, + 29.93, + 14.07, + 13.13, + 17.26, + 24.55, + 19.77, + 29.85, + 48.17, + 25, + 13.39, + 16.49, + 21.5, + 12.66, + 16.21, + 13.81, + 17.51, + 24.52, + 20.76, + 31.71, + 7.25, + 31.85, + 16.82, + 32.9, + 17.89, + 14.48, + 9.6, + 34.63, + 34.65, + 23.33, + 45.35, + 23.17, + 40.55, + 20.69, + 20.9, + 30.46, + 18.15, + 23.1, + 15.69 + ], + "x0": " ", + "xaxis": "x", + "y": [ + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun", + "Sun" + ], + "y0": " ", + "yaxis": "y" + }, + { + "alignmentgroup": "True", + "box": { + "visible": false + }, + "hoverlabel": { + "namelength": 0 + }, + "hovertemplate": "day=%{y}
total_bill=%{x}", + "legendgroup": "day=Thur", + "marker": { + "color": "#ab63fa" + }, + "name": "day=Thur", + "offsetgroup": "day=Thur", + "orientation": "h", + "scalegroup": "True", + "showlegend": true, + "side": "positive", + "type": "violin", + "uid": "07ae9d99-772f-4723-a260-60adf7972626", + "width": 1.5, + "x": [ + 27.2, + 22.76, + 17.29, + 19.44, + 16.66, + 10.07, + 32.68, + 15.98, + 34.83, + 13.03, + 18.28, + 24.71, + 21.16, + 10.65, + 12.43, + 24.08, + 11.69, + 13.42, + 14.26, + 15.95, + 12.48, + 29.8, + 8.52, + 14.52, + 11.38, + 22.82, + 19.08, + 20.27, + 11.17, + 12.26, + 18.26, + 8.51, + 10.33, + 14.15, + 16, + 13.16, + 17.47, + 34.3, + 41.19, + 27.05, + 16.43, + 8.35, + 18.64, + 11.87, + 9.78, + 7.51, + 19.81, + 28.44, + 15.48, + 16.58, + 7.56, + 10.34, + 43.11, + 13, + 13.51, + 18.71, + 12.74, + 13, + 16.4, + 20.53, + 16.47, + 18.78 + ], + "x0": " ", + "xaxis": "x", + "y": [ + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur", + "Thur" + ], + "y0": " ", + "yaxis": "y" + } + ], + "layout": { + "grid": { + "xaxes": [ + "x" + ], + "xgap": 0.1, + "xside": "bottom", + "yaxes": [ + "y" + ], + "ygap": 0.1, + "yside": "left" + }, + "height": 600, + "legend": { + "tracegroupgap": 0 + }, + "margin": { + "t": 60 + }, + "violinmode": "group", + "xaxis": { + "title": { + "text": "total_bill" + } + }, + "yaxis": { + "categoryarray": [ + "Thur", + "Sun", + "Sat", + "Fri" + ], + "categoryorder": "array", + "title": { + "text": "day" + } + } + } +} diff --git a/test/jasmine/tests/box_test.js b/test/jasmine/tests/box_test.js index d169d661093..ba5321104b0 100644 --- a/test/jasmine/tests/box_test.js +++ b/test/jasmine/tests/box_test.js @@ -579,11 +579,11 @@ describe('Test box restyle:', function() { y0: 0.1 }]) .then(function() { - _assert('base', [-0.2, 1.5], [-0.444, 8.444]); + _assert('base', [-0.289, 1.5], [-0.444, 8.444]); return Plotly.restyle(gd, 'visible', [true, 'legendonly']); }) .then(function() { - _assert('only trace0 visible', [-0.2, 0.2], [-0.444, 8.444]); + _assert('only trace0 visible', [-0.2222, 0.2222], [-0.444, 8.444]); return Plotly.restyle(gd, 'visible', ['legendonly', true]); }) .then(function() { diff --git a/test/jasmine/tests/violin_test.js b/test/jasmine/tests/violin_test.js index 80bfa26d8a5..d4ac9aa4698 100644 --- a/test/jasmine/tests/violin_test.js +++ b/test/jasmine/tests/violin_test.js @@ -347,6 +347,14 @@ describe('Test violin hover:', function() { return Plotly.plot(gd, fig).then(function() { mouseEvent('mousemove', pos[0], pos[1]); assertHoverLabelContent(specs); + + if(specs.hoverLabelPos) { + d3.selectAll('g.hovertext').each(function(_, i) { + var bbox = this.getBoundingClientRect(); + expect([bbox.bottom, bbox.top]) + .toBeWithinArray(specs.hoverLabelPos[i], 10, 'bottom--top hover label ' + i); + }); + } }); } @@ -512,6 +520,24 @@ describe('Test violin hover:', function() { nums: 'x: 42.43046, kde: 0.083', name: '', axis: 'Saturday' + }, { + desc: 'one-sided violin under hovermode y (ridgeplot case)', + mock: require('@mocks/violin_ridgeplot.json'), + patch: function(fig) { + fig.data.forEach(function(t) { t.hoveron = 'violins'; }); + fig.layout.hovermode = 'y'; + return fig; + }, + nums: [ + 'max: 50.81', 'median: 18.24', 'min: 3.07', + 'q1: 13.8575', 'q3: 24.975', 'upper fence: 39.42' + ], + name: ['', '', '', '', '', ''], + axis: 'Sat', + hoverLabelPos: [ + [364, 270], [339, 270], [352, 270], + [346, 270], [349, 270], [387, 270] + ] }, { desc: 'single horizontal violin', mock: require('@mocks/violin_non-linear.json'),