Iain Wood
Iain Wood

Reputation: 21

Plotly.js create a point on click

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/

Upvotes: 1

Views: 4177

Answers (1)

Iain Wood
Iain Wood

Reputation: 21

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

Upvotes: 1

Related Questions