✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

Get movable shape position on mouse move

I have this code, that removes data points from inside a area marked by a circular shape,

<head>

    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
  </head>
  <div id="tester" style="width:90%;height:90%;"></div>
  
  <script>
        const test = document.getElementById('tester')
        f = Plotly.d3.random.normal(100,10)
        xx = Plotly.d3.range(1,100,1)
        yy = xx.map(_=>f())

        Plotly.plot(test, 
            [{
                mode:"markers+lines",
                x: xx,
                y: yy ,
                line:{
                    width :1,
                    color:"blue"
                },
                marker:{
                    color:"red"
                }
            }], { 
                margin: { t: 0 } ,
                shapes: [{
                    type: 'circle',
                    xref: 'paper',
                    yref: 'paper',
                    x0: .4,
                    y0: .4,
                    x1: .4 + .2*(test.offsetHeight/test.offsetWidth),
                    y1: .6,
                    opacity: 0.5,
                    fillcolor: 'green',
                    line: {
                        color: 'green'
                    }
                }]
            }, {
                showSendToCloud:true,
                editable:true
            }
        );



    function repulsePoints(){
      var shape = test.layout.shapes[0]
      rangeX = test._fullLayout.xaxis.range
      rangeY = test._fullLayout.yaxis.range
      rnX = rangeX[1] - rangeX[0]
      rnY = rangeY[1] - rangeY[0]

      var cX = rangeX[0]+ (shape.x1+shape.x0)*rnX/2
      var cY = rangeY[0]+ (shape.y1+shape.y0)*rnY/2
      var rX = (shape.x1-shape.x0)*rnX/2
      var rY = (shape.y1-shape.y0)*rnY/2

      var dpsX = test.data[0].x
      var dpsY = test.data[0].y
      var dX,dY;
      var listOfPoinsts = []

      for(let i=0;i<dpsX.length;i++){
           dX = ((dpsX[i]-cX)/rX)**2
           dY = ((dpsY[i]-cY)/rY)**2
           val= dX+dY
           if(val<1) listOfPoinsts.push([i,dX,dY   ])

      }
      // find the closest point

      if(listOfPoinsts.length){
        // get minimum
        minIndex = listOfPoinsts[0][0]
        minVal =   listOfPoinsts[0][1] + listOfPoinsts[0][2]
        listOfPoinsts.forEach((elem)=>{
            val = elem[1] + elem[2]
            if(val<minVal){
                minVal = val
                minIndex = elem[0]
            }
        })
        sign = cY<dpsY[minIndex]  ? +1 : -1
        
        listOfPoinsts.forEach(elem=>{
            shift = cY + rY*Math.sqrt(1- elem[1])*sign
            dpsY[elem[0]] = shift
        })
        
        Plotly.restyle(test, {y: [dpsY]})
      }
  }
  repulsePoints()
  test.on("plotly_relayout",repulsePoints)


  </script>

Now if you drag the shape it will remove the points outside. This works fine but only when you are done with the drag i.e. when the relayout is emitted.

I want to run the funciton on every mousemove, i.e. the points will be removed while dragging. I can simply do test.onmousemove=repulsePoints but the shape position information in test.layout.shapes doesn’t change while dragging. Is there a way to get the position of the shape while dragging?