plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
17.09k stars 1.87k forks source link

'catch-all' hover/click events #2696

Open cpsievert opened 6 years ago

cpsievert commented 6 years ago

It'd be awesome to have dedicated events for obtaining the mouse position (in graph paper/axis coordinates) upon clicking/hovering anywhere on a plot.

This could be useful for many things, including adding annotations on click in a dash/shiny application. In fact, the R community is used to having this capability for any static figure in a shiny application.

PS. this is a feature request related to some existing threads, but was surprised that I couldn't find an existing GH issue

etpinard commented 6 years ago

That's probably an item in https://github.com/plotly/plotly.js/issues/145 about this already. But yeah, this probably deserves an issue of its own.

jonmmease commented 6 years ago

I like this idea.

One subtlety (at least to me!) that came to mind as I was thinking about this is that in order for the axis coordinates to be meaningful, the identity of the associated axes would need to be included somewhere in the event data. For example, the event data might indicate that the coordinates are with respect to xaxis and yaxis2.

jshukle commented 6 years ago

Yes! I have been hoping plotly would add this functionality to their R library for a while now. There are so many applications where this would expand my usage of plotly within my shiny apps.

vttrifonov commented 5 years ago

I am surprised this does not exist already. How do I do this until the feature is added? Surely there must be a way... Shiny does it.

ismirsehregal commented 5 years ago

Here is a workaround for R users based on this codepen. However, there is a small horizontal offset I couldn't get rid of so far.

sleighsoft commented 4 years ago

I am currently trying to add this to Plotly.js.

I would like to know if there is a way to transform an event into x/y coordinates within a graph axis? The current click does it by acessing a point underneath a click, which is not possible in the case of a click "anywhere".

I captured this event with the debugger while hovering over a graph.

The event I am talking about is used here:

https://github.com/plotly/plotly.js/blob/72c7f312133ab1f990c42b53d2f6d8b010ceb406/src/components/fx/click.js#L14

This is an example event

evt
    mousedown
    altKey: false
    bubbles: true
    button: 0
    buttons: 1
    cancelBubble: false
    cancelable: true
    clientX: 881
    clientY: 323
    composed: true
    ctrlKey: false
    currentTarget: null
    defaultPrevented: true
    detail: 1
    eventPhase: 0
    explicitOriginalTarget: <rect class="nsewdrag drag" style="fill: transparent; strok…x; pointer-events: all;" data-subplot="xy" x="80" y="100" width="853" height="270">
    isTrusted: true
    layerX: 881
    layerY: 243
    metaKey: false
    movementX: 0
    movementY: 0
    mozInputSource: 1
    mozPressure: 0
    offsetX: 0
    offsetY: 0
    originalTarget: <rect class="nsewdrag drag" style="fill: transparent; strok…x; pointer-events: all;" data-subplot="xy" x="80" y="100" width="853" height="270">
    pageX: 881
    pageY: 323
    pointerX: 881
    pointerY: 243
    rangeOffset: 0
    rangeParent: null
    region: ""
    relatedTarget: null
    returnValue: false
    screenX: 881
    screenY: 397
    shiftKey: false
    srcElement: <rect class="nsewdrag drag" style="fill: transparent; strok…x; pointer-events: all;" data-subplot="xy" x="80" y="100" width="853" height="270">​
    target: <rect class="nsewdrag drag" style="fill: transparent; strok…x; pointer-events: all;" data-subplot="xy" x="80" y="100" width="853" height="270">
    timeStamp: 4803793
    type: "mousedown"
    view: Window http://localhost:3000/devtools/test_dashboard/index.html#line_style
    which: 1
    x: 881
    y: 323
    <get isTrusted()>: function isTrusted()
    <prototype>: MouseEventPrototype { initMouseEvent: initMouseEvent(), getModifierState: getModifierState(), initNSMouseEvent: initNSMouseEvent(), … }

I want to obtain the coordinates within the axis as is currently done within gd._hoverdata:

gd._hoverdata
    curveNumber: 0
    data: Object { mode: "markers", name: "North America", type: "scatter", … }
    fullData: Object { type: "scatter", uid: "163286", visible: true, … }
    pointIndex: 0
    pointNumber: 0
    text: "United States"
    x: 52698
    xaxis: Object { _attr: "xaxis", _name: "xaxis", _id: "x", … }
    y: 53
    yaxis: Object { _attr: "yaxis", _name: "yaxis", _id: "y", … }
    <prototype>: Object { … }

I used the line_style example when running npm run start: grafik

Besides not knowing how to transform a x/y click coordinates to axis coordinates, I have the following ideas:

Let me know what you all think and any help on the above is very welcome.

hp8wvvvgnj6asjm7 commented 3 years ago

omg I need this. ~_~

FabSN commented 3 years ago

Is there an update about this issue ?

amaralc commented 3 years ago

I also have been looking for this feature. The onHover option already gives access to the point closest to the mouse position, but I could not do the same for the onClick method. By the way, I'm using plotly with React, in JavaScript.

TheLogan commented 3 years ago

One issue with the example workaround is that it doesn't account for padding/margin in parent objects

I've taken the example and added a parent div that has both padding and margin on the left side, this then skews the value of the x-axis value, and is clearly something that would need to be handled in such a solution as is suggested here.

updated example: https://codepen.io/tim-logan/pen/yLXgpyp

I found this issue because I was trying to do something similar for a library I'm working on internally for the company I work for, we want a "hoveron='line'" feature for our scatter plots and I figured I could write that, but I've yet to find a way to handle parent padding/margins.