# How to make 'shape' track mouse motion?

**URL:** <https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604>\
**Category:** plotly.js\
**Created:** [July 21, 2016, 2:49pm UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604 "2016-07-21T14:49:06Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![chris](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@chris](https://community.plotly.com/u/chris)\
**Post date:** [July 21, 2016, 2:49pm UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/1 "2016-07-21T14:49:06Z")

</div>

I have a requirement to provide a selection mechanism in one chart that will prompt a change in the data displayed in a related chart. The first chart is a smoothed x-y plot, let’s say covering an x range of 0 to 20, displayed in an element 800px wide. I have added an array of two rectangular shapes to the layout object of that chart. One of those should track the mouse motion, but snapping to integer values (i.e. when the mouse is at 4.87, the highlight will cover the interval from 4 to 5). A single click on the chart should lock the second highlight to the current position of the tracking highlight.

As far as I can tell, Plotly supports click and hover events but not motion. I don’t believe hover will help here, as the tracking is expected to work continuously, rather than only when in proximity of the the data. As a consequence, I’m now using jQuery motion events to get mouse coordinates within the SVG canvas. If I could get access to the underlying D3 scale object, I think I can map screen coordinates to data values. I would then need to use those values to update the shapes. I haven’t yet managed to confirm that that updating is a supported operation.

Is this possible? Am I approaching this the right way, or is there a less involved mechanism?

---

<div class="post-metadata">

**Author:** ![etienne](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/etienne/32/17_2.png) [@etienne](https://community.plotly.com/u/etienne)\
**Post date:** [July 22, 2016, 2:47pm UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/2 "2016-07-22T14:47:31Z")

</div>

> [@chris](#):
>
> As far as I can tell, Plotly supports click and hover events but not motion.

That’s correct. You might want to look at [http://codepen.io/etpinard/pen/EyydEj](http://codepen.io/etpinard/pen/EyydEj) for a _sorta hacky_ way to track cursor position on a plotly graph. I think that should add you need for your project. Let me know if you have any other questions.

---

<div class="post-metadata">

**Author:** ![chris](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@chris](https://community.plotly.com/u/chris)\
**Post date:** [August 1, 2016, 1:05pm UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/3 "2016-08-01T13:05:02Z")

</div>

Thanks etienne, that looks like exactly what I was needing (assuming I can successfully use .relayout() to move a shape).

---

<div class="post-metadata">

**Author:** ![vvv](https://avatars.discourse-cdn.com/v4/letter/v/41988e/32.png) [@vvv](https://community.plotly.com/u/vvv)\
**Post date:** [March 16, 2021, 2:12am UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/5 "2021-03-16T02:12:02Z")

</div>

The coordinates are not working after some basic action like zoom:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/plot/original/2X/8/83d3e6dfa2cfdbc37c22a237ad689a3d88b5b347.png)

---

<div class="post-metadata">

**Author:** ![alexGS](https://avatars.discourse-cdn.com/v4/letter/a/e495f1/32.png) [@alexGS](https://community.plotly.com/u/alexGS)\
**Post date:** [March 16, 2021, 10:04am UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/6 "2021-03-16T10:04:52Z")

</div>

Because you have old reference of chart’s layout. On relayout the chart’s area changes its boundaries values, and you need its new values. You should to update this variables on relayout

```auto
  var xaxis = gd._fullLayout.xaxis;
  var yaxis = gd._fullLayout.yaxis;
  var l = gd._fullLayout.margin.l;
  var t = gd._fullLayout.margin.t;

```

---

<div class="post-metadata">

**Author:** ![kassianefacanha](https://avatars.discourse-cdn.com/v4/letter/k/e9c0ed/32.png) [@kassianefacanha](https://community.plotly.com/u/kassianefacanha)\
**Post date:** [December 1, 2022, 3:00am UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/7 "2022-12-01T03:00:40Z")

</div>

how do i can do this in react ?

---

<div class="post-metadata">

**Author:** ![Bhushanw](https://avatars.discourse-cdn.com/v4/letter/b/3ab097/32.png) [@Bhushanw](https://community.plotly.com/u/Bhushanw)\
**Post date:** [December 1, 2022, 10:14am UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/8 "2022-12-01T10:14:02Z")

</div>

by using ref, gd is the just parent element of whole graph which will get created when you use , so just use ref and you should be able to access it.

---

<div class="post-metadata">

**Author:** ![HHFox](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/hhfox/32/11493_2.png) [@HHFox](https://community.plotly.com/u/HHFox)\
**Post date:** [April 30, 2023, 10:56am UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/9 "2023-04-30T10:56:33Z")

</div>

That’s a perfect solution. If your gd is not placed at the left border of the page, rather use evt.offsetX and evt.offsetY as they refer to the mouse position relative to the gd’s top left edge.

---

<div class="post-metadata">

**Author:** ![HHFox](https://sea2.discourse-cdn.com/flex024/user_avatar/community.plotly.com/hhfox/32/11493_2.png) [@HHFox](https://community.plotly.com/u/HHFox)\
**Post date:** [April 30, 2023, 11:04am UTC](https://community.plotly.com/t/how-to-make-shape-track-mouse-motion/1604/10 "2023-04-30T11:04:11Z")

</div>

Recently I struggled to to the same with geo plots, which have a different coordinate system. I wrote the following function to cover all (?) possibilities and also to clip events that occur outside of the plotting area:

```javascript
function eventToCursor(event) {
    var layout = gd._fullLayout
    x = event.offsetX - layout.margin.l
    y = event.offsetY - layout.margin.t
    if (x < 0 || y < 0 || x > layout.width || y > layout.height) {
        return
    }
    
    if (layout.hasOwnProperty('xaxis')) {
        x = layout.xaxis.p2c(x)
        y = layout.yaxis.p2c(y)
        cursor = {cursor: {x: x, y: y}}
    } else {
        if (layout.hasOwnProperty('geo')) {
            geo = layout.geo
        } else if (layout.hasOwnProperty('mapbox')) {
            geo = layout.mapbox
        } else {
            return
        }
        x = geo._subplot.xaxis.p2c()
        y = geo._subplot.yaxis.p2c()
        cursor = {cursor: {lon: x, lat: y}}
    }
    return cursor
}

```
