1

Having an issue. Using plotly.js to draw a scatter chart, I need to be able to click on the chart and retrieve the values of the point so that I can draw a new point at the clicked location. The plotly_click event only fires on already created points.

Any ideas how I can get a click event to get the current values from the location so I can plot the new point?

So far I'm only getting this:

var trace1 = {
    x: [1, 2, 3, 4],
    y: [10, 15, 13, 17],
    mode: 'markers',
    type: 'scatter'
};

var trace2 = {
    x: [2, 3, 4, 5],
    y: [16, 5, 11, 9],
    mode: 'lines',
    type: 'scatter'
};

var trace3 = {
    x: [1, 2, 3, 4],
    y: [12, 9, 15, 12],
    mode: 'lines+markers',
    type: 'scatter'
};

var data = [trace1, trace2, trace3];

Plotly.newPlot('myDiv', data);

document.getElementById('myDiv').on('plotly_click', function(data){
    var pts = '';

    for(var i=0; i < data.points.length; i++){
        pts = 'x = ' + data.points[i].x +'\ny = ' + data.points[i].y.toPrecision(4) + '\n\n';
    }

    alert('Closest point clicked:\n\n'+pts);
});

https://codepen.io/mayasky76/pen/ZXRRMJ/

krlzlx
  • 5,752
  • 14
  • 47
  • 55
Iain Wood
  • 21
  • 1
  • 5

1 Answers1

1

Many thanks to Maximillian Peters for this

Now have a scatter graph that reports location (xy) value on mousemove and plots a point to the chart on click

<head>
  <!-- Plotly.js -->
   <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>

<body>
  x :<input id="xvalue" size="5"  /> y :<input id="yvalue" size="5" /> 
 <div id="myPlot" style="width:100%;height:100%"></div>
  <script>
    <!-- JAVASCRIPT CODE GOES HERE -->
  </script>
</body>

Javascript

var traces = [{
  x: [1, 2, 3, 4],
  y: [10, 15, 13, 17],
  mode: 'markers',
  type: 'scatter'
}];

traces.push({
  x: [2, 3, 4, 5],
  y: [16, 5, 11, 9],
  mode: 'markers',
  type: 'scatter'
});

traces.push({
  x: [1, 2, 3, 4],
  y: [12, 9, 15, 12],
  mode: 'markers',
  type: 'scatter'
});

traces.push({
  x: [],
  y: [],
  mode: 'markers',
  type: 'scatter'
});

var myPlot = document.getElementById('myPlot')
Plotly.newPlot('myPlot', traces, {hovermode: 'closest'});

Number.prototype.between = function(min, max) {
  return this >= min && this <= max;
};


Plotly.d3.select(".plotly").on('click', function(d, i) {
  var e = Plotly.d3.event;
  var bg = document.getElementsByClassName('bg')[0];
  var x = ((e.layerX - bg.attributes['x'].value + 4) / (bg.attributes['width'].value)) * (myPlot.layout.xaxis.range[1] - myPlot.layout.xaxis.range[0]) + myPlot.layout.xaxis.range[0];
  var y = ((e.layerY - bg.attributes['y'].value + 4) / (bg.attributes['height'].value)) * (myPlot.layout.yaxis.range[0] - myPlot.layout.yaxis.range[1]) + myPlot.layout.yaxis.range[1]
  if (x.between(myPlot.layout.xaxis.range[0], myPlot.layout.xaxis.range[1]) &&
    y.between(myPlot.layout.yaxis.range[0], myPlot.layout.yaxis.range[1])) {
    Plotly.extendTraces(myPlot, {
      x: [
        [x]
      ],
      y: [
        [y]
      ]
    }, [3]);
  }
});

Plotly.d3.select(".plotly").on('mousemove', function(d, i) {
  var e = Plotly.d3.event;
  var bg = document.getElementsByClassName('bg')[0];
  var x = ((e.layerX - bg.attributes['x'].value + 4) / (bg.attributes['width'].value)) * (myPlot.layout.xaxis.range[1] - myPlot.layout.xaxis.range[0]) + myPlot.layout.xaxis.range[0];
  var y = ((e.layerY - bg.attributes['y'].value + 4) / (bg.attributes['height'].value)) * (myPlot.layout.yaxis.range[0] - myPlot.layout.yaxis.range[1]) + myPlot.layout.yaxis.range[1]
  if (x.between(myPlot.layout.xaxis.range[0], myPlot.layout.xaxis.range[1]) &&
    y.between(myPlot.layout.yaxis.range[0], myPlot.layout.yaxis.range[1])) {
    console.log("Location X:"+x+" Y"+y)
   document.getElementById("xvalue").value = x;
   document.getElementById("yvalue").value = y;
  }
});

https://codepen.io/mayasky76/pen/ZXRRMJ

Iain Wood
  • 21
  • 1
  • 5
  • The given link seems expired. Here is the new one https://codepen.io/circleoncircles/pen/abObLLE I cannot replicate the behaviour. Only what I see so far is that the x,y value change when hover over plotly toolbox – CircleOnCircles Feb 06 '20 at 12:32
  • Changes to plotly have led to different elements needing to be chosen for this. The version crossover where the behavior stopped working as documented in this answer was 1.41.3 to 1.42.0. I had a version working as of Apr 2022 posted as an answer to this question: https://stackoverflow.com/questions/71755717/plotly-js-adding-point-on-click-2022/71757501#71757501 – jranalli Apr 05 '22 at 19:47