如何防止更改链接或元素?

How to prevent changes to links or elements?

我需要限制某些链接和元素的用户交互。 例如,如果用户移动或删除项目,则该项目的最后状态将立即显示并且图形看起来没有改变。

理想情况下,我正在寻找一个简单的 属性 可以在创建元素时添加它以防止发生所有更改,例如isModifiable: false.

因为我找不到,所以我使用了 change 事件和一个不太优雅的链接递归解决方案(添加为下面的答案,现在 编辑 有更好的替代解决方案)。

是否有理想的方法来停止或限制更改的发生?

个人Element/Link限制

我设法通过修改与单元格关联的事件来部分解决这个问题,例如joint.dia.Link:

  1. change 事件添加自定义函数;
  2. 触发更改后,从图中删除新更改的 link;
  3. 使用初始 link 的完整克隆并再次克隆它以将其用作新恢复的 link;
  4. 将相同的功能添加到克隆的 link change 事件中;
  5. 将克隆的 link 添加到图表中。

所以这些将是:

let mylink = new joint.dia.Link({
  source: sourceObj,
  target: targetObj,
  attrs : attrsObj
});
let mylinkClone = mylink.clone();

function restoreLink(link, changeStats) {
  link.remove();
  let rlink = mylinkClone.clone();
  rlink.on('change', restoreLink);
  rlink.addTo(graph);
}

mylink.on('change', restoreLink);

一旦用户单击删除按钮,或尝试将 link 拖出,或其他任何操作,几乎没有视觉变化。

这可能不是一个非常优雅或高性能的解决方案(由于重复克隆),我注意到在 token is sent through the link 期间,用户仍然可以删除它。但是如果你有非常具体的 links/elements 一旦它们被创建你需要限制,它仍然有效。

论文interactive属性限制

这是另一种更好的方法,可以使用 joint.Paper.prototype.options.interactive, as .

来限制对所有元素或纸上 link 的特定操作

限制 Links

所以当论文被实例化时,如果你想永久限制与link的所有交互,你可以这样做:

var paper = new joint.dia.Paper({
  interactive: {
    useLinkTools: false,
    labelMove: false,
    vertexRemove: false,
    vertexAdd: false
    vertexMove: false,
    arrowheadMove: false,
  },
  gridSize: 10,
  drawGrid: true,
  model: graph,
  defaultLink: new joint.shapes.app.Link,
  // other properties ....
})

限制 Elements

如果您只想限制所有元素的交互,那么:

var paper = new joint.dia.Paper({
  interactive: {
    elementMove: false,
    addLinkFromMagnet: false,
  },
  // other properties ....
})

interactive提供功能(高度定制化)

或者,如果您 interactive 属性 值使用一个函数,您只需 需要从link中区分出元素,然后对它们进行操作。要限制 仅 links 交互,您只需要 return false 当检测到这些交互时:

var paper = new joint.dia.Paper({
  interactive: function (cellView) {
    if(cellView.model instanceof joint.dia.Link) {
      console.log('Link interaction');
      return false;
    }
    else {
      console.log('Element interaction of type:', cellView.model.get('type'));
      return true;
    }
  },
  // other properties ....
})

对于我的具体情况,我首选的限制方法只是通过 识别连接到某些来源的 link 和 returning [=26] =] 对他们来说:

var paper = new joint.dia.Paper({
  interactive: function (cellView) {
    if(cellView.model instanceof joint.dia.Link) {
      console.log('Link interaction');
      var lSource = cellView.model.getSourceElement();
      if(lSource instanceof joint.shapes.app.AwesomeShape){
        // do not allow links connected to these sources to be modified
        console.log(`Links with ${lSource.get('type')} sources cannot be modified!`);
        return false;
      }
      // allow other links to be modified
      return true;
    }
    console.log('Element interaction of type:', cellView.model.get('type'));
    return true;
  },
  // other properties ....
})

您应该阻止用户在文件中执行操作,而不是阻止程序员对图形进行更改。

请参阅 interactive option dia.Paper

// add the specific attribute to your desired shape
link.set('isModifiable', true);

// use the `interactive` option within your paper
new joint.dia.Paper({
  interactive: function(cellView) {
    return cellView.model.get('isModifiable');   
  }
});

请注意,通过这种方式您仍然可以通过编程方式更改 link。

// this will trigger `change` event, but it won't be reverted
link.attr('.connection/stroke', 'red');