繁体   English   中英

如何防止jointjs / rappid中的循环

[英]How to prevent loops in jointjs / rappid

我正在构建一个使用jointjs / rappid的应用程序,并且我希望能够避免在多个单元之间发生循环。

Jointjs已经有一些示例,说明如何在单个单元中避免这种情况(将“ out”端口连接到同一单元的“ in”端口),但是对于如何检测和防止链中进一步出现环路一无所知。

为了帮助理解,假设本文中的每个单元格都是要完成的步骤。 每个步骤只能运行一次。 如果最后一步有一个“ out”端口连接到第一个单元格的“ in”端口,它将永远循环。 这就是我要避免的。

任何帮助是极大的赞赏。

实际上,对于所有希望实现同一目标的人,我确实找到了一种非常简单的方法。 只需包括graphlib依赖关系并使用以下命令:

        paper.on("link:connect", function(linkView) {
            if(graphlib.alg.findCycles(graph.toGraphLib()).length > 0) {
                linkView.model.remove();
                // show some error message here
            }
        });

这行:

graphlib.alg.findCycles(graph.toGraphLib())

返回一个包含任何循环的数组,因此,通过检查长度,我们可以确定纸张是否包含任何循环,如果存在,则删除用户尝试创建的链接。

注意:这不是完全完全的证明,因为如果纸张已经包含一个循环(在用户添加链接之前),则仅删除用户正在创建的链接不会删除存在的任何循环。 对我而言,这很好,因为我的所有论文都会从头开始创建,只要始终保持这种逻辑,就不会创建循环。

通过graphlib解决

基于Adam的graphlib解决方案 ,graphlib文档建议使用isAcyclic函数 ,而不是使用findCycles来测试循环,该函数

返回true如果图没有周期,并返回false ,如果它。 该算法在检测到第一个周期后立即返回

因此,这种情况:

if(graphlib.alg.findCycles(graph.toGraphLib()).length > 0)

可以缩短为:

if(!graphlib.alg.isAcyclic(graph))

JointJS函数解决方案

查找新连接元素的祖先后继数组,并将它们相交

// invoke inside an event which tests if a specific `connectedElement` is part of a loop

function isElementPartOfLoop (graph, connectedElement) {
  var elemSuccessors = graph.getSuccessors(connectedElement, {deep: true});

  var elemAncestors = connectedElement.getAncestors();
  //       *** OR *** graph.getPredecessors(connectedElement, {deep: true});

  var commonElements = _.intersection(elemSuccessors, elemAncestors);

  // if an element is repeated (non-empty intersection), then it's part of a loop
  return !_.isEmpty(commonElements);
}

我还没有测试过,但是您要完成的测试背后的理论应该是相似的。 该解决方案的效率不如直接使用graphlib函数。

预防

防止链接添加到图形的一种方法是在事件中进行处理:

graph.on('add', _.bind(addCellOps, graph));

function addCellOps (cell, collection, opt) {
  if (cell.isLink()){
    // test link's target element: if it is part of a loop, remove the link
    var linkTarget = cell.getTargetElement();
    // `this` is the graph
    if(target && isElementPartOfLoop(this, linkTarget)){
      cell.remove();
    }
  }
  // other operations ....
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM