Author Topic: How to hide connectors?  (Read 9375 times)

Manfred Kröpfli

  • EA User
  • **
  • Posts: 31
  • Karma: +0/-0
    • View Profile
How to hide connectors?
« on: August 21, 2009, 05:34:18 pm »
Hi

I ran into the problem that I'm not able to query visible connectors of an newly generated diagram (through Automation API).

I'd like to do:
Code: [Select]
               foreach (EA.DiagramLink dlink in diagram.DiagramLinks)
                {
                    connector = repository.GetConnectorByID(dlink.ConnectorID);
                    if (!connector.Name.EndsWith("impact"))
                    {
                        dlink.IsHidden = true;
                        dlink.Update();
                    }
                }
but whenever I call diagram.DiagramLinks, I get an empty collection, though connectors are clearly visible!

BTW, in the EA User Guide, I find the note on p. 1687:
"A DiagramLink is only created once a user modifies a connector in a
diagram in some way. Until this condition has been met default values
are used and the DiagramLink is not in use."

Maybe this leads to the solution?

Thx for any clues
Manfred
Cheers
Manfred

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13401
  • Karma: +566/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: How to hide connectors?
« Reply #1 on: August 21, 2009, 05:42:42 pm »
Well, in that case I'm afraid you'll have to create the diagramLinks yourself and them set them to hidden.

Geert

Manfred Kröpfli

  • EA User
  • **
  • Posts: 31
  • Karma: +0/-0
    • View Profile
Re: How to hide connectors?
« Reply #2 on: August 21, 2009, 06:56:58 pm »
Tough one!

You mean, I have to figure out all connections between the elements contained in my diagram to add and hide a diagram link for each connection?

Any idea for a lean algorithm?

Manfred
Cheers
Manfred

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13401
  • Karma: +566/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: How to hide connectors?
« Reply #3 on: August 21, 2009, 07:28:22 pm »
I'm afraid there is not going to be a lean algorithm.
I think you'll have to do something like
  • Loop all DiagramObjects
  • For each DiagramObject get the Element and put it in a collection of some sort (preferably a dictionary/hashmap/whatever it is calle in your language) with the ElementID as key
  • Loop all elements in your collection
  • for each element loop all Element.Connectors
  • for each connector figure out whether it is shown on the diagram by comparing the ClientID and SupplierID with the id's of the element in your collection (hence the dictionary with key ElementID)
  • if both ID's are in the element collection then create a diagramLink based on the diagram
  • set the appropriate fields (ConnectorID)
  • hide the diagramLink
  • update the diagramLink (and maybe the diagram, to be tested)
The order in which you perform the updates is sometimes a bit difficult. Usually a bit of trial and error gets you there.

Geert

«Midnight»

  • EA Guru
  • *****
  • Posts: 5651
  • Karma: +0/-0
  • That nice Mister Grey
    • View Profile
Re: How to hide connectors?
« Reply #4 on: August 21, 2009, 07:52:01 pm »
I can shed some light on what's happening. You will have to come up with your own opinion about it...

By default EA does not create and store diagram links for all connectors on a diagram. Only links that have at least one non-default property are actually stored in the database. The 'tweak' in the property can be something minor like a specific layout, or a visibility setting. A simple example is deciding to hide a connector on a diagram. In this case EA will create a diagram link for that connector (if one is not already in the database) and mark it as not visible.

When EA loads a diagram it queries the database for all links between elements that are visible on the diagram. For each link it then checks the database for a diagram link. If the link is found EA uses the stored properties of the link to draw (or hide) the link on the diagram. If the link is not found EA draws the link using any default settings that might apply. This is why you sometimes see new links pop up on diagrams in evolving models, and why these new links are often over elements or using inconvenient paths.

So if you want diagram links to have anything other than default properties, or don't want to accept EA's default drawing methods, then you have to set the properties yourself. In the case of new links (or new diagrams that don't have any defined links) you have to first create the links, then set at least one property.

HTH, David
No, you can't have it!

Manfred Kröpfli

  • EA User
  • **
  • Posts: 31
  • Karma: +0/-0
    • View Profile
Re: How to hide connectors?
« Reply #5 on: August 21, 2009, 07:54:31 pm »
Wow! That was quick :-)

You mean something like this:
Code: [Select]
               ArrayList elementIDs = new ArrayList();
                EA.Collection dobjs = diagram.DiagramObjects;
                foreach (EA.DiagramObject dobj in dobjs)
                    elementIDs.Add(dobj.ElementID);

                foreach (EA.DiagramObject dobj in dobjs)
                {
                    element = repository.GetElementByID(dobj.ElementID);
                    foreach (EA.Connector connector in element.Connectors)
                    {
                        if (elementIDs.Contains(connector.ClientID) &&
                            elementIDs.Contains(connector.SupplierID))
                        {
                            dlink = (EA.DiagramLink) diagram.DiagramLinks.AddNew("","");
                            dlink.ConnectorID = connector.ConnectorID;
                            dlink.IsHidden = true;
                            dlink.Update();
                        }
                    }
                    elementIDs.RemoveAt(elementIDs.IndexOf(dobj.ElementID));
                }

                diagram.Update();

Unfortunately no luck. The connections don't disappear. Still trying to find out why ...

Manfred
Cheers
Manfred

«Midnight»

  • EA Guru
  • *****
  • Posts: 5651
  • Karma: +0/-0
  • That nice Mister Grey
    • View Profile
Re: How to hide connectors?
« Reply #6 on: August 21, 2009, 07:57:59 pm »
You probably need to refresh the diagram. Using Update() merely ensures changes are stored to the database; it does not affect the display.

Why are you doing the final RemoveAt operation? [Please excuse if this is obvious. I didn't go through the code in depth.]
No, you can't have it!

Manfred Kröpfli

  • EA User
  • **
  • Posts: 31
  • Karma: +0/-0
    • View Profile
Re: How to hide connectors?
« Reply #7 on: August 21, 2009, 08:12:16 pm »
David,

just to avoid that a connector is treated twice (via both ends).

BTW, both:
Code: [Select]
repository.RefreshOpenDiagrams(true);
repository.ReloadDiagram(diagram.DiagramID);
do not fix my problem.

Manfred
Cheers
Manfred

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13401
  • Karma: +566/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: How to hide connectors?
« Reply #8 on: August 21, 2009, 08:55:20 pm »
Yes, that was about wat I meant.
Did you check the database to check whether the isHidden property is set to true?
I've seen it happen before that updating some setting through the API didn't stick.

Maybe updating the diagramLink between setting the connectorID and setting isHidden helps. (long shot)

«Midnight»

  • EA Guru
  • *****
  • Posts: 5651
  • Karma: +0/-0
  • That nice Mister Grey
    • View Profile
Re: How to hide connectors?
« Reply #9 on: August 21, 2009, 09:07:01 pm »
You are quite correct Manfred, it is important to eliminate duplicate connectors.

Geert is correct as well, you have to make sure the property sticks.

What I have always done is the following: [NOTE: It has been a long time, so you might have to toy around with this to account for my failing memory...]

First, ensure that you create the new diagram link and save it before you set the visibility. Then update the visibility and save it again. You are correct however in setting the ConnectorID before you first save the link; failure to do so would result in an invalid link and EA would not save the information. This means you will call Update() twice when you create the link: once immediately after you set the ConnectorID, and a second time after you set the visibility to hide the connector. Note that if you want to have the connector displayed, set some other property explicitly, then save the second time. I think you might be OK if you set the visibility to show the connector, but you will have to test this.

Second, playing around with the DeleteAt call to a collection that's in use is inherently dangerous. There are simply too many ways to get the collection out of sync with your logic. I have always created some kind of list (or dictionary or whatever) in my code (as appropriate for the programing paradigm I am using at the time) to keep track of the connectors. I check for duplicates using this list, only adding unique instances. I then iterate through the list and create the entire set of diagram links. This paradigm also allows me to individually tailor the properties I will set by creating some custom classes (in my code) with (only) the settings I am interested in. I can then query each object in the list to determine what to set. Once I finish creating the diagram links I can Refresh() the collection in EA and then update the diagram (if the UI is open).

HTH, David
No, you can't have it!

Manfred Kröpfli

  • EA User
  • **
  • Posts: 31
  • Karma: +0/-0
    • View Profile
Re: How to hide connectors?
« Reply #10 on: August 21, 2009, 09:26:49 pm »
Hi Geert & David

thanks for the very helpful session on dealing with DiagramLinks in EA.

I confirm that:
- setting the type in DiagramLinks.AddNew("",connector.Type) and
- the two-phase DiagramLink.Update() and
- the Diagram.DiagramLinks.Refresh() and
- the final diagram reload
did the needed magic.

I wish you both a pleasant weekend.

Code: [Select]
               foreach (EA.DiagramObject dobj in dobjs)
                {
                    element = repository.GetElementByID(dobj.ElementID);
                    foreach (EA.Connector connector in element.Connectors)
                    {
                        if (elementIDs.Contains(connector.ClientID) &&
                            elementIDs.Contains(connector.SupplierID))
                        {
                            dlink = (EA.DiagramLink)diagram.DiagramLinks.AddNew("", connector.Type);
                            dlink.ConnectorID = connector.ConnectorID;
                            dlink.Update();
                            dlink.IsHidden = true;
                            dlink.Update();
                        }
                    }
                    elementIDs.RemoveAt(elementIDs.IndexOf(dobj.ElementID));
                }
                diagram.DiagramLinks.Refresh();

                if (diagram.Update())
                    repository.ReloadDiagram(diagram.DiagramID);
« Last Edit: August 21, 2009, 09:30:55 pm by kroepfli »
Cheers
Manfred

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13401
  • Karma: +566/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: How to hide connectors?
« Reply #11 on: August 21, 2009, 09:32:32 pm »
Manfred,

I'm happy you have a working solution now.

David,
I agree that deleting elements from a collection (especially an EA.Collection) is dangerous, but in this instance it is not a problem.
The collection in question (ElementIDs) is a plain old ArrayList, and it is not being iterated.

Nice weekend to you too.

Geert