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?