Book a Demo

Author Topic: Add new DiagramObjects to active diagram, then re-position them.  (Read 12610 times)

bizna

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
hello, I'm writing an add-in using c# that adds new "DiagramObjects" to the active diagram, then re positions them in alphabetical order.  The trouble I'm having is that the diagram object's Top, Bottom, Left, and Right properties are all showing up as zero when I try to reposition them.  If I run only the code that creates the diagram objects on the diagram, then shut down EA and run the code that re-positions the diagram objects, the Top, Bottom, Left, and Right properties show up with their proper, non-zero values and the code is able to work as expected.  While I could simply write two add-ins to achieve this, I wonder if I need to.  I have tried inserting all sorts of diagram.Update() and diagram.Refresh statements, to no avail.

Here is the code where I create the diagram object:

                    EA.DiagramObject diagram_object = diagram.DiagramObjects.AddNew("", "");
                    diagram_object.ElementID = el.ElementID;
                    diagram_object.Update();
                    diagram.Update();

I am purposely leaving out any position arguments, as I want EA to create the initial size of the diagram object for me.

Later in the code, I retrieve the diagram object, like so:

                EA.DiagramObject diagram_object = diagram.GetDiagramObjectByID(diagram_object_ID, null);

Then try to access it's position properties, e.g. diagram_object.bottom, but the values are all zero.

Does anyone know what I should do to be able to retrieve the values as expected?

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13523
  • Karma: +574/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #1 on: January 16, 2019, 03:08:29 pm »
Have you tried to reload the diagram before accessing the diagramobjects?

Geert

bizna

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #2 on: January 17, 2019, 04:54:44 am »
Hi Geert,

Yes, I've tried reloading the diagram.  Out of desperation,I've also tried a few combinations of the following lines of code, none of which work:

            diagram.DiagramObjects.Refresh();
            Repository.SaveDiagram(diagramID);
            Repository.RefreshModelView(0);
            Repository.ReloadDiagram(diagramID);
            Repository.RefreshOpenDiagrams(true);
            diagram = Repository.GetDiagramByID(diagramID);

I've also tried retrieving the diagram like this, just in case it is somehow different:

            diagram = Repository.GetCurrentDiagram();

thanks,
Jason

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +397/-301
  • I'm no guru at all
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #3 on: January 17, 2019, 05:35:19 am »
Phew. Looks like you put some source in a mixer and looked what comes out.


Code: [Select]
EA.DiagramObject diagram_object = diagram.GetDiagramObjectByID(diagram_object_ID, null);
The operation takes only one argument, the ID.

Code: [Select]
            diagram.DiagramObjects.Refresh();
            Repository.SaveDiagram(diagramID);
            Repository.RefreshModelView(0);
            Repository.ReloadDiagram(diagramID);
            Repository.RefreshOpenDiagrams(true);
            diagram = Repository.GetDiagramByID(diagramID);


Salsa? Why do you load the diagram object? There is no need to save the diagram if you just want to add a diagram object. Maybe you show us just the minimal code where you try to add an object. Btw. I don't see any coordinate being supplied.

q.
« Last Edit: January 17, 2019, 06:52:32 pm by qwerty »

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13523
  • Karma: +574/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #4 on: January 17, 2019, 06:09:36 pm »
Why do you need to retrieve the diagramObject after having created it?
Can't you just keep a reference of it?

Try adding a diagramObject with 0 for x, y, top and bottom. EA will automatically set the correct size.
This is what I do in my code:

Code: [Select]
        public UML.Diagrams.DiagramElement addToDiagram(UML.Classes.Kernel.Element element, int x = 0, int y = 0, int newHeight = 0, int newWidth = 0)
        {
            UML.Diagrams.DiagramElement diagramElement = null;
            if (element != null)
            {
                //first check whether this element is not already added to this diagram
                diagramElement = this.getDiagramElement(element);
                if (diagramElement == null)
                {
                    if (element is EA.ElementWrapper)
                    {
                        string addNewString = createAddNewString(x, y, newHeight, newWidth);
                        //first save the diagram to make sure we don't lose any unsaved changes
                        this.model.saveOpenedDiagram(this);
                        global::EA.DiagramObject newDiagramObject = this.wrappedDiagram.DiagramObjects.AddNew(addNewString, "") as global::EA.DiagramObject;
                        diagramElement = ((Factory)this.model.factory).createDiagramElement(newDiagramObject);
                        diagramElement.element = element;
                        //save the element diagramObject
                        ((DiagramObjectWrapper)diagramElement).save();
                        //add the diagramObject to the list
                        this.diagramObjectWrappers.Add(diagramElement);
                        // now refresh to make sure we see the new element on the diagram
                        this.reFresh();
                    }

                    else if (!(element.owner is UML.Classes.Kernel.Package))
                    {
                        diagramElement = this.addToDiagram(element.owner);
                    }
                }
            }
            return diagramElement;
        }

Geert

bizna

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #5 on: January 18, 2019, 05:18:05 am »
Hi Q,

I know it looks like I threw everything at it but the kitchen sink! I added lines incrementally as I was attempting to have the diagram object return the position properties I expected.

Regarding your first point, although the documentation says the second parameter for diagram.GetDiagramObjectByID, the DUID, is optional, visual studio was insisting it was required,  so I used null to satisfy visual studio.

this code:
Code: [Select]
            diagram.DiagramObjects.Refresh();
            Repository.SaveDiagram(diagramID);
            Repository.RefreshModelView(0);
            Repository.ReloadDiagram(diagramID);
            Repository.RefreshOpenDiagrams(true);
            diagram = Repository.GetDiagramByID(diagramID);

... comes after creating the diagram objects.  The only reason I'm trying all this refreshing, saving, and reloading is to attempt to have the diagram objects return non-zero position (top, bottom, left, right) properties.

When I create the diagram objects, I don't supply any position information.  This results in them all being situated in the top left of the diagram, overlapping each other.  What they do have at this point is non-zero position values, as evidenced by their placement on the diagram, and, if I look at them in the t_diagramobjects table by opening the .eapx file in MS Access, I can see that they have non-zero values in the RectTop, RectBottom, RectLeft, RectRight fields.

... So my question is, how can you add a diagram object in a diagram (supplying no coordinate information), then retrieve the coordinate information that EA somehow generates?

Jason

bizna

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #6 on: January 18, 2019, 07:12:56 am »
Hi Geert,

Thanks for your response.  I've tried to add the position arguments as you've shown in your code. So now I have this, but the 'right'
property is still returning zero:

Code: [Select]
                    string addNewString = "l=0;r=0;t=0;b=0;";
                    EA.DiagramObject diagram_object = diagram.DiagramObjects.AddNew(addNewString, "");
                    diagram_object.ElementID = el.ElementID;
                    diagram_object.Update();
                    Debug.WriteLine(diagram_object.right); // still shows zero!

Am I missing something else in my translation from your example to my code?
Thanks
Jason

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +397/-301
  • I'm no guru at all
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #7 on: January 18, 2019, 08:27:42 am »
Comes to checking this, but GetDiagramObject is no operation up to V13. Are you using V14? If so, this is probably a bug in a new operation. They never test anything and trust in users to find bug :-(

Here's a sample (pseudo) code (from my Scripting book):
Code: [Select]
dia_obj = diagram.DiagramObjects.AddNew ("l=10;r=110;t=-20;b=-80", "");
  dia_obj.ElementID = element.ElementID;
  dia_obj.Update ();
  Repository.ReloadDiagram (diagram.DiagramID);

Note that coordinates go positive left (0) to right and negative from top (0) to bottom

q.

bizna

  • EA Novice
  • *
  • Posts: 6
  • Karma: +0/-0
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #8 on: January 18, 2019, 09:04:32 am »
Hi Q,

Thanks for the suggestion, I tried it out like so:
Code: [Select]
                    string addNewString = "l=0;r=0;t=0;b=0;";
                    EA.DiagramObject diagram_object = diagram.DiagramObjects.AddNew(addNewString, "");
                    diagram_object.ElementID = el.ElementID;
                    diagram_object.Update();
                    Repository.ReloadDiagram(diagram.DiagramID);
                    Debug.WriteLine(diagram_object.right); // returns zero, not a positive number

Unfortunately, it still gives a zero.  Yes, I'm using version 14.1.1427.  So perhaps this is just a bug.

I will change the add-in so that it requires the diagram objects to be created ahead of time, and just does the repositioning I'm after.

thanks Geert and Q for your assistance.
Jason

Aaron B

  • EA Administrator
  • EA User
  • *****
  • Posts: 941
  • Karma: +18/-0
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #9 on: January 18, 2019, 10:46:43 am »
AFAIK, EA doesn't set the left, right, top and bottom until a Save is explicitly performed on the diagram. I think you might be able to force this by first calling Repository.ReloadDiagram() to get EA to load the DiagramObjects you've just added, then call Repository.SaveDiagram() to have it write the calculated positions to the database. You may also need to get new references to your Diagram and DiagramObject afterward to make sure you can access the updated values.

Code: [Select]
Repository.ReloadDiagram(diagramID);
Repository.SaveDiagram(diagramID);

//diagram and diagramobject may have become invalidated. get new references to both.
diagram = Repository.GetDiagramByID(diagramID);
diagramobject = diagram.DiagramObjects.GetAt(0);

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +397/-301
  • I'm no guru at all
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #10 on: January 18, 2019, 07:40:49 pm »
Well, out of curiosity I installed V14 and ran the above code. No issues. Object placed at expected. You should check whether you have any add-ins / MDGs running and turn them all off first. If that does not help, try with another empty EA repository. Next step would be a re-installation. If none helps, you should either try to come up with more details or you contact Sparx support.

q.

k2901

  • EA User
  • **
  • Posts: 25
  • Karma: +0/-0
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #11 on: February 06, 2019, 09:27:21 pm »
I get the same issue regarding the zero values in top,left,bottom,right for new DiagramObjects. Has there been any further news from anyone regarding this issue? I'm using version 14.0.1423

Done some further testing, using the same .EAP, and version 14.0.1423. Have built a C# solution using existing code and works 100%, and some new code to build the same using a different way of coding and I get the issue the issue as described above. Not been able to determine what the issue is, but it's code/C# related.

Update - Just seen this note in build 1427...
- "DiagramObject.Update() changed to improve positioning of wireframe elements and other embedded elements when the diagram isn't open"

I don't have access to download the latest build, otherwise I'd try it...
« Last Edit: February 07, 2019, 12:04:42 am by k2901 »

k2901

  • EA User
  • **
  • Posts: 25
  • Karma: +0/-0
    • View Profile
Re: Add new DiagramObjects to active diagram, then re-position them.
« Reply #12 on: February 12, 2019, 10:20:24 pm »
Some good news, I managed to resolve the problem with the diagramObject, having zeros as the position. The only way I could get this resolved, was to use LayoutDiagram. This will layout the diagram and set eh left, right,top,bottom attributes correctly. I wanted to use the LayoutDiagramEx, but didn't have any documentation which was informative enough to understand how to use it correctly.