jerosoler / Drawflow

Simple flow library 🖥️🖱️
https://jerosoler.github.io/Drawflow/
MIT License
4.65k stars 722 forks source link

Output connection lines do not align when importing the saved data #408

Closed gpack closed 2 years ago

gpack commented 2 years ago

Hi,

As soon as I import the data back onto the canvas, the connection lines (specifically the output) are not aligning up. When I start from fresh and draw nodes/lines, they connect fine. It's ONLY when I import the data.

Also, as soon as I move a node, the lines automatically fix themselves. I'm using your (Fix vertical lines script - editor.createCurvature), because my input/output is top/bottom. Does this refresh or does it need to be called again?

I've looked at the solutions from other posts and have tried implementing those fixes, but still not having any luck aligning the lines again to their respective outputs (when importing).

I've tested both on Chrome and Firefox and Smartphone too, getting the same exact issue across all devices. I load the editor by default in zoom level 0.8. I've even reset the zoom levels back to 1 and tried saving it that way, but still no luck.

I've had a look at issue #218. But I'm not zooming out in Chrome (it's at 100%).

This is how I initiate editor: editor.reroute_fix_curvature = true; editor.start(); editor.zoom = 0.6; editor.zoom_max = 0.8; editor.zoom_min = 0.2; editor.zoom_refresh(); editor.import(dataToImport);

I've also updated the CSS with: .drawflow .connection { position: absolute; pointer-events: none; aspect-ratio: 1 / 1; width: 1000000px; height: 1000000px;
}

But none of them have helped. I've attached screenshot for you to see. Any help would be much appreciated.

conn-lines-not-aligned

thanks.

jerosoler commented 2 years ago

This usually happens because the css has not yet been loaded and drawflow has already been launched.

Do you have the css before the javascript?

If you can't try this other: settimeout

gpack commented 2 years ago

Yes, I have all the CSS first loading at the top in between the head tag, and then at the very bottom I have the "drawflow.min.js" script and the rest of the Javascript to initiate and load it.

How would I use the "settimeout" exactly, do I import the "drawflow.min.js" script after a few seconds OR do I put the "editor.start()" in a settimeout function?

thanks.

jerosoler commented 2 years ago

On editor.start(); or editor.import(); The start and import methods need all the css to be loaded, to correctly get the position of the nodes.

gpack commented 2 years ago

Yeh I gave that a shot and it didn't work. I don't think it's to do with the CSS being delayed. I set the timeout to 5, 10 seconds, but when drawflow finally loaded/imported, the lines were still out of place.

What I did was, using the editor.on('import') function (which executes once import is done I'm assuming), I loop through all the nodes and update the connections using "updateConnectionNodes()". But I even had to put this in settimeout function of half a second. But the lines end up being fixed.

Does that give you any clues to what the underlying issue could be?

Hopefully my method won't slow down too much when there are over 50 nodes? What are your thoughts, is it an ideal temporary solution?

jerosoler commented 2 years ago

Try this, if this works correctly.

editor.import(editor.export());

Try adding the drawflow style to a css file and not to the component itself.

Are you using any vue or react type library?

gpack commented 2 years ago

I replaced "editor.import(dataFromDB)" with "editor.import(editor.export());", but no luck. It didn't load anything.

I'm using straight native Javascript and Jquery.

I have all the CSS in a file, and the CSS file is included at the top of the page in between the head tag. So like a traditional website, it loads all the required CSS at the top, and then javascript files and JS scripts are at the bottom.

jerosoler commented 2 years ago

Does this example work for you?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.css"/>
  <script src="https://cdn.jsdelivr.net/gh/jerosoler/Drawflow/dist/drawflow.min.js"></script>
</head>
<body>
<div id="drawflow"></div>
  <style>
    #drawflow { 
      position: relative;
      text-align:initial;
      width: 100%;
      height: 800px;
      border: 1px solid red;
    }
</style>
<script>
    var id = document.getElementById("drawflow");
    const editor = new Drawflow(id);

    editor.start();

    editor.addNode('aaa', 0, 1, 100, 300, 'aaa', {}, '<input type="text">' );
    editor.addNode('bbb', 1, 0, 400, 400, 'bbb', {}, 'bbb' );
    editor.addNode('ccc', 1, 0, 500, 500, 'ccc', {}, 'ccc' );
    editor.addConnection(1, 2, 'output_1', 'input_1');

  //  editor.import(JSON.parse('{"drawflow":{"Home":{"data":{"1":{"id":1,"name":"aaa","data":{},"class":"aaa","html":"<input type=\\"text\\">","typenode":false,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"2","output":"input_1"}]}},"pos_x":100,"pos_y":300},"2":{"id":2,"name":"bbb","data":{},"class":"bbb","html":"bbb","typenode":false,"inputs":{"input_1":{"connections":[{"node":"1","input":"output_1"}]}},"outputs":{},"pos_x":400,"pos_y":400},"3":{"id":3,"name":"ccc","data":{},"class":"ccc","html":"ccc","typenode":false,"inputs":{"input_1":{"connections":[]}},"outputs":{},"pos_x":500,"pos_y":500}}}}}'));
</script>
</body>
</html>
gpack commented 2 years ago

Yes, that above example works and the lines match up.

So could it be in the way I'm saving the export? But then again, if it was broken, the lines wouldn't show or match at all. It seems like they're just a little off on my version.

Could it be to do with performance? I've got too much CSS loading? I don't have that much, it's a standard website.

jerosoler commented 2 years ago

Can you provide the html? Or a codepen to see the problem?

gpack commented 2 years ago

I went ahead and created a basic HTML test version (stripped down to bare minimal), and when I tested it with the same import data, the lines worked fine. So it must be something on my other page.

I went through the code and realised I have a script that automatically runs through each node to update their heights to match their content. And that's what was causing the lines not to match up. Because drawflow was drawing the lines based on initial height of the nodes (on load), but then the other resize() script would execute and change the height (without updating the connections).

I know the issue and how to fix it now. Thanks for your thoughts and fixes on this issue Jero, much apreciated because it helped me figure out the issue.

alextenev commented 1 year ago

@jerosoler , Hey man, I'm facing a similar issue. In the body of the nodes I have texts of various sizes and they stretch the nodes. I'm using vue. After import the connections are misaligned. If I move a node just slightly it rearranges perfectly.

Is there a way for me to programmatically trigger this redraw?