jerosoler / Drawflow

Simple flow library πŸ–₯οΈπŸ–±οΈ
https://jerosoler.github.io/Drawflow/
MIT License
4.65k stars 722 forks source link

Import saved data with remote nodes #380

Closed John-jk closed 2 years ago

John-jk commented 2 years ago

Hello. I can not restore the diagram after deleting multiple nodes and save data. When I do editor.export() I get the following object:

image

In which 1 and 2 nodes have been removed. When trying to restore this object via editor.import () I get the following error:

drawflow.min.js Uncaught TypeError: Cannot read properties of null (reading 'id')

which occurs when trying to process remote nodes. Remove this error managed to add a NULL check to the load() method.

Maybe there are other solutions that I missed?

jerosoler commented 2 years ago

The default export method start nodes in one.

image

When a node is deleted, the entire entry is removed. image

How are you deleting the nodes?

Are you generating the json?

John-jk commented 2 years ago

I try delete with condition:

editor.removeNodeId = function(id) {
        if (id == 'node-0') {
            alert('do not delete');
            return false;
        }
        let remove = confirm('are you sure?');
        if (remove) {
            this.removeConnectionNodeId(id);
            let moduleName = this.getModuleFromNodeId(id.slice(5));
            if (this.module === moduleName) {
                this.container.querySelector(`#${id}`).remove();
            }
            delete this.drawflow.drawflow[moduleName].data[id.slice(5)];
            this.dispatch('nodeRemoved', id.slice(5));
        }
   }
  1. right click and delete node
  2. editor.export() and output to the console image
  3. Yes, I generating json and save to DB, then I try to restore
jerosoler commented 2 years ago

Have you modified anything else from the library?

I'm trying your method but it keeps coming out correctly. image

Are you using the latest version?

jerosoler commented 2 years ago

Try yourself:

<!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>

<style>
  #drawflow { 
    position: relative;
    text-align:initial;
    width: 100%;
    height: 800px;
    border: 1px solid red;
  }

  .drawflow .connection {
   aspect-ratio: 1 / 1;
  }

</style>
</head>
<body>
<div id="drawflow"></div>

<script>
    var id = document.getElementById("drawflow");
    const editor = new Drawflow(id);

    editor.reroute = true;
    editor.reroute_fix_curvature = true;

    editor.removeNodeId = function(id) {
        if (id == 'node-0') {
            alert('do not delete');
            return false;
        }
        let remove = confirm('are you sure?');
        if (remove) {
            this.removeConnectionNodeId(id);
            let moduleName = this.getModuleFromNodeId(id.slice(5));
            if (this.module === moduleName) {
                this.container.querySelector(`#${id}`).remove();
            }
            delete this.drawflow.drawflow[moduleName].data[id.slice(5)];
            this.dispatch('nodeRemoved', id.slice(5));
        }
   }

    editor.start();

  editor.addNode("start", 1,0, 300, 300, 'test', {}, `start`);
    editor.addNode("end", 1,0, 300, 300, 'test', {}, `end`);
    editor.addNode("three", 1,0, 300, 300, 'test', {}, `three`);

    console.log(editor.export());

</script>

</body>
</html>
John-jk commented 2 years ago

Yes, I use latest version. You sample works fine but can you try this code with import:

<!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>

<style>
  #drawflow { 
    position: relative;
    text-align:initial;
    width: 100%;
    height: 800px;
    border: 1px solid red;
  }

  .drawflow .connection {
   aspect-ratio: 1 / 1;
  }

</style>
</head>
<body>
<div id="drawflow"></div>

<script>
    var id = document.getElementById("drawflow");
    const editor = new Drawflow(id);

    editor.reroute = true;
    editor.reroute_fix_curvature = true;

    editor.removeNodeId = function(id) {
        if (id == 'node-0') {
            alert('do not delete');
            return false;
        }
        let remove = confirm('are you sure?');
        if (remove) {
            this.removeConnectionNodeId(id);
            let moduleName = this.getModuleFromNodeId(id.slice(5));
            if (this.module === moduleName) {
                this.container.querySelector(`#${id}`).remove();
            }
            delete this.drawflow.drawflow[moduleName].data[id.slice(5)];
            this.dispatch('nodeRemoved', id.slice(5));
        }
   }

    editor.start();

let json = {"drawflow":{"Home":{"data":[{"id":0,"name":"start","data":{"action":"start"},"class":"start","html":"<div>\n                                <div class=\"title-box\">\n                                    <i class=\"far fa-file-alt\"></i>\n                                    <span> Начало скрипта</span>\n                                </div>\n                                <div class=\"box\">\n                                    <p>Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ</p>\n                                    <input type=\"text\" df-title>\n                                    <p>ОписаниС</p>\n                                    <textarea id=\"script-textarea-0\" data-type=\"start\" df-text></textarea>\n                                </div>\n                            </div>","typenode":false,"inputs":{},"outputs":{"output_1":{"connections":[{"node":"2","output":"input_1"},{"node":"1","output":"input_1"}]}},"pos_x":93,"pos_y":98},{"id":1,"name":"button","data":{},"class":"button","html":"\n                <div>\n                    <div class=\"title-box\">\n                        <i class=\"fas fa-exchange-alt\"></i><span> Кнопка</span>\n                    </div>\n                    <div class=\"box\">\n                        <p>Кнопка</p>\n                        <textarea df-text></textarea>\n                    </div>\n                </div>","typenode":false,"inputs":{"input_1":{"connections":[{"node":"0","input":"output_1"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":534,"pos_y":289},{"id":2,"name":"button","data":{},"class":"button","html":"\n                <div>\n                    <div class=\"title-box\">\n                        <i class=\"fas fa-exchange-alt\"></i><span> Кнопка</span>\n                    </div>\n                    <div class=\"box\">\n                        <p>Кнопка</p>\n                        <textarea df-text></textarea>\n                    </div>\n                </div>","typenode":false,"inputs":{"input_1":{"connections":[{"node":"0","input":"output_1"}]}},"outputs":{"output_1":{"connections":[]}},"pos_x":509,"pos_y":29}]}}}
 editor.import(json);

 console.log(editor.export());
</script>

</body>
</html>
jerosoler commented 2 years ago

The json is malformed. The "data" is not an array, it is an object.

Your data:

{
    "drawflow": {
        "Home": {
            "data": [
                {
                    "id": 0,
                    "name": "start",
                    "data": {
                        "action": "start"
                    },
                    "class": "start",
...

The default data:

{
    "drawflow": {
        "Home": {
            "data": {
               "0": {
                    "id": 0,
                    "name": "start",
                    "data": {
                        "action": "start"
                    },
                    "class": "start",
                    "html": "<div>\n                                <div class=\"title-box\">\n                                    <i class=\"far fa-file-alt\"></i>\n                                    <span> Начало скрипта</span>\n                                </div>\n                                <div class=\"box\">\n                                    <p>Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ</p>\n                                    <input type=\"text\" df-title>\n                                    <p>ОписаниС</p>\n                                    <textarea id=\"script-textarea-0\" data-type=\"start\" df-text></textarea>\n                                </div>\n                            </div>",
                    "typenode": false,
                    "inputs": {},
                    "outputs": {
                        "output_1": {
                            "connections": [
                                {
                                    "node": "2",
                                    "output": "input_1"
                                },
                                {
                                    "node": "1",
                                    "output": "input_1"
                                }
                            ]
                        }
                    },
                    "pos_x": 93,
                    "pos_y": 98
                },
               "1": {
                    "id": 1,
                    "name": "button",
                    "data": {},
                    "class": "button",
                    "html": "\n                <div>\n                    <div class=\"title-box\">\n                        <i class=\"fas fa-exchange-alt\"></i><span> Кнопка</span>\n                    </div>\n                    <div class=\"box\">\n                        <p>Кнопка</p>\n                        <textarea df-text></textarea>\n                    </div>\n                </div>",
                    "typenode": false,
                    "inputs": {
                        "input_1": {
                            "connections": [
                                {
                                    "node": "0",
                                    "input": "output_1"
                                }
                            ]
                        }
                    },
                    "outputs": {
                        "output_1": {
                            "connections": []
                        }
                    },
                    "pos_x": 534,
                    "pos_y": 289
                },
               "2": {
                    "id": 2,
                    "name": "button",
                    "data": {},
                    "class": "button",
                    "html": "\n                <div>\n                    <div class=\"title-box\">\n                        <i class=\"fas fa-exchange-alt\"></i><span> Кнопка</span>\n                    </div>\n                    <div class=\"box\">\n                        <p>Кнопка</p>\n                        <textarea df-text></textarea>\n                    </div>\n                </div>",
                    "typenode": false,
                    "inputs": {
                        "input_1": {
                            "connections": [
                                {
                                    "node": "0",
                                    "input": "output_1"
                                }
                            ]
                        }
                    },
                    "outputs": {
                        "output_1": {
                            "connections": []
                        }
                    },
                    "pos_x": 509,
                    "pos_y": 29
                }
            }
        }
    }
}
John-jk commented 2 years ago

My start node was incorrect πŸ€¦β€β™‚οΈ. Now all nodes remove correctly. Thank you for your support.