jerosoler / Drawflow

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

How to Import back the Exported file with Drawflow information. #359

Closed Aravinda93 closed 2 years ago

Aravinda93 commented 2 years ago

I am creating the Drawflow Nodes and Connection dynamically and Exporting the data in Drawflow. Is there any way to import back the Exported data? Looking for some suggestions.

I have added the code sample here.

Link: https://codesandbox.io/s/blissful-wozniak-6voii?file=/components/DrawflowSample.vue

jerosoler commented 2 years ago

View your generated json:

{
    "drawflow": {
        "Home": {
            "data": {
                "1": {
                    "id": 1,
                    "name": "Identifiers",
                    "data": {
                        "ID": 1,
                        "nodeId": 1,
                        "eventType": "Identifiers"
                    },
                    "class": "Identifiers",
                    "html": "Identifiers",
                    "typenode": "vue",
                    "inputs": {},
                    "outputs": {
                        "output_1": {
                            "connections": []
                        }
                    },
                    "pos_x": null,
                    "pos_y": 100
                }
            }
        }
    }
}

You just have to register the nodes and use the import method.

editor.start();
editor.registerNode("Identifiers", Identifiers, {}, {});
editor.import(YOUR_JSON);
Aravinda93 commented 2 years ago

@jerosoler Thanks a lot for the response. I am really sorry I was working on another critical requirement so missed this.

You are correct the generated JSON has the structure that you have provided. However, when I try to import the exported drawflow structure then nothing happens and I get the error:

drawflow.min.js:218 Uncaught TypeError: Cannot read properties of undefined (reading 'Home')
    at i.load (drawflow.min.js:218:47)
    at i._import (drawflow.min.js:1295:77)
    at FileReader.reader.onload (index.js?!./node_modules/vue-loader/lib/index.js?!./components/fileName.vue?vue&type=script&lang=js&:404:26)

I am following the process that you have mentioned above not sure why am I getting the error. I have provided the sample code in Codesandbox for your reference: https://codesandbox.io/s/blissful-wozniak-6voii?file=/components/DrawflowSample.vue

If you get a chance can you please have a look and provide some workaround or suggestions? All I want to do is import the same diagram into my Drawflow canvas that I exported:

jerosoler commented 2 years ago

When you read the file you are not parsing to JSON.

Try:

this.$df.import(res.target.result);

To

this.$df.import(JSON.parse(res.target.result));
Aravinda93 commented 2 years ago

@jerosoler Thanks a lot for the response. Now I am able to get the import and the diagram.

I am facing one small issue related to some of the data that I am importing. During the Export I am also appending the data that the user has provided for each of my Node along with the Drawflow diagram info so that during the import I can populate my Arrays with the data that the user provided during the creation the Nodes.

However, some of the data will not be pre-populated during the import of the info although they are populated in the respective Array.

For example:

  1. Create 2 Nodes within the Drawflow canvas.
  2. Populate the Syntax for the first Node as URN and second as WebURI
  3. Now export the data using the Export feature. This file will have the Drawflow information along with the information provided for each Node.
  4. Now import the same file data using the Import feature. During the import, I am populating my Vuex Store with the information of the respective Nodes and then creating the Drawflow diagram.
  5. Now if you observe the Nodes will not have the information that I provided although the data are present within my Vuex Store.

@jerosoler Is there any possibility to populate the data as well along with the Drawflow info? I have provided the code sample in CodeSandbox. Looking for some suggestions on how to assign value to the Nodes which are present within the Vuex Store.

Creation of Nodes and Exporting them to JSON along with Node info: Example-1

Import of all data into Drawflow where only the last Node will have the value WebURI of all other Nodes without the value: CPT2203041125-1920x1096

jerosoler commented 2 years ago

Why don't you save the data directly to drawflow node with the "df-*" attributes?

 "5": {
                        "id": 5,
                        "name": "Identifiers",
                        "data": {
                            "ID": 5,
                            "nodeId": 5,
                            "eventType": "Identifiers"
                        },
                        "class": "Identifiers",
                        "html": "Identifiers",
                        "typenode": "vue",

I see that it saves data to node. But save the id, you already have it. It's a little weird.

Why don't you save like this:

 "data": {
                    "5": {
                        "id": 5,
                        "name": "Identifiers",
                        "data": {
                            "identifierSyntax": "URN",
                        },
                        "class": "Identifiers",
                        "html": "Identifiers",
                        "typenode": "vue",
                        "inputs": {},
                        "outputs": {
                            "output_1": {
                                "connections": []
                            }
                        },
                        "pos_x": null,
                        "pos_y": 27
                    },
                    "6": {
                        "id": 6,
                        "name": "Identifiers",
                        "data": {
                           "identifierSyntax": "WebURI",
                        },
                        "class": "Identifiers",
                        "html": "Identifiers",
                        "typenode": "vue",
                        "inputs": {},
                        "outputs": {
                            "output_1": {
                                "connections": []
                            }
                        },
                        "pos_x": 229,
                        "pos_y": 197
                    }
                }

And here you will receive the data:

const data = this.$df.getNodeFromId(id.slice(5));

I don't see the error in your code.

Aravinda93 commented 2 years ago

@jerosoler Thanks a lot for the response and workaround.

Actually, I am creating different types of Nodes by registering them. Identifiers are one of the types of Node. The information associated with these Nodes is not simple rather complex and they are stored within the different Vuex stores. So if I would like to save them into the data of the respective node during the export then it would require a lot of processes also I have to follow a similar process during the import again.

Currently, I am using the Drawflow for the visual representation within my application and storing all the information within my Vuex store array.

@jerosoler Is there any other alternative approach that I can use to fix the issue and obtain the value within my Drawflow Node during the import? Looking for some suggestions. Thanks in advance.

jerosoler commented 2 years ago

I think you have it half solved, what you have is some error in your code, I would try to find that error.

I try to fork codesandbox but it gives me an error when loading the application.

Aravinda93 commented 2 years ago

@jerosoler Thanks a lot for looking into the code.

I have modified my code within CodeSandbox based on your previous comment for storing the value within data of Drawflow. If you get a chance please have a look or else if you have forked my code already then you can provide me some workaround or suggestion based on that as well.

Based on your previous suggestion I tried to store only the IdentifierSyntax value within my IdentifiersNode as that's the only information that I show within the Drawflow Node and the rest everything I can take care of within my Vuex Store.

After this I will have the Drawflow information something like this:

"2": {
                        "id": 2,
                        "name": "Identifiers",
                        "data": {
                            "ID": 2,
                            "nodeId": 2,
                            "eventType": "Identifiers",
                            "identifierSyntax": "WebURI"
                        },
                        "class": "Identifiers",
                        "html": "Identifiers",
                        "typenode": "vue",
                        "inputs": {},
                        "outputs": {
                            "output_1": {
                                "connections": []
                            }
                        },
                        "pos_x": 453,
                        "pos_y": 188
                    },

Now during the import, only some Identifiers Nodes i.e particularly only with WebURI will be default selected. For URN value it wont be selected but gets selected if the last node is URN. Please refer the code in Codesandbox.

jerosoler commented 2 years ago

I have been checking and it has a problem in the improtation:

 importDesignInfo() {
      const reader = new FileReader();
      this.file = this.$refs.readDrawflowInfo.files[0];
      this.$refs.readDrawflowInfo.value = null;
      reader.onload = (res) => {
        const importData = JSON.parse(res.target.result);

        this.$store.commit(
          "modules/ConfigureIdentifiersInfoStore/populateIdentifiersArray",
          importData.identifiersNodeInfo
        );

        this.$df.start();
        this.$df.registerNode("Identifiers", Identifiers, {}, {});
        this.$df.import(importData.drawflowInfo);
      };

Change to:

 importDesignInfo() {
      const reader = new FileReader();
      this.file = this.$refs.readDrawflowInfo.files[0];
      this.$refs.readDrawflowInfo.value = null;
      reader.onload = (res) => {
        const importData = JSON.parse(res.target.result);

        this.$store.commit(
          "modules/ConfigureIdentifiersInfoStore/populateIdentifiersArray",
          importData.identifiersNodeInfo
        );

        this.$df.import(importData.drawflowInfo);
      };

Remove "Start and Register", since it is already calling it in the mounted method.

Aravinda93 commented 2 years ago

@jerosoler Thanks a lot for the response. It worked.

I also removed the default value that I provided in the IdentifiersNode.vue : identifierSyntax: "",. Thanks a lot for looking into the help and for the really nice library. Have a great weekend ahead :)