Skip to content

Commit 0c9962c

Browse files
committed
Cartesian dropline support
Draw droplines to the x and y axes on hover if the option is enabled and we're not on 'compare' hovermode.
1 parent 2b24f9d commit 0c9962c

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

src/components/dragelement/unhover.js

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ unhover.raw = function unhoverRaw(gd, evt) {
4141
}
4242

4343
fullLayout._hoverlayer.selectAll('g').remove();
44+
fullLayout._hoverlayer.selectAll('line').remove();
4445
gd._hoverdata = undefined;
4546

4647
if(evt.target && oldhoverdata) {

src/plot_api/plot_config.js

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ module.exports = {
4848
// new users see some hints about interactivity
4949
showTips: true,
5050

51+
// display droplines on cartesian graphs
52+
showDroplines: false,
53+
5154
// enable axis pan/zoom drag handles
5255
showAxisDragHandles: true,
5356

src/plots/cartesian/graph_interact.js

+46-3
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,9 @@ function hover(gd, evt, subplot) {
563563
// rotate the labels so they don't overlap
564564
var rotateLabels = hovermode === 'y' && searchData.length > 1;
565565

566+
var oldhoverdata = gd._hoverdata,
567+
newhoverdata = [];
568+
566569
hoverData.sort(function(d1, d2) { return d1.distance - d2.distance; });
567570

568571
var bgColor = Color.combine(
@@ -577,16 +580,23 @@ function hover(gd, evt, subplot) {
577580
container: fullLayout._hoverlayer,
578581
outerContainer: fullLayout._paperdiv
579582
};
583+
584+
if(gd._context.showDroplines && hoverChanged(gd, evt, oldhoverdata)) {
585+
var droplineOpts = {
586+
hovermode: hovermode,
587+
container: fullLayout._hoverlayer,
588+
outerContainer: fullLayout._paperdiv
589+
};
590+
createDroplines(hoverData, droplineOpts);
591+
}
592+
580593
var hoverLabels = createHoverText(hoverData, labelOpts);
581594

582595
hoverAvoidOverlaps(hoverData, rotateLabels ? 'xa' : 'ya');
583596

584597
alignHoverText(hoverLabels, rotateLabels);
585598

586599
// lastly, emit custom hover/unhover events
587-
var oldhoverdata = gd._hoverdata,
588-
newhoverdata = [];
589-
590600
// pull out just the data that's useful to
591601
// other people and send it to the event
592602
for(itemnum = 0; itemnum < hoverData.length; itemnum++) {
@@ -818,8 +828,41 @@ fx.loneUnhover = function(containerOrSelection) {
818828
d3.select(containerOrSelection);
819829

820830
selection.selectAll('g.hovertext').remove();
831+
selection.selectAll('line.dropline').remove();
821832
};
822833

834+
function createDroplines(hoverData, opts) {
835+
var hovermode = opts.hovermode,
836+
container = opts.container;
837+
838+
if(hovermode !== 'closest') return;
839+
var c0 = hoverData[0];
840+
var x = (c0.x0 + c0.x1) / 2;
841+
var y = (c0.y0 + c0.y1) / 2;
842+
var xOffset = c0.xa._offset;
843+
var yOffset = c0.ya._offset;
844+
container.selectAll('line.dropline').remove();
845+
container.append('line')
846+
.attr('x1', xOffset + (c0.ya.side === 'right' ? c0.xa._length : 0))
847+
.attr('x2', xOffset + x)
848+
.attr('y1', yOffset + y)
849+
.attr('y2', yOffset + y)
850+
.attr('stroke-width', 3)
851+
.attr('stroke', c0.color)
852+
.attr('stroke-dasharray', '5,5')
853+
.attr('class', 'dropline');
854+
855+
container.append('line')
856+
.attr('x1', xOffset + x)
857+
.attr('x2', xOffset + x)
858+
.attr('y1', yOffset + y)
859+
.attr('y2', yOffset + c0.ya._length)
860+
.attr('stroke-width', 3)
861+
.attr('stroke', c0.color)
862+
.attr('stroke-dasharray', '5,5')
863+
.attr('class', 'dropline');
864+
}
865+
823866
function createHoverText(hoverData, opts) {
824867
var hovermode = opts.hovermode,
825868
rotateLabels = opts.rotateLabels,

0 commit comments

Comments
 (0)