We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Save diagram - get nodes and connectors list in controller

Hi,
I studied your demos here: https://help.syncfusion.com/aspnetmvc/diagram/data-binding?cs-save-lang=1&cs-lang=js#how-to-perform-editing-at-runtime
I need to pass diagram changes to my controller and access list of nodes and connectors (same strucure as nodes and connectors passed for display to view via ViewData["diagramModel"] = model;). It would be nice if this happens on the fly - I add new node or connector and some controller method gets invoked, I save data into database immediately as user edits his diagram. I do not know how to achieve this. Can you provide sample aplication for this?

Thank you,
Tom Frajer

10 Replies

SG Shyam G Syncfusion Team September 29, 2016 09:27 AM UTC

Hi Tom, 

We have created a simple CRUD workflow sample to achieve your requirement. 


 
Regards, 
Shyam G 



TF Tom Frajer September 29, 2016 11:57 AM UTC

This is very helpful as Im now able to save my diagram on press of the button. Is it possible to save diagram everytime I change something in diagram? I would like to remove all buttons and save everything on the fly immediately. Thank you.
 


TF Tom Frajer September 29, 2016 04:53 PM UTC

What the is purporse of DiagramBuilderData.designer.cs in your sampse? Should I transfer this to my project? Why it is not part of Syncfusion framework?


SG Shyam G Syncfusion Team September 30, 2016 09:32 AM UTC

Hi Tom, 
 
Query 
Response 
This is very helpful as Im now able to save my diagram on press of the button. Is it possible to save diagram everytime I change something in diagram? I would like to remove all buttons and save everything on the fly immediately. Thank you. 
Yes, you can use the diagram client Side events to perform add/edit/delete operation in the database.  
 
We have used nodeCollectionChange event to perform add/delete operations in the database. 
 
Code example: 
//define nodecollectionchange event 
            model.NodeCollectionChange = "nodecollectionchange"; 
function nodecollectionchange(args) {          
        var diagram = $("#Diagram").ejDiagram("instance"); 
        if (args.state === "changed") { 
            if (args.changeType === "insert") { 
                diagram.insertData(); 
            } 
            if (args.changeType === "remove") { 
                diagram.removeData(); 
            } 
        } 
    } 
 
For an edit operation, we have used sizeChange and drag event. 
 
Code example: 
            //define sizechange event 
            model.SizeChange = "sizechange"; 
            //define drag event 
            model.Drag = "drag"; 
function sizechange(args) { 
        var diagram = $("#Diagram").ejDiagram("instance"); 
        if (args.resizeState === "completed") { 
            diagram.updateData(); 
        } 
    } 
 
    function drag(args) { 
        var diagram = $("#Diagram").ejDiagram("instance"); 
        if (args.dragState === "completed") { 
            diagram.updateData(); 
        } 
    } 
 
 
 
Please refer to the sample below. 
 
What the is purpose of DiagramBuilderData.designer.cs in your sample? Should I transfer this to my project? Why it is not part of Syncfusion framework? 
 
You need to transfer entire dbml file(DiagramBuilderData.dbml, DiagramBuilderData.dbml.layout, DiagramBuilderData.designer.cs) to your project. We use linq to sql approach. The DBML file is mapping that defines your classes based on your database schema. 
 
Linq to Sql uses a database-first approach where you have the database and model your classes after the DB schema. By dragging & dropping the table onto there, you'll be automating the creation of the classes(for example: DiagramBuilderData.designer.cs is automatically generated which contains the classes and properties). 
 
 
Regards, 
Shyam G 



TF Tom Frajer September 30, 2016 06:25 PM UTC

Is it possible to access upadated DiagramProperties in controller upon submitting changes? I would like to hande saving data into database my own way (using Dapper and my service and data layer). Im preparing DiagramProperties for a view, filling it with all necessary data (FlowShapes, Connectors) and I would like to return changed diagram in same format as Im constructing it on first load. Is this possible? It will be much cleaner and easier way for me. Thank you.



TF Tom Frajer September 30, 2016 06:29 PM UTC

Here is how Im preparing data for my view:

        public ActionResult WorkflowDiagram()
        {
            IEnumerable<WorkflowTransition> transitions;
            IEnumerable<WorkflowState> states;
            transitions = workflowService.GetAllWorkflowTransitions();
            states = workflowService.GetAllWorkflowStates();

            //Create data model for diagram
            DiagramProperties model = new DiagramProperties();

            model.Width = "100%";
            model.Height = "600px";

            //Hide snap grid
            model.SnapSettings = new SnapSettings() { SnapConstraints = SnapConstraints.None };

            //Default Settings
            model.DefaultSettings.Node = new Node() { Type = Shapes.Flow, Width = 140, Height = 50, OffsetX = 300 };
            model.DefaultSettings.Connector = new Connector()
            {
                Labels = new Collection() { new Label() { FillColor = "white" } },
                Segments = new Collection() { new Segment(Segments.Orthogonal) }
            };

            int offsetX = 150;
            int offsetY = 80;

            //Create diagram states
            foreach (WorkflowState state in states)
            {
                model.Nodes.Add(CreateDiagramState(state.s_name, offsetX, offsetY, FlowShapes.Process, state.s_name));
                offsetX += 250;
                if (((offsetX - 150) / 250) == 5)
                {
                    offsetX = 150;
                    offsetY += 120;
                }
            }

            //Create diagram transitions between states
            foreach (WorkflowTransition transition in transitions)
            {
                model.Connectors.Add(CreateDiagramTransition(transition.s_name, transition.s_from_state, transition.s_to_state, transition.s_button_text));
            }

            model.DataSourceSettings = new DataSourceSettings()
            {
                CrudAction = new CRUDAction()
                {
                    //Specify the method name which is used to get the updated data from client side to the server side                         
                    Create = "/Diagram/UpdateDiagramState",
                },
                ConnectionDataSource = new ConnectionDataSourceSettings()
                {
                    CrudAction = new CRUDAction()
                    {
                        //Specify the method name which is used to get the updated data from client side to the server side                        
                        Create = "/Diagram/UpdateDiagramTransition",
                    }
                }
            };

            ViewData["diagramModel"] = model;
            return View();
        }

        private Connector CreateDiagramTransition(string name, string source, string target, string text="", Segment segment = null)
        {
            Connector connector = new Connector()
            {
                Name = name,
                SourceNode = source,
                TargetNode = target,
                Labels = new Collection() { new Label() { Text = text } }
            };
            if (segment != null) connector.Segments = new Collection() { segment };
            return connector;
        }

        private FlowShape CreateDiagramState(string name, int offsetX, int offsetY, FlowShapes shape, string text)
        {
            FlowShape node = new FlowShape()
            {
                Shape = shape,
                Name = name,
                OffsetX = offsetX,
                OffsetY = offsetY,
                Labels = new Collection() { new Label() { Text = text } }
            };
            return node;
        }


SG Shyam G Syncfusion Team October 4, 2016 09:36 AM UTC

Hi Tom, 
 
To achieve your requirement, you can use DiagramProperties ParseModel object in the server side which converts JSON string into the object. Please refer to the code example and sample below. 
 
Code example: 
[HttpPost] 
        public ActionResult save(string stringify) 
        { 
            //parsemodel method converts JSON string to diagram's model object 
            model.ParseModel(stringify); 
            //you can do the changes with diagram's model here 
            return null; 
        } 
 
 
Regards, 
Shyam G 



TF Tom Frajer October 6, 2016 02:16 PM UTC

That is it! Thank you. Now Im able to access changed diagram model in my aplication. I checked by renaming one of the connectors and found changed text inside model.  Now I have to figure out how to pull offsetX, offsetY and label properties of my nodes and label properties of my connectors. That will be enough for now. If you can help with this, that will be appreciated, but I think I will figure this out. Maybe it will be helpfull for some other people reading this post.

I also want to disable rotation of nodes.

Im very pleased so far :)


TF Tom Frajer October 6, 2016 02:42 PM UTC

I have it:

        public ActionResult WorkflowDiagramSave(string stringify)
        {
            IEnumerable<WorkflowTransition> transitions;
            IEnumerable<WorkflowState> states;

            model.ParseModel(stringify);

            foreach (Connector connector in model.Connectors)
            {
                WorkflowTransition transition = new WorkflowTransition();
                var transEnum = connector.Labels.GetEnumerator();
                transEnum.MoveNext();
                var transLabel = (Label)transEnum.Current;
                transition.s_button_text = transLabel.Text;
                //workflowService.UpdateWorkflowTransition(transition);
            }
            return null;
        }


SG Shyam G Syncfusion Team October 7, 2016 06:23 AM UTC

Hi Tom, 

Please refer to the code example in which we have shown how to iterate the nodes/connectors and its labels. 

Code example: 
  
        public ActionResult save(string stringify) 
        { 
            //parsemodel method used to get the diagram's model 
            model.ParseModel(stringify); 
            foreach (Node node in model.Nodes) 
            { 
                node.OffsetX = 300; 
                node.OffsetY = 200; 
                //disables rotator 
                node.Constraints = node.Constraints & ~NodeConstraints.Rotate; 
                //iterate node labels 
                foreach (Label label in node.Labels) 
                { 
                    //modify labels text 
                    label.Text = "design"; 
                } 
            } 
            foreach (Connector connector in model.Connectors) 
            { 
                //iterate connector labels 
                foreach (Label label in connector.Labels) 
                { 
                    //modify labels text 
                    label.Text = "connector"; 
                } 
            } 
            return null; 
        } 

Regards, 
Shyam G 


Loader.
Live Chat Icon For mobile
Up arrow icon