Get all diagrams method not working

Dear Capella and Python4Capella users,

I am a bit blocked with an issue I am not capable to find a solution for, related to the get_all_diagrams() method. Basically, I want to get a list of all the diagrams for a given model. The subset of code that I am using for this is:

aird_path = '/model_name/model_name.aird'
model = CapellaModel()
model.open(aird_path)

diagram_list = model.get_all_diagrams()
for diagram in diagram_list:
    diagram_name= diagram.get_name()
    print(diagram_name)

However, I do not get any diagram through the console and when checked, the length of diagram_list is zero (there are a total of 17 diagrams I believe in the model I am using).

Any clues for this? Seems like an easy method but I just cannot identify where the problem is.

PS: extra question, does Capella identify subtypes within type “diagram”? (e.g. a LAB, a LES, a PAB… and so on). Let’s say I want to perform this differentiation to call get_all_contents_by_type, where I want to get all the LABs as specialisation for get_all_contents_by_type (Diagram)

Thanks in advance,
Carlos.

I reproduce this issue. It’s weird bug, the Java method returns a non empty list but the Python loop doesn’t iterate over any of the element. I fixed the bug by replacing CapellaModel.get_all_diagram():

    def get_all_diagrams(self) -> List[Diagram]:
        """
        Returns: Diagram[*]
        """
        return JavaList(Sirius.get_all_diagrams(self.session), Diagram)

I opened the following issue:

You can use:

diagram.get_type()

But it’s not a Python type, it’s the Sirius description name of the diagram. You can use it to identify the kind of diagram you are working with but it can’t be used with get_all_contents_by_type().
Also diagrams are not contained in the semantic (Capella model) resource but in an other resource (.aird file) so get_all_contents_by_type(Diagram) will not work.

1 Like

Dear Yvan,

First of all thanks for the inmediate response! The fix works just fine :slight_smile:

And for the second question: understood, thanks again!

PS: Taking advantage of this already created thread: I was thinking in defining a model metric that evaluates the number of model elements that appear on diagrams vs the total number of model elements. The complexity here is that there are some model elements which do not support appearing in diagrams and thus the metric would get contaminated by them. Is there any way in which I could retrieve those model elements whose type supports to appear in a diagram, to them compute the metric against them? I have seen there is a method defined for EObjects called get_representing_diagrams, so maybe I should head in that direction.

Thanks in advance.

Kind regards,
Carlos.

1 Like

Technically you should be able to know which type can be represented on a diagram using the description of each diagram. You will have to use the Java API in your script that can be difficult if you don’t have the Java code of Sirius in this case.

A diagram description (DiagramDescription) have a list of mappings (NodeMapping, ContainerMapping, EdgeMapping) that reference a domain class. The domain class is the name of the EClass (or type) of the element the mapping can be applied on. From this you can create a list of type names that can be represented on a diagram to filter elements from your model.

The following code doesn’t work because even if mapping lists are not empty I can’t iterate over them with Python. Didn’t find why nor how to workaround this. I leave the code here maybe you will find a workaround or some obvious mistake I made. :slight_smile:

diagrams = model.get_all_diagrams()

# remove duplicated descriptions
diagram_descriptions = set()
for diagram in diagrams:
    description = diagram.get_java_object().getRepresentation().getDescription()
    if description.eClass().getName() == "DiagramDescription":
        diagram_descriptions.add(description)

represented_type_names = set()
for diagram_description in diagram_descriptions:
    print(diagram_description.getName())
    for mapping in JavaList(diagram_description.getNodeMappings(), EObject):
        print(" - " + mapping.get_java_object().getName())
        represented_type_names.add(mapping.get_java_object().getDomainClass())
    for mapping in JavaList(diagram_description.getContainerMappings(), EObject):
        print(" - " + mapping.get_java_object().getName())
        represented_type_names.add(mapping.get_java_object().getDomainClass())
    for mapping in JavaList(diagram_description.getEdgeMappings(), EObject):
        print(" - " + mapping.get_java_object().getName())
        represented_type_names.add(mapping.get_java_object().getDomainClass())

for name in represented_type_names:
    print(name)

Thanks again for the prompt response Yvan. I will try to get my way around this with the code you provided.

Kind Regards,
Carlos.

1 Like

Hi,

I’ve faced the same issue while trying to use CapellaModel.get_all_diagrams(), I tried to apply the fix suggested by @Yvan, i.e., replacing the get_all_diagrams() function in the capella.py file in the simplified_api folder with the code suggested by Yvan, but I still get an empty list.

Can anyone please point out what am I doing wrong?

Cheers,
Ebrahim

It is working now :slightly_smiling_face:
I’ll just leave this comment here for future newbies like me; after modifying the simplified_api/capella.py file, you need to reload the Python4Capella project (close and open the project).

3 Likes