'Click anywhere' 剧情中的事件

'Click anywhere' event in plotly

我正在尝试在 plotly 中实现一个 'click anywhere' 功能,这样我就可以在用户点击 plotly 图表的任何地方时获得坐标。当前的“官方”绘图功能仅在用户单击绘制的数据点时有效,但我想注册点击,例如在白色背景上 canvas.

绘图的闪亮点击事件可以做到这一点,但令人惊讶的是,这在 plotly 中似乎还不存在。

我做了一些研究,发现了以下接近的代码笔实现:https://codepen.io/tim-logan/pen/yLXgpyp

#JS
var d3 = Plotly.d3;
var gd = document.getElementById('graph');

Plotly.plot('graph', [{
  y: [2, 1, 2]
}])
.then(attach);

function attach() {
  var xaxis = gd._fullLayout.xaxis;
  var yaxis = gd._fullLayout.yaxis;
  var l = gd._fullLayout.margin.l;
  var t = gd._fullLayout.margin.t;
  
  gd.addEventListener('mousemove', function(evt) {
    var xInDataCoord = xaxis.p2c(evt.x - l);
    var yInDataCoord = yaxis.p2c(evt.y - t);
    console.log(evt.x, l)
    
    Plotly.relayout(gd, 'title', ['x: ' + xInDataCoord, 'y : ' + yInDataCoord].join('<br>'));
  });
}

# HTML
<head>
  <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
  <div style="padding-left: 100px; margin-left: 100px">
    <div id="graph"></div>
  </div>
</body>

然而,正如 codepen 的创建者指出的那样,点击坐标并不精确,因为它们没有考虑填充/边距:

One issue with the example workaround is that it doesn't account for padding/margin in parent objects. I've taken the example and added a parent div that has both padding and margin on the left side, this then skews the value of the x-axis value, and is clearly something that would need to be handled in such a solution as is suggested here.

根据 flot 文档,这应该可以通过从坐标中减去绘图偏移量来绘制对象: https://github.com/flot/flot/blob/master/API.md#plot-methods

参见例如以下摘录:

Various things are stuffed inside an axis object, e.g. you could use getAxes().xaxis.ticks to find out what the ticks are for the xaxis. Two other useful attributes are p2c and c2p, functions for transforming from data point space to the canvas plot space and back. Both returns values that are offset with the plot offset.

或:

offset()

Returns the offset of the plotting area inside the grid relative to the document, useful for instance for calculating mouse positions (event.pageX/Y minus this offset is the pixel position inside the plot).

我试图实现基于 offset() 的解决方法,但由于我的 js 知识不太好,我无法获得代码的工作版本。

有人能提供解决偏移问题的解决方法吗?

我设法通过获取父框的尺寸来消除偏移。请参阅以下修复上述代码笔的示例:

var d3 = Plotly.d3;
var gd = document.getElementById('graph');

Plotly.plot('graph', [{
  y: [2, 1, 2]
}])
.then(attach);

function attach() {
  
  gd.addEventListener('mousemove', function(evt) {
    var bb = evt.target.getBoundingClientRect();
    var x = gd._fullLayout.xaxis.p2d(evt.clientX - bb.left);
    var y = gd._fullLayout.yaxis.p2d(evt.clientY - bb.top);
    
    Plotly.relayout(gd, 'title', ['x: ' + x, 'y : ' + y].join('<br>'));
  });
}

在此处修复代码笔:https://codepen.io/flaviofusero/pen/BaZRgzO

此处改编自 sleighsoft 的实施:plotly click events from anywhere on the plot