Individual Element
/Link
restriction
I managed to solve this problem partially by modifying the events associated to the cells, e.g. for joint.dia.Link
:
- Add a custom function to the
change
event;
- Once a change is triggered, remove the newly changed link from the graph;
- Use an intact clone of the initial link and clone it again for using it as the newly restored link;
- Add the same function to the cloned link
change
event;
- Add the cloned link to the graph.
So these would be:
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);
Once the user clicks the delete button, or tries to drag the link out, or anything else, there is literally no visual change.
This may not be a very elegant or high performance solution (due to repeated cloning) and I noticed during the period in which a token is sent through the link, the user is still able to delete it. But if you have very specific links/elements once they are created that you need to restrict, it's still effective.
Paper interactive
property restrictions
This is an alternative better way to restrict specific actions on all elements or links on the paper by using joint.Paper.prototype.options.interactive
, as suggested by Roman in another answer.
Restrict Link
s
So when the paper is instantiated, if you want all the interactions with links to be permanently restricted, you can just do:
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 ....
})
Restrict Element
s
If you want to only restrict all elements' interactions, then:
var paper = new joint.dia.Paper({
interactive: {
elementMove: false,
addLinkFromMagnet: false,
},
// other properties ....
})
Providing a function to interactive
(high customisation)
Or, if you use a function for the interactive
property value, you just
need to distinguish elements from links and then operate on them. For restricting only links interactions you just need to return false
when these are detected:
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 ....
})
My preferred method of restriction for my specific case was simply done by identifying the links connected to certain sources and returning false
for them:
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 ....
})