Javascript (Vis.js网络)getPositions的节点坐标不正确?

Javascript (Vis.js网络)getPositions的节点坐标不正确?,javascript,popup,vis.js,vis.js-network,Javascript,Popup,Vis.js,Vis.js Network,在我的vis.js网络中,我想在单击某个节点时,在该节点的位置上显示一个弹出窗口 我使用了getPositions方法,但是弹出窗口出现在错误的位置(左上角太多),好像坐标不正确 network.on("click", function (params) { // Get the node ID var nodeId = params.nodes[0]; if (nodeId) { // Get the node titl

在我的vis.js网络中,我想在单击某个节点时,在该节点的位置上显示一个弹出窗口

我使用了getPositions方法,但是弹出窗口出现在错误的位置(左上角太多),好像坐标不正确

network.on("click", function (params) {
        // Get the node ID
        var nodeId = params.nodes[0];
        if (nodeId) {

            // Get the node title to show in the popup
            var popup = this.body.nodes[nodeId].options.title;

            // Get the node coordinates
            var nodePosition = network.getPositions(nodeId);
            var nodeX = nodePosition[nodeId].x;
            var nodeY = nodePosition[nodeId].y;

            // Show the tooltip in a div
            document.getElementById('popup').innerHTML = popup;
            document.getElementById('popup').style.display = "block";
            // Place the div
            document.getElementById('popup').style.position = "absolute";
            document.getElementById('popup').style.top = nodeY+'px';
            document.getElementById('popup').style.left = nodeX+'px';

        }
    });
    // Empty and hide the div when click elsewhere
    network.on("deselectNode", function (params) {
        document.getElementById('popup').innerHTML = null;
        document.getElementById('popup').style.display = "none";
    });

您正在使用network.getPositions(params.nodes[0]),但由于在画布上放大、缩小和移动网络时节点可能会发生很大变化,因此这些位置与节点的实际位置不匹配。我不知道这是visjs中的一个bug,还是有其他原因。文档说它们返回了节点在画布空间中的位置。但你的例子显然不是这样

查看文档[],单击事件参数包含:

{
    nodes: [Array of selected nodeIds],
    edges: [Array of selected edgeIds],
    event: [Object] original click event,
    pointer: {
        DOM: {x:pointer_x, y:pointer_y},     // << Try using this values
        canvas: {x:canvas_x, y:canvas_y}
    }
}
--未经测试

我在这方面得到了一些帮助。 原来,诀窍是使用
canvasToDOM()

下面是它如何应用于我的代码:

network.on("click", function(params) {
  // Get the node ID
  var nodeId = params.nodes[0];
  if (nodeId) {
    // Get the node title to show in the popup
    var popup = this.body.nodes[nodeId].options.title;

    // Get the node coordinates
    var { x: nodeX, y: nodeY } = network.canvasToDOM(
      network.getPositions([nodeId])[nodeId]
    );

    // Show the tooltip in a div
    document.getElementById("popup").style.display = "block";
    // Place the div
    document.getElementById("popup").style.position = "absolute";
    document.getElementById("popup").style.top = nodeY + "px";
    document.getElementById("popup").style.left = nodeX + "px";
  }
});

当网络处于静止状态时,它可以工作,但在我的例子中,我希望适应网络并放大单击的节点,因此不会出现弹出窗口,但由于这是一个单独的问题,我将发布另一个问题。

为了更快地响应:创建一个JSFIDLE或类似的工具,以便用户可以用自己的眼睛快速看到问题。另外,如果弹出窗口总是与顶部和左侧对齐过多,你不能通过在代码中添加一些像素来说明这一点吗?比如:style.top=10+nodeY+'px'我刚刚在我的帖子中添加了一个链接来查看结果。我无法在代码中添加像素,因为每个弹出窗口的偏移量并不完全相同。我认为它们都有节点的形状,但看起来它们不在同一缩放级别上,就像我的节点在zoom 1,而getPositions返回的节点位置在zoom 1.5(我实际上没有这些值,这只是它看起来的一个示例)。我现在看到了。请再次删除问题中的链接。以防止将来断开链接。对于这样的图,可以包含一个屏幕截图。它听起来确实像一个bug,因为我在提供的基本示例中也测试了它,结果是一样的。我已经测试了你的解决方案,这是我的计划。。。这真的不是很理想,因为当我点击一个节点时,我也会使用fit()函数来缩放一组节点(我只是在我的帖子中展示的演示中禁用了它)。因此,如果我使弹出窗口出现在指针坐标处,它就出现在我单击的位置,但由于视图随后在画布上的其他位置缩放,弹出窗口不再位于正确的位置。是的,您必须考虑如何处理缩放和移动。可能在缩放或移动时隐藏弹出窗口?但这是另一个问题。
network.on("click", function(params) {
  // Get the node ID
  var nodeId = params.nodes[0];
  if (nodeId) {
    // Get the node title to show in the popup
    var popup = this.body.nodes[nodeId].options.title;

    // Get the node coordinates
    var { x: nodeX, y: nodeY } = network.canvasToDOM(
      network.getPositions([nodeId])[nodeId]
    );

    // Show the tooltip in a div
    document.getElementById("popup").style.display = "block";
    // Place the div
    document.getElementById("popup").style.position = "absolute";
    document.getElementById("popup").style.top = nodeY + "px";
    document.getElementById("popup").style.left = nodeX + "px";
  }
});