当前位置: 首页 > 知识库问答 >
问题:

jsPlumb-每侧的动态endpoint锚

符佐
2023-03-14

我试图找出一种方法,如何将endpoint锚动态添加到jsPlumb容器中。

我希望源endpoint位于左侧,目标endpoint仅位于右侧。

问题是,我无法找到任何方法来做到这一点,而不是像我现在这样求助于一些黑客。

jsPlumb支持连续锚,但单个锚的位置将根据连接器之间的方向和连续锚的数量重新计算。这意味着源endpoint和目标endpoint可以共享容器的同一侧,这是我希望避免的。

这是我想出的一个jsFiddler代码

以下是我自己用来破解和重新计算锚点位置(单击Add按钮时)的代码的一部分,其中有一些错误的结果:(

   function fixEndpoints(endpoints) {

            //there are 2 types - input and output

            var inputAr = $.grep(endpoints, function (elementOfArray, indexInArray) {
                return elementOfArray.isSource; //input
            });

            var outputAr = $.grep(endpoints, function (elementOfArray, indexInArray) {
                return elementOfArray.isTarget; //output
            });

            calculateEndpoint(inputAr, true);
            calculateEndpoint(outputAr, false);
        }

        function calculateEndpoint(endpointArray, isInput) {

            //multiplyer
            var mult = 1 / endpointArray.length;

            for (var i = 0; i < endpointArray.length; i++) {

                if (isInput) {
                    endpointArray[i].anchor.x = 1;
                    endpointArray[i].anchor.y = mult * i;//, 1, 0] };
                } 
                else {
                    endpointArray[i].anchor.x = 0;
                    endpointArray[i].anchor.y = mult * i;//, -1, 0] };
                }
            }
        }



        //Add additional anchor
        $(".button_add").live("click", function () {

            var parentnode = $(this)[0].parentNode.parentNode;

            jsPlumb.addEndpoint(
                parentnode,
                anEndpointSource
            );

            jsPlumb.addEndpoint(
                parentnode,
                anEndpointDestination
            );

            //get list of current endpoints
            var endpoints = jsPlumb.getEndpoints(parentnode);

            //fix endpoints
            fixEndpoints(endpoints);

            jsPlumb.recalculateOffsets();
            jsPlumb.repaint(parentnode);
        });

如上图所示,左侧仅有源endpoint(Dot),右侧(Box)仅有目标endpoint,添加新endpoint后,将根据一侧的锚点数量重新计算锚点。

这工作,但仍然有缺陷:位置更新只有一次我移动容器和容器之间的连接是不正确的,以及。

我想要的是一种it工作并正确连接项目的方法(最好使用正确的jsPlumb代码而不诉诸黑客)

共有3个答案

翟高明
2023-03-14

感谢您提供的解决方案,当锚定侧被预定义时,它可以很好地工作,就像这里的源始终位于左侧,目标始终位于右侧。

但如果它们是动态的,我们需要自己实施侧选择吗?

作为一种解决方法,我所做的是在默认配置中设置更多可能的锚点位置。还有更好的主意吗?

谢谢

杜思远
2023-03-14

您可以通过添加双击删除状态

                     newState.dblclick(function(e) {
                        alert("This will delete the state and its connections");
                        instance.detachAllConnections($(this));
                      $(this).remove();
                      e.stopPropagation();
                    });

函数到您的jsPlumb.ready函数。您可以通过添加

var windows = jsPlumb.getSelector(".statemachine-demo .state");
            windows.dblclick(function(e) {
            alert("This will delete the state and its connections");
            instance.detachAllConnections($(this));
          $(this).remove();
          e.stopPropagation();
        });

在这里statemachine-demo是div的id在您的接触器和状态是类的状态div。

戚锦
2023-03-14

我终于想出了办法。这比我想象的要容易。

代码基本上是相同的,只是有一些改动,这里是更新的fiddler示例

<!DOCTYPE html>
<html>
<head>
<title>JS plumb test</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
    <script type="text/javascript" src="./include/jquery.jsPlumb-1.3.16-all-min.js"></script>

<style>
    .window { 
        background-color: #EEEEEF;
        border: 1px solid #346789;
        border-radius: 0.5em;
        box-shadow: 2px 2px 5px #AAAAAA;
        color: black;
        height: 5em;
        position: absolute;
        width: 5em;
    }

    .window:hover { 
        box-shadow: 2px 2px 19px #AAAAAA;
        cursor: pointer;
    }


    .button_add, .button_add_window, .button_remove, .button {
        background-color: deepskyblue;
        text-align: center;
        border: 1px solid;
    }

    .button_container {
        margin: 5px;
        background-color: #aaaaaa
    }
</style>

<script>

    jsPlumb.ready(function () {


        //FIX DOM:
        $(("#container1"))[0].innerHTML = $(("#container0"))[0].innerHTML;

        //all windows are draggable
        jsPlumb.draggable($(".window"));


        var anEndpointSource = {
            endpoint: "Rectangle",
            isSource: true,
            isTarget: false,
            maxConnections: 1,

            anchor: [1, 0, 1, 0]
        };

        var anEndpointDestination = {
            endpoint: "Dot",
            isSource: false,
            isTarget: true,
            maxConnections: 1,

            anchor: [0, 1, -1, 0]
        };


        //Fixes endpoints for specified target
        function fixEndpoints(parentnode) {

            //get list of current endpoints
            var endpoints = jsPlumb.getEndpoints(parentnode);

            //there are 2 types - input and output

            var inputAr = $.grep(endpoints, function (elementOfArray, indexInArray) {
                return elementOfArray.isSource; //input
            });

            var outputAr = $.grep(endpoints, function (elementOfArray, indexInArray) {
                return elementOfArray.isTarget; //output
            });

            calculateEndpoint(inputAr, true);
            calculateEndpoint(outputAr, false);

            jsPlumb.repaintEverything();
        }

        //recalculate endpoint anchor position manually
        function calculateEndpoint(endpointArray, isInput) {

            //multiplyer
            var mult = 1 / (endpointArray.length+1);

            for (var i = 0; i < endpointArray.length; i++) {

                if (isInput) {

                    //position
                    endpointArray[i].anchor.x = 1;
                    endpointArray[i].anchor.y = mult * (i + 1);
                } 
                else {

                    //position
                    endpointArray[i].anchor.x = 0;
                    endpointArray[i].anchor.y = mult * (i + 1);
                }
            }
        }



        //Add additional anchor
        $(".button_add").live("click", function () {

            var parentnode = $(this)[0].parentNode.parentNode;

            jsPlumb.addEndpoint(
                parentnode,
                anEndpointSource
            );

            jsPlumb.addEndpoint(
                parentnode,
                anEndpointDestination
            );

            fixEndpoints(parentnode);
        });

        //Remove anchor 
        $(".button_remove").live("click", function () {

            var parentnode = $(this)[0].parentNode.parentNode;

            //get list of current endpoints
            var endpoints = jsPlumb.getEndpoints(parentnode);

            //remove 2 last one

            if (endpoints.length > 1) {
                jsPlumb.deleteEndpoint(endpoints[endpoints.length - 2]);
            }

            if (endpoints.length > 0) {
                jsPlumb.deleteEndpoint(endpoints[endpoints.length - 1]);
            }

            fixEndpoints(parentnode);
        });


        //adds new window
        $(".button_add_window").click(function () {

            var id = "dynamic_" + $(".window").length;

            //create new window and add it to the body
            $('<div class="window" id="' + id + '" >').appendTo('body').html($(("#container0"))[0].innerHTML);

            //set jsplumb properties
            jsPlumb.draggable($('#' + id));
        });
    });
</script>

</head>
<body >

    <!-- Adds new windows to the page -->
    <div class="window" style="left: 600px" id="details">
        <p style="text-align: center">Window</p>
        <div class="button_container">
            <div class="button_add_window">Add</div>
        </div>
    </div>

    <!-- Primary window - used as html templated for descendants -->
    <div class="window" style="left: 20px" id="container0">
        <div class="button_container">
            <div class="button_add">Add</div>
            <div class="button_remove">Remove</div>
        </div>
    </div>

    <div class="window" style="left: 200px" id="container1">
    </div>


</body>
</html>

我所做的更改:

>

  • 现在我在添加endpoint锚偏移时指定它,我只计算锚位置,所以偏移永远不会改变,它从一开始就总是正确的:

    var anEndpointSource = {
        endpoint: "Rectangle",
        isSource: true,
        isTarget: false,
        maxConnections: 1,
    
        anchor: [1, 0, 1, 0]
    };
    

    添加endpoint后,我重新计算锚点位置并调用(这将重新绘制连接):

    jsPlumb.repaiverything()

    以下是最终结果:

  •  类似资料:
    • 我试图创建动态endpoint,作为我的连接和运行问题的覆盖。我试图模拟这个人在SO上有什么: jsPlumb连接自定义覆盖-endpoint未移动 然而,当我达到这一点时,无论我尝试做什么: 我无法识别连接。我尝试将此逻辑放入绑定连接中,但在尝试建立连接覆盖时,这也不起作用。在这方面提供任何帮助都会非常有帮助。

    • 我正在使用jsPlumb创建一个包含两列的匹配小部件。 jsPlumb实例创建为: 我创建了源和目标,如下所示: 连接过程正常工作。但是在建立一个连接后的问题如果我删除连接,连接endpoint仍然可见。 我尝试添加配置“\u deleteondetch”,还尝试删除connectiondeach上的endpoint。在这两种情况下,endpoint都被删除,但在我尝试连接相同的元素时,它会出错。

    • 我不希望源endpoint与相同元素的目标endpoint连接,因此在连接事件中,我分离当前连接,如 但这会使我的源endpoint与div分离,在我拖动div后,endpoint挂在同一位置,如下图所示(点是我的源endpoint和目标endpoint中的矩形)。 在创建连接之前 创建连接后 在这种情况下,我不希望Join_1的源endpoint与Join_1的目标endpoint连接。 我使用

    • 我已经被这件事困扰了几天,希望你能帮助我解决这个问题。我创建了一个类似流程图的应用程序来绘制不同类型的铅锤项目,并将不同的endpoint连接到这些项目上。将其创建为元素后,将根据铅锤项目的类型动态添加endpoint。是这样的吗。 这就是我创建铅锤项目的方式。 然后根据endpoint的类型添加endpoint。 这就是它看起来的样子 屏幕一 我设法从方法“GetConnections”中获取数

    • 在中,我正在填充和。现在,我需要定义一个新的路由,它使用来自上传队列的消息,并复制一个本地文件夹(基于在上一个路由中生成的Id),并将其上传到目标文件夹,该文件夹是一个ftp服务器(这也在上一个路由中填充) 那么,如何设计一条新的路线,其中从和到终点都是动态的,如下所示?