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

How to set offset position for a node while refreshing the canvas after moving the node within diagram container

I have enabled ej.diagrams.NodeConstraints.AllowDrop , so that I can reposition a node within diagram container. I am trying to capture the final position  of this node after the node is dragged with the diagram container.

To do this , I am using

positionChange: function (args) { ...} and storing the offsetX = args.newValue.offsetX and

,offsetY  args.newValue.offsetY against the node's unique id in a json object.

After this when I am reloading the diagram , I am calling diagram.destroy() and recreating the diagram with json data which I get back on load event. 

but while reloading the diagram ,  the node , which was dragged from it's default to user defined position it's retaining it's default position. 

 dataSourceSettings: {

           ..

            dataManager: new ej.data.DataManager(workflowData),

            doBinding: function (node, data, diagram) {

                node.id = data.Key;

                node.addInfo = { "Type": nodeType, "UId": data.Id};

                node.height = getNodeHeight( nodeType );

                node.width = getNodeWidth( nodeType );

                node.constraints = CanvasDefaults.TaskNodeConstraints;

                node.shape =

                    {

                        type: 'HTML',

                        content: nodeTemplate

                    };

               node.OffsetX = userdefinedPosition.OffsetX,

               node.OffsetY = userdefinedPosition .OffsetY,

}

}

userdefinedPosition .OffsetX and  userdefinedPosition.OffsetY is a global object holds the newposition.offsetX and offsetY which I had captured earlier on positionchange event. 

But this is not working.


Q1. Can you please help me figure out what how to capture the final position of a node after user moves it within diagram container, and I also want to use that information to set the offsetX and offsetY when I recreate the diagram, so that those nodes appear in it's user defined position

Q2. since position change gets triggered all along the movement, is there drag end like event which gives me the final coordinates? I have tried drop/dragend, none of them works. The reason could be these events are supposed to get triggered when we drag something from pallet to diagram, but here I am only trying to change it's position within container.



10 Replies 1 reply marked as answer

BM Balasubramanian Manikandan Syncfusion Team February 3, 2023 03:31 PM UTC

We rendered a sample for node stay its user defined position while load the diagram. Refer to the below-mentioned code example and sample.


Code Example

document.getElementById('RetrivePosition').onclick = function () {

var diagramData = {

     offsetX : "nodeOffsetX",

     offsetY : "nodeOffsetY"

};

localStorage.setItem("file", diagramData);

JSON.stringify(localStorage.getItem("file"));

};


Sample:

https://stackblitz.com/edit/nbdixb?file=index.html,index.js


Marked as answer

SD Sourangsu Dasgupta replied to Balasubramanian Manikandan February 5, 2023 02:00 PM UTC

Hi Bala -

Thanks for the example, when the node is associated with other nodes through connector, will this work? if bind the node while loading with the new offsetX and offsetY, it apparently holds it's old(default) position. Do I need to override the connector default as well?

if yes, could you please provide me with an example on what properties of the connectors need to be overridden to retain the node in its user defined position.



BM Balasubramanian Manikandan Syncfusion Team February 6, 2023 10:06 AM UTC

We have created a sample for your requirement. By using the node inEdges and outEdges property we can be able to get the connector connected to node. After get the inEdges through diagram getObject method we can able to get the connector from node. By using the connector’s sourcePoint and targetPoint method we can able to get the connector points and store it in JSON. Refer to the below-mentioned code example and sample.


Code Example

function positionChange(args) {

  if (args.state == 'Completed') {

    nodeOffsetX = args.newValue.offsetX;

    nodeOffsetY = args.newValue.offsetY;

    if(args.source.inEdges.length > 0 || args.source.outEdges.length > 0){

      var connector = args.source.inEdges.length ? diagram.getObject(args.source.inEdges[0]) : diagram.getObject(args.source.outEdges[0]);

      connectorSourcePoint = connector.sourcePoint;

      connectorTargetPoint = connector.targetPoint;

    }

  }

}

document.getElementById('RetrivePosition').onclick = function () {

var diagramData = {

     offsetX : "nodeOffsetX",

     offsetY : "nodeOffsetY",

     sourcePoint: "connectorSourcePoint",

     targetPoint: "connectorTargetPoint"

};

localStorage.setItem("file", diagramData);

JSON.stringify(localStorage.getItem("file"));

};


Sample:

https://stackblitz.com/edit/nbdixb-qsyklp?file=index.html,index.js




SD Sourangsu Dasgupta replied to Balasubramanian Manikandan February 8, 2023 04:55 AM UTC

I have tried to set the offsetX, offsetY for the node and target and source position of all the inner and outer Edges associated.

When I am loading the screen, I am using doBinding to bind the diagram with data provided to dataManager .

and for every data in nodeModel , I am applying the offsetx/Y and trying to override it's default position.

Also in the getConnectorDefaults , I am trying to override the source and targetPoints for inner and outerEdges. Still it doesn't work. Attached some code snippet for reference.


Attachment: Diagram_6b37380d.zip


2. Also- I saw some relevant article on an api "moveNode" ? can you please share some example 

code on how to  move a node along with it's connectors?



GD Gobinath Dhamotharan Syncfusion Team February 9, 2023 12:51 PM UTC

We modified a sample to achieve your requirement. We retrieved the last changed node position in position Change event and store it in local storage and in created event we update the node position by collecting the data from local storage. Also the connector get moves along with the node after changes. Please refer to the below sample for your reference.

Code snippet

created: function () {

    diagram.fitToPage({ mode: 'Width' });

    jsondata = JSON.parse(localStorage.getItem('file'));

    if (jsondata != undefined) {

      if (diagram.nodes) {

        for (var i = 0; i < diagram.nodes.length; i++) {

          if (diagram.nodes[i].data.Name == jsondata.Name) {

            diagram.nodes[i].offsetX = jsondata.offsetX;

            diagram.nodes[i].offsetY = jsondata.offsetY;

            diagram.dataBind();

          }

        }

      }

    }

  },

 

function positionChange(args) {

  if (args.state == 'Completed') {

    nodeOffsetX = args.newValue.offsetX;

    nodeOffsetY = args.newValue.offsetY;

    nodeName = args.source.data.Name;

    nodeCollection.offsetX = nodeOffsetX;

    nodeCollection.offsetY = nodeOffsetY;

    nodeCollection.Name = nodeName;

  }

  localStorage.setItem('file', JSON.stringify(nodeCollection));

  jsondata = JSON.parse(localStorage.getItem('file'));

}


Sample

https://stackblitz.com/edit/8girl6?file=index.html,index.js



SD Sourangsu Dasgupta February 9, 2023 03:09 PM UTC

Thanks - for your response, I have tried to implement the example you have sent in my code, here the diagram is already rendered in UI(created) and after that we are manipulating the offsets of the node, in this way even for a split second I can still see the nodes in its default position and then it transitions back to its user defined position. This makes the user experience odd, and it seems like the entire canvas is a bit jerky just after loading.  Can't I set the offsets of the node while doing doBinding: 

function (nodeModel, data, diagram) {

                nodeModel.id = data.Key;

                nodeModel.addInfo = { "TaskType": taskType, "UniqueId": data.UniqueId };

                nodeModel.height = getNodeHeight(taskType);

                nodeModel.width = getNodeWidth(taskType);

                nodeModel.constraints = CanvasDefaults.TaskNodeConstraints;

                nodeModel.shape =

                    {

                        type: 'HTML',

                        content: nodeTemplate

                    };

                nodeModel.annotations = [

                    {

                        constraints: ej.diagrams.AnnotationConstraints.ReadOnly,

                    }

                ];


                positionNodesInUserDefinedPosition();

}


or in some other way can I set it , before rendering the image?

I see that we can still set the offsetX,offsetY for nodes, and it works when it's not associated with any connector, but for nodes with connectors setting the offsetX,offsetY doesn't work. 

Also, not sure if this is not working for me since I am using a html template as node.shape



GD Gobinath Dhamotharan Syncfusion Team February 13, 2023 04:20 PM UTC

Hi Sourangsu,

We will validate and update you with more details on Feb 15, 2023.

Regards,

Gobinath



GD Gobinath Dhamotharan Syncfusion Team February 14, 2023 03:26 PM UTC

We save the last interacted node position in positionChange event and at initial loading, the created event triggers in which we set the position for last changed node. Similarly, you can set the node position in the created event. Please refer to the sample below for your reference. 

Sample 

https://stackblitz.com/edit/8girl6-hznguo?file=index.html,index.js 



SD Sourangsu Dasgupta replied to Gobinath Dhamotharan February 15, 2023 06:27 AM UTC

But Is this any different compared to last response posted in this thread on  February 9, 2023 06:21 PM? 



GD Gobinath Dhamotharan Syncfusion Team February 16, 2023 03:03 PM UTC

The difference is we modified the sample on FEB 14 update, your requirements were not met by the attached sample on February 9


Loader.
Live Chat Icon For mobile
Up arrow icon