【问题标题】:(Vis.js network) Incorrect node coordinates with getPositions?(Vis.js 网络)getPositions 的节点坐标不正确?
【发布时间】:2019-10-05 18:13:06
【问题描述】:

在我的 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";
    });

【问题讨论】:

  • 为了更快的响应:创建一个 jsfiddle 或类似的东西,这样用户就可以用自己的眼睛快速看到问题。
  • 另外,如果弹出窗口总是与顶部对齐过多并且左侧不能通过在代码中添加一些像素来解决这个问题?喜欢:style.top = 10 + nodeY + 'px'
  • 我刚刚在我的帖子中放了一个链接来查看结果。我无法在我的代码中添加像素,因为每个弹出窗口的偏移量都不是完全相同的。我认为它们都有节点的形状,但看起来它们不在同一个缩放级别上,就像我的节点在缩放 1 并且 getPositions 返回的节点的位置在缩放 1.5(我不t 实际上在任何地方都有这些值,这只是它的外观示例)。
  • 我现在看到了。请再次从您的问题中删除链接。以防止将来出现断开的链接。对于这样的图表,可以包含屏幕截图。

标签: javascript popup vis.js vis.js-network


【解决方案1】:

我在vis support section of github 上得到了一些帮助。 原来诀窍是使用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";
  }
});

当网络保持不变时它可以工作,但在我的情况下,我想适应网络并放大点击的节点,所以弹出窗口不会跟随,但由于这是一个单独的问题,我将发布另一个问题。

【讨论】:

    【解决方案2】:

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

    查看文档 [https://visjs.github.io/vis-network/docs/network/#Events],点击事件参数包含:

    {
        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}
        }
    }
    

    尝试使用 params.pointer.DOM 或 params.pointer.canvas 位置 X 和 Y 来定位您的弹出窗口。这应该是光标的位置。这将与节点的位置相同,因为您单击了它。

    所以尝试一下:

        document.getElementById('popup').style.top = params.pointer.DOM.y +'px';
        document.getElementById('popup').style.left = params.pointer.DOM.x +'px';
    

    -- 未测试

    【讨论】:

    • 听起来确实像一个错误,因为我也在提供的基本示例中对此进行了测试,结果是相同的。我已经测试了您的解决方案,这是我的计划 B... 这真的不理想,因为当我单击一个节点时,我还将使用 fit() 函数来缩放一组节点(我只是在演示中禁用了它我在我的帖子中展示了)。因此,如果我让弹出窗口出现在指针坐标处,它会出现在我单击的位置,但是由于视图随后会缩放画布上的其他位置,因此弹出窗口不再位于正确的位置。
    • 是的,您必须考虑如何处理缩放和移动。也许隐藏缩放或移动的弹出窗口?但这是一个不同的问题。
    【解决方案3】:

    使用点击事件并在画布上绘制一个 div。

    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;
    
            //use JQUERY to see where the canvas is on the page.
            var canvasPosition = $('.vis-network').position();
    
            //the params give x & y relative to the edge of the canvas, not to the 
            //whole document.
            var clickX = params.pointer.DOM.x + canvasPosition.top;
            var clickY = params.pointer.DOM.y + canvasPosition.left;
    
            // 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 = clickY + "px";
            document.getElementById("popup").style.left = clickX + "px";
        }
    });
    

    fixed position for tooltip/popup example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多