projectstorm / react-diagrams

a super simple, no-nonsense diagramming library written in react that just works
https://projectstorm.cloud/react-diagrams
MIT License
8.69k stars 1.18k forks source link

Link rendering behind nodes. #614

Open jacobatnari opened 4 years ago

jacobatnari commented 4 years ago

Hi,

react version: 16.8.6 react-diagrams version: 6.0.1-beta.7

Thanks so much for this great library and all of the work you do in maintaining it. I am having a problem with the link layer rendering behind the node. Due to the positioning of the ports within my node widget (i.e. not at the edge of the widget) the link appears discontinuous in the diagram, as seen in image 1. The link attaches as usual to the port widget, as seen in image 2.

image 1 image 2

To solve this problem, and after seeing the discussion on #327, I reversed the order of the NodeLayer and LinkLayer with the following code:

// Setup the diagram engine and model
this.engine = createCustomEngine();
this.model = new DiagramModel();
this.model.layers = this.model.getLayers().reverse();
this.engine.setModel(this.model);

After this change, the links are rendering correctly (i.e. fully visible in the diagram and not obscured by the node) but the free of the link doesn't connect to the port. This can be seen in images 3 and 4.

image 3 image 4

The targetPortChanged event is not being fired, the canLinkToPort function on the PortModel is not being called, and the css hover selector for the port widget is not being activated either. I think this means that when the link is dragged over the port widget, the z-index of the port widget (or the whole node?) prevents any events from firing to allow the link to be connected to the target port.

Do you have an idea of how I could fix this? Desired outcomes are visible nodes, visible links, and the ability to connect them using the normal user experience of clicking and dragging the link between desired ports.

Thank you for your help and time!

onefork commented 4 years ago

probably the same as #461:

I would recommend to extend the DiagramModel and redefine the constructor.

This way, you can invert the addLayer between the Links and the Nodes one.

Thank you, I will try.

Originally posted by @Wing-Lo in https://github.com/projectstorm/react-diagrams/issues/461#issuecomment-561449493

have you come to a solution? @Wing-Lo

onefork commented 4 years ago

I just checked the source code. The reason is some svg elements in the LinkLayer listen to mouse events (for example DefaultLinkPointWidget). When LinkLayer is displayed over the NodeLayer, these elements will be the event target instead of the element on NodeLayer.

A possible fix could be to modify DiagramEngine.getMouseElement() and add some logic to find the right target, like:

for (const element of document.elementsFromPoint(event.clientX, event.clientY)) {
  // check if potential target
  // we only need to find the topmost dom element from each layer
}
// return the correct target model

BTW an alternative way to change the display order is with CSS:

.diagram-container > svg {
    z-index: 1;
}
alexandernst commented 3 years ago

This is how I did it: https://github.com/Develatio/react-diagrams/commit/c9e0fd1658b1ae08e99d70440a29764827409450