archimatetool / archi

Archi: ArchiMate Modelling Tool
https://www.archimatetool.com
MIT License
946 stars 269 forks source link

[Specialization] Allow icon customization and profiles #705

Closed Phillipus closed 2 years ago

Phillipus commented 3 years ago

From @jbsarrodie

This should make it possible to use an imported image instead of the built-in ArchiMate icon. This image could be of a different size, so positioning the icon (which is a change introduced before) should be implemented with care (e.g. top right position means that the top right corner of the icon is drown some pixels away from the top right figure corner, thus the icon is always drawn inside the figure).

At this step, it become possible to create a "toolbox" which leveral stereotypes and custom notation. This is my MVP.

Phillipus commented 3 years ago

Let's review what we have so far in the branch icons (which I will be constantly rebasing and cherry picking over time).

  1. It uses the same mechanism for adding an image from file as used in Canvas blocks and stickies
  2. Once an image is added, the *.archimate file is saved as a zip archive format file and images are stored in that file with a generated path such as images/_8tf3UBlQEeuRw8mw0SgOkA.png
  3. That image path is used by all objects that reference that image. This is the image's unique ID. Example of usage - <child xsi:type="archimate:DiagramObject" imagePath="images/_8tf3UBlQEeuRw8mw0SgOkA.png" imagePosition="4">
  4. If the same image is re-added from file, the original image in the model is re-used even if it has a different file name (image equality is based on comparison of image bytes)
  5. It uses the same positioning mechanism of 9 positions (top-left, top-centre, etc). There is no pixel position fine tuning. There is no margin offset, either.
  6. Once an image is added to an ArchiMate object, its ArchiMate icon (if it has one) is not shown (see the question below as to whether this behaviour is wanted)
  7. The Format Painter tool in the palette will also copy the image path to the target object

These are the objects that can now contain an image (Canvas objects are unchanged):

  1. All ArchiMate objects
  2. Visual Groups
  3. Notes
  4. View References
  5. Sketch Stickies

Questions:

  1. Do we want all of the objects in the above list to support images? Does it make sense, for example, to have images in View References? How about Notes?
  2. Do we want to auto-hide the mini-icon in ArchiMate objects if there is an image? It can get in the way if it is visible as well as an image. Do we need a checkbox in Properties tab to show/hide this icon as well?
  3. There was a discussion about referencing image files from jArchi with ids and names. As mentioned above, the current mechanism is to store them in the format images/_8tf3UBlQEeuRw8mw0SgOkA.png and use that as the unique id. This is deliberate because image file names can be arbitrary or duplicate (see above on image bytes re-use). **

** Edit - it is possible to use the filename as the path name, as in images/my_image.png and if the name already exists add it as images/my_image1.png It depends on what/how we expose these images in jArchi. We can return a list of image paths.

morb-au commented 3 years ago

Is it possible to use PNG-encoded images instead of JPEG-encoded images? This would allow for lossless compression of icons.

*** edit: previously posted under my secondary account

morb-au commented 3 years ago

Is it possible to use PNG-encoded images instead of JPEG-encoded images? This would allow for lossless compression of icons.

Yes. An image is stored "as is". The above was an example.

Thanks

jbsarrodie commented 3 years ago

Hi,

Jumping on the discussion...

Do we want all of the objects in the above list to support images? Does it make sense, for example, to have images in View References? How about Notes?

Yes because I might want to add a magnify glass icon to a view reference to show that one can drill down and have more details by navigating this view reference, or add a green check mark or a red cross to a note to show its status.

Do we want to auto-hide the mini-icon in ArchiMate objects if there is an image? It can get in the way if it is visible as well as an image. Do we need a checkbox in Properties tab to show/hide this icon as well?

Good question. I know some use-cases in which we would want to keep the archimate icon to make sure people know the generic type, and add a custom one for the specialization.

But this raises the issue of the icon position: if I show both icons I want both of them to be visible if set to top-right :

+---------------------+
|            :-)  =[] |
|                     |
|                     |
|                     |
|                     |
+---------------------+

But if I show only the custom one, I want it on the top right:

+---------------------+
|                 :-) |
|                     |
|                     |
|                     |
|                     |
+---------------------+

That's a bit similar and related to the way the figure label behaves: if set to top, the label bounding box excludes the icon, if set to middle or bottom, the label bounding box includes the icon. Do we want to open this pandora box and have to manage all these different cases?

There was a discussion about referencing image files from jArchi with ids and names. As mentioned above, the current mechanism is to store them in the format images/_8tf3UBlQEeuRw8mw0SgOkA.png and use that as the unique id. This is deliberate because image file names can be arbitrary or duplicate (see above on image bytes re-use). Edit - it is possible to use the filename as the path name, as in images/my_image.png and if the name already exists add it as images/my_image1.png It depends on what/how we expose these images in jArchi. We can return a list of image paths.

The typical use-case is to create a script which iterate on all view to make sure the figure icon matches the element's stereotype associated icon. This means that images should have a somewhat readable name, something we can reference and match to a stereotype name or any property value. This name can be the "internal" name of the image or an associated property.

So I can see several options:

I would choose the last option because it would also open the way to a clever behavior in which the icon automatically matches the stereotype name (if defined), and we do want this ultimately. Of course we could also add a way to define a mapping between stereotypes and icons, at model level (that's what Hervé did in his latest version of his specialization plugin) but this would be a completely new thing to code, and though a bit more explicit (centralized configuration for stereotypes images) this wouldn't add much to a simpler approach in which we simply match the stereotype name and the image name.

Phillipus commented 3 years ago

Icon positioning

That's a bit similar and related to the way the figure label behaves: if set to top, the label bounding box excludes the icon, if set to middle or bottom, the label bounding box includes the icon. Do we want to open this pandora box and have to manage all these different cases?

Each figure is hand-crafted. And there is code to determine where to place the small icon and text (label) control. A Figure has a getIconOrigin() method to position the icon depending on what type of shape it is. There is also an iconOffset variable used in some Figures so that when calculateTextControlBounds() is called and the text control (label) is at the top and centre/right positioned the text control is moved slightly so it doesn't overlap the icon.

So, all of that hand-crafted code for icon/text label placement will break (and need changing) if we introduce other factors (including if we have alternative shapes).

Some options that occur to me:

  1. Hide the little icon if the figure contains a user image (current behaviour)
  2. Add an option to hide/show the little icon and keep the current icon positioning code (requires adding a Feature to store the setting and a new UI tick-box on the Properties tab)
  3. Move the icon depending on certain factors - Is there a user image? Where is it? What size is it? Does it overlap the icon position?
  4. Allow pixel positioning of the icon (would need x, y position controls in Properties tab)
  5. Combinations of (2) and (3) and (4)

For me, the last options are the "Pandora's box" options. This type of coding is always time-consuming, fiddly and always ends up being changed. If we are going to refactor all of the Figure drawing code to support allowing different shapes for each Figure it might be better to leave this for now and go for a simple option. There's a danger of getting bogged down in this kind of stuff. ;-)

Edit - another option is to allow finer positioning of the user image. We use a class IconicDelegate[1] that takes care of positioning and drawing the image in one of the nine positions. I also added internal support for left, right, top and bottom pixel offsets (IconicDelegate.setTopOffset() is used when drawing a Group figure so that the image is drawn in the bottom recatngle if using a tabbed figure). So, for example, you can draw the image in the top-right position and also set a right-hand offset of, say, -15 which will draw the image 15 pixels to the left in the top-right position. These four offsets could be exposed in the UI and saved in a Feature. Or we could simply expose two offsets, x and y, for additional finer image position placement.

[1] https://github.com/archimatetool/archi/blob/master/com.archimatetool.canvas/src/com/archimatetool/canvas/figures/IconicDelegate.java

jbsarrodie commented 3 years ago

Some options that occur to me:

There are in fact several use-cases for custom icons and they might interfere and require different behaviors:

  1. One use-case is to replace the ArchiMate icon (at the same place) for specialized concepts (i.e. stereotypes) in the spirit of what was illustrated in ArchiMate 2 specs (see below). That's what I had in mind for this sprint. The icon is linked to the stereotype.
  2. One use-case is to keep the ArchiMate icon (no specialization) but to add some small icon for communication/analysis purpose. For example, add a traffic light, a star, a cross... In such case, the icon should be of a similar size than the ArchiMate one. We might also want to link this icon the some property, maybe even allow multiple icons.
  3. One use-case is to simplify the notation and mimic "cloud" diagrams. In this case, the icon replace the ArchiMate icon but is usually bigger and centered. That's what I did in this example which uses AWS icon set: Stereotypes and Profiles (demo)
  4. One last use-case I can see is to fully replace the standard figure. For example, let's say I work on micro-services, I might want to replace the application component figure by an hexagon and produce something like that: image

I'd say that:

So all that being said, I would keep current implementation (custom icon replace default icon), and maybe, as you suggested, add an option to hide/show the ArchiMate icon. But what annoys me is that in some occasion, hiding should be automatic (if the custom icon is on top-right, we know almost for sure that the ArchiMate icon should be hidden). So the "hidding" feature is not as straightforward as it may seem.

Phillipus commented 3 years ago

Let's be clear about the terminology - "icon" is the little icon drawn in Draw2D code, I use "image" to mean a user image (png, jpg, etc) which can be any size (no scaling is done) and can be located in one of nine positions.

One use-case is to replace the ArchiMate icon (at the same place)

Given the way images are located (one of nine positions) and given that the user image can be of any size, this might not always work. We can position the existing Draw2D icon at an exact x,y location because we know what its size is, but with a user image it might not work if it is positioned at the same x, y location. The image positioning code does not do absolute x,y positioning.

So, now I'm not clear if you're proposing not using the image positioning code (as is used in Canvas objects) and instead something else that positions the image at one x,y position at top right?

So - do we want to use the nine-position IconicDelegate system of displaying images with their sizes as-is, or is something else needed instead like positioning the image at an absolute x,y location and scale the image to a 16x16 or 32x32 size to fit (as in Canvas objects)? Because if so, I'll have to scrap all the work I've done so far and start all over again. 😕

maybe even allow multiple icons.

That would require rather a large change to the code! :-0

But what annoys me is that in some occasion, hiding should be automatic (if the custom icon is on top-right, we know almost for sure that the ArchiMate icon should be hidden).

It depends on the image and its size. User might have an image with enough white space or transparency to allow space for an icon. So I can see some cases where the auto-hide might not be wanted.

So all that being said, I would keep current implementation (custom icon replace default icon), and maybe, as you suggested, add an option to hide/show the ArchiMate icon.

Or just add the option to hide/show the ArchiMate icon and no auto-hide. Then if user wants both image + icon they can.

Phillipus commented 3 years ago

@jbsarrodie

I think there's been a misunderstanding here.

I thought that the idea was to re-purpose the Canvas image positioning code so that a user can set an image of any size in one of the nine positions. A small-sized image in the top-right position would then effectively be an icon replacement (case #1). But also, an image (of any size) could be positioned somewhere else (case #3). This has been the implementation in the branch icons for some time now. I thought this was what was agreed?

But it seems that you're saying that you want to just replace the small Draw2d icon in the existing top-right position with a small or scaled-down image at that exact x,y position? If so, then I have to go back to the drawing board and start again...

jbsarrodie commented 3 years ago

TL;DR: don't worry ;-)

Longer answer being written

Phillipus commented 3 years ago

Quick point - all of the image handling code is re-purposed from the current Canvas image handling of one "iconic" image per object. If more than one image is required per object (icon replacement and another icon image) then all of the image handling code will have to be re-written. 😨

jbsarrodie commented 3 years ago

Let's be clear about the terminology - "icon" is the little icon drawn in Draw2D code, I use "image" to mean a user image (png, jpg, etc) which can be any size (no scaling is done) and can be located in one of nine positions.

Ok, from now on I'll use the same terminolgy

Given the way images are located (one of nine positions) and given that the user image can be of any size, this might not always work.

Of course: My point is just that a user using a 16x16 image positioned top-right addresses #1.

So, now I'm not clear if you're proposing not using the image positioning code (as is used in Canvas objects) and instead something else that positions the image at one x,y position at top right?

Current implementation (which is the same as canvas object) is perfect!

do we want to use the nine-position IconicDelegate system of displaying images with their sizes as-is,

Yes we do !

maybe even allow multiple icons.

That would require rather a large change to the code! :-0

I know. That's why I wrote that this use-case can already be addressed through small notes (with icon, transparent borders and transparent fill) nested inside elements' figure (I already do this with icon fonts).

But what annoys me is that in some occasion, hiding should be automatic (if the custom icon is on top-right, we know almost for sure that the ArchiMate icon should be hidden).

It depends on the image and its size. User might have an image with enough white space or transparency to allow space for an icon. So I can see some cases where the auto-hide might not be wanted.

Yes, I though about it too.

Or just add the option to hide/show the ArchiMate icon and no auto-hide. Then if user wants both image + icon they can.

Not auto-hide, but option to hide/show plus something else...

My issue is this: the use-case we ultimately want to address at the end of our sprints is "automated #1" and comprises:

For this to work, we need 3 options which are dependent:

So you can first implement the "Show icon" option.

The last part ("Use stereotype's Image") obviously depends on having a stereotype attribute for concepts, and ability to set a name on images, so this is not the urgent part and we'll be able to discuss more about this if needed.

Phillipus commented 3 years ago

Ability to hide the icon. I'd suggest a "Show icon" checkbox (checked by default) like the "Show Label" we have on relationships

This is implemented now, and appears in the same Properties tab as setting the image. I think it makes sense to keep these items together as typically you'll want to hide the icon when adding an image manually (this will be automatic in other cases).

Image Placement

Images, when placed in one of the outer positions, are positioned at the edge of the figure, so any blank space in the image itself will determine its overall placement inside the figure. In the case of a stereotype I would think that a user would typically want a smallish image placed in the top-right roughly where the current icon is. However, the position of the image might not be exactly as wanted, so do we need to provide fine adjustment of image positioning? (See my comment above about using left, right, top and bottom offsets).

jbsarrodie commented 3 years ago

Images, when placed in one of the outer positions, are positioned at the edge of the figure, so any blank space in the image itself will determine its overall placement inside the figure. In the case of a stereotype I would think that a user would typically want a smallish image placed in the top-right roughly where the current icon is. However, the position of the image might not be exactly as wanted, so do we need to provide fine adjustment of image positioning? (See my comment above about using left, right, top and bottom offsets).

I don't think we need nor want fine adjustment. I'd prefer to have the image be placed in one of the nine position, but relative to a rectangle which is not always the bounding box of the figure but dependent on the overall shape (in red below): image

For some figures (Product and Artifact) it might be interesting to go one step further (but that's not MVP) and allow per position, hard coded offsets, so that (e.g.) top-right on Product would still be the extreme top-right, while top-left would be below the small horizontal line of Product figure.

What do you think?

Phillipus commented 3 years ago

What do you think?

Excellent idea! Thanks for those helpful diagrams. I think your idea makes sense and is, in fact, already implemented in the Group and Grouping figures:

if(type == 1) {
   getIconicDelegate().setTopOffset(0);
}
else {
   getIconicDelegate().setTopOffset(tabHeight);
}

So I'll see if it's possible to apply the same principle to the other figures. (Observation - this "pixel-shifting" code takes more time than it really should to implement 🤓 ).

I don't think we need nor want fine adjustment.

OK, but it's there in the code if we do need to expose it.

Phillipus commented 3 years ago

We could refine this by only adding the offset when there is a visual feature there. For example, the Artifact figure only really needs adjustment for the top-right position.

Image 1

Phillipus commented 3 years ago

We could refine this by only adding the offset when there is a visual feature there. For example, the Artifact figure only really needs adjustment for the top-right position.

Hmmm...depends on how big the figure and image is.

This is middle-right on a normal-sized figure:

dr

Phillipus commented 3 years ago

I just read this part (sorry I missed it!):

For some figures (Product and Artifact) it might be interesting to go one step further (but that's not MVP) and allow per position, hard coded offsets, so that (e.g.) top-right on Product would still be the extreme top-right, while top-left would be below the small horizontal line of Product figure.

This is what I was saying in the last two comments, but you said it first! 💡

But it does depend on the actual figure and image sizes as to whether it works or not.

Phillipus commented 3 years ago

@jbsarrodie I've spent more time experimenting with icon placement and tweaking the code. The icons branch simply places user icons in their nine absolute positions, and some of these, depending on the type of Figure need to have their positions adjusted.

So I've created a new branch, icons-offset-experiment, that makes adjustments depending on the Figure type and position. When you get time, please try these to see whether this works or not.

But to play devil's advocate again, I do wonder if users will want to make finer positioning adjustments? We could, if needed, expose the offset adjustment factors in the image properties tab.

However, I seem to have gotten bogged down in image positioning. ;-) So let's come back to that and move onto this...

Image Naming and Stereotype classes

From earlier:

This means that images should have a somewhat readable name, something we can reference and match to a stereotype name or any property value. This name can be the "internal" name of the image or an associated property.

Keep the current behavior, but dissociate image id and image name: internally, elements would reference the image id (which never changes and is the current image/hash.ext), but the "Images Manager" would make it possible to associate a name to images (default could be empty or equal to the id). This name would be what we manipulate through jArchi. This approach makes it possible to "rename" images without impacting views (because they in fact use the id).

I would choose the last option because it would also open the way to a clever behavior in which the icon automatically matches the stereotype name (if defined), and we do want this ultimately. Of course we could also add a way to define a mapping between stereotypes and icons, at model level.

So, where to store image names? The filename of an image and its position is referenced by each instance as follows:

<child xsi:type="archimate:DiagramObject" imagePath="images/_8tf3UBlQEeuRw8mw0SgOkA.png" imagePosition="4">

So we need one place to store the readable name, and this also has to remain in sync with the actual image file and its name - if an image is not used it is not saved in the *.archimate file so its name should also not be saved. Is the Image name stored in a Stereotype eCore class?

jbsarrodie commented 3 years ago

@Phillipus I've seen your comment. I'll answer later today or tomorrow at last.

Edit: I'm a bit late on this. Working on it now....

jbsarrodie commented 3 years ago

Long term goal

Before defining our MVP, we have to set the long term goal:

In ArchiMate we have two related notions:

So a long term goal could be to support profiles this way:

Add a "Profiles & Stereotypes Manager" menu entry under "Tools" which would open a dialog very similar to "Properties Manager":

image

This dialog would allow the user to add/edit profiles.

When creating a new one, this would lead to this dialog:

image

From here it is possible to name the profile, bound it to a specific concept type and set it as a stereotype which then allows to set an image. It is also possible to define the properties included in the profile together with their default value (if any).

MVP (proposal)

As we want to focus on stereotypes for the moment, we could create those two dialogs, with some differences:

Leading to:

image

Other remarks and answers (sort of)

So, where to store image names?

With this approach, setting a name on images is no more needed because we explicitely link images to stereotypes, which is our ultimate goal. Of course, for other use cases (using images outside of stereotype) scripting will be less easy, but I'd consider this out of scope for the moment.

if an image is not used it is not saved in the *.archimate file

For this we would have to make sure that an image is not saved if it is not used in a view and not used in a stereotype definition.

I see that other tools allow you to define a Stereotype for a given ArchiMate concept and associate an image to it. Where in the UI do we expose the Stereotypes?

This is addressed by the dialogs detailed before

How is a Stereotype stored in the eCore model? Is it a new class? Can we store the image name there? What other Stereotype info is stored?

Could this be done in a way similar to model features and properties, i.e. by attaching a ProfilesEList (or maybe just an EList) containing multiple Profile to the model element itself ?

Profile would then :

Is this referenced from concepts that are stereotypes? If so we need to keep them in sync if a Stereotype is updated or deleted.

I'd say yes, concepts would have a reference to the profile object and must be in sync. But has profiles/stereotypes would be edited in a modal dialog, maybe this makes it easier to force a refresh of views, labels... when an existing one is edited/renamed...

jbsarrodie commented 3 years ago

@Phillipus any update on this or code that I could test/provide feedback on?

Phillipus commented 3 years ago

@Phillipus any update on this or code that I could test/provide feedback on?

Still working on some experiments. Coming soon...

Phillipus commented 3 years ago

I feel we should avoid using the word "Stereotype" in Archi's implementation and instead use "Specialization".

  1. The ArchiMate spec makes the difference clear (https://pubs.opengroup.org/architecture/archimate31-doc/chap15.html#_Toc10045466)
  2. Herve uses the term in his plug-in
  3. To make it clear that this is not a UML type thing

(I've had several emails from people who want to create brand new concepts in the ArchiMate metamodel, and I have to disabuse them of this idea.)

jbsarrodie commented 3 years ago

I feel we should avoid using the word "Stereotype" in Archi's implementation and instead use "Specialization".

I agree. "Stereotype" has never been the real name of this mecanism in the standard, but was only used as an illustration (to help people understand what it is). Recent dicussions related to this topic for the exchange file format go in the same direction: let's don't use the word "stereotype".

So we should use "Is specialization" instead of "Is stereotype" (and in other places).

I've had several emails from people who want to create brand new concepts in the ArchiMate metamodel, and I have to disabuse them of this idea.

For the record: even in UML one can't create "brand new concepts" out of nowhere: they have to stereotype existing concepts.

Phillipus commented 3 years ago

Given that a user defines Profiles in the dialog and these are stored as a collection of Profiles at the root model node how is a Profile then used and referenced?

(BTW - I'm not doing the MVP. I'm going for the full thing with Properties)

Phillipus commented 3 years ago

I notice that another tool allows multiple Stereotypes. I guess we're not going to allow this (for multiple Profiles/Specializations)?

i.e. Once a Profile is set for a concept do we disallow setting more Profiles for the same concept?

jbsarrodie commented 3 years ago

BTW - I'm not doing the MVP. I'm going for the full thing with Properties

Ok, you've been warned (and you can change your mind if this proved to be too complicated/long)

I notice that another tool allows multiple Stereotypes. I guess we're not going to allow this (for multiple Profiles/Specializations)? i.e. Once a Profile is set for a concept do we disallow setting more Profiles for the same concept?

ArchiMate standard is not fullly clear on this. My (practical) interpretation is that there can be multiple profiles assigned to a concept (clearly stated in the specs), but only one leading to a concept specialization (ie, with isSpecialization flag set). This last part is not explicitely enforced in the spec but would lead to several issues otherwise (you can't set two different notation at the same time)

How does a user apply the Profile to a Concept instance? Does the user link an existing concept instance to a Profile (via the Profile's ID) perhaps in the concept's Properties tab?

Good question and I have no good answer. For "simple" profiles (ie. not Specialization), this could be done through the Properties tab (as you suggested) with a new button in the right part (where we have "New", "New multiple", "Remove" and "Manage"). For "specialization" profile, I think it would be more intuitive in the "Main" tab with a new entry on the first row: Specialization: [drop-down-list-with-none-as-default]. In both cases, I think the internal way to link concept instance and profile should be the same (should make it easier when un-setting the "isSpecialization" flag on profile definition).

I'm not clear on what happens with the Properties in the Profile. Are these added to the Concept's Properties list when the Profile is applied to the concept?

Profiles' properties (from "simples" and "specialization" profiles) should appear in the main "Properties" tab once set. In this aspect, a profile can be seen as a kind of namespace, so I think adding a "Profile" column on the left of the "Name" column should be enough to distinguish normal properties from properties created through a profile.

This is not trivial and means that the way properties are managed should change:

If so how do we keep them in sync?

Let's assume that:

Then, we can keep them in sync by running a small job whenever the user decide to change the profile definition by adding, renaming or deleting properties:

Of course, we could have an option in the validator to check the coherence of profile definitions and concepts (just in case...)

What happens if a Concept is linked to a Profile and the Profile is changed? Perhaps the "isSpecialization" setting is set or unset.

That's a more complex one which involves two parts:

Each time the concept is added to a View do we set the object's icon to that in the Profile?

Only if "Use stereotypes' images by default" is enabled in the preferences.

This is related to a previous comment in which I wrote:

  • There's a new option inside Preferences > Default Figures, named "Use ~stereotypes~ specializations' images by default"
  • When this option is enabled, each time an element is added to a view, it should be set in a state in which, ~if a stereotype is set, and an image exist with the same name~ if a specialization profile is set and this profile defines a custom image, then this image is used instead of the icon. Of course, like for any other visual attribute, the user could change this attribute and use another image (or no image) and/or decide to show the icon.

For this to work, we need 3 options which are dependent:

  • Ability to set an image and its position (between the nine): this is what we have now.
  • Ability to hide the icon. I'd suggest a "Show icon" checkbox (checked by default) like the "Show Label" we have on relationships
  • Ability to link image and ~stereotype~ specialization. I'd suggest a "Use ~stereotype~ specialization's Image" checkbox on "Appearance" tab. The default state being the one of the "Use ~stereotype~ specialization' images by default" preference option. When enabled, options to set an image, image position and hide the icon are disabled.

Can a user create multiple Profiles to the same concept type?

Yes, for example, Artifact can be used to define DB File Profile, Executable Profile...

Phillipus commented 3 years ago

BTW - I'm not doing the MVP. I'm going for the full thing with Properties

Ok, you've been warned (and you can change your mind if this prooved to be too complicated/long)

Yep, I've changed my mind. The Properties thing is more complicated than I thought.

jbsarrodie commented 3 years ago

Yep, I've changed my mind. The Properties thing is more complicated than I thought.

At least, we now have a better visioin of what could be the full target and the challenges involved. So this should help us do the right choices for the MVP.

Phillipus commented 3 years ago

ArchiMate standard is not fullly clear on this. My (practical) interpretation is that there can be multiple profiles assigned to a concept (clearly stated in the specs), but only one leading to a concept specialization (ie, with isSpecialization flag set). This last part is not explicitely enforced in the spec but would lead to several issues otherwise (you can't set two different notation at the same time)

Therefore there are two "types" of Profile:

  1. A set of Properties ("simple")
  2. A Specialization which includes (1), has a mandatory ArchiMate type, and an optional icon

Should we allow a Concept to reference multiple type (1) and only one type (2)?

If so, it becomes a bit harder to manage.

Creating the eCore model a Concept can reference either 0...1 Profiles or 0...many Profiles. If a Concept can reference 0...many Profiles then there will be places in the code where we have to find the one where isSpecialization is set to true. Or we can have 0...1 reference to a Specialization type and 0...many to simple types.

Phillipus commented 3 years ago

But if one can have a Specialization without a set of Properties then we could separate out the two things with two eCore classes:

  1. Specialization - contains name, restricted Class type, and icon.
  2. Profile - contains Properties

Then a Concept can have 0...1 reference to (1) and 0...many references to (2).

Of course this is for internal eCore. We can enforce that a Concept has at least one type (2) if (1) is set.

Question - what makes a concept a Specialization? Is it that it has a set of Properties or simply that we say it is a Specialization?

Spec says:

Specialization of concepts is done by using the profile mechanism described in Section 15.1. The name of the profile is the name of the specialization, and it may have other attributes if relevant to the specialization. The specialized concept is modeled by assigning such a profile to the generalized concept.

But surely you can make a Specialization without a set of Properties (Profile)?

jbsarrodie commented 3 years ago

First, a remark: Standard is in fact very clear and states that:

Note that multiple specialization profiles may be assigned to the same generalized concept; in the default notation, these are shown as a comma-separated list (“«specialization 1, specialization 2»”).

This only leads to issue when one decide to use (for tools allowing it) a custom notation, because (obviously) it then becomes impossible to have two different notation at the same time for the same concept instance in a view.

Therefore there are two "types" of Profile:

  1. A set of Properties ("simple")
  2. A Specialization which includes (1), has a mandatory ArchiMate type, and an optional icon

Yes.

For the sake of the discussion, let's define this convention:

If having the restriction on concept being optional in IProfile and mandatory in ISpecializationProfile leads to complication, then we can remove it from IProfile.

Should we allow a Concept to reference multiple type (1) and only one type (2)?

Yes and no :-)

What we want to avoid is ambiguity on which image to show when specialization is used. So the real constraint is not to have only one type (2) but just to make sure we that if we have several of them, we can deterministically find the primary specialization that will drive the custom notation.

If a Concept can reference 0...many Profiles then there will be places in the code where we have to find the one where isSpecialization is set to true. Or we can have 0...1 reference to a Specialization type and 0...many to simple types.

There are two possible approaches:

  1. Allow 0..many IProfile (thus including SpecializationProfile) in an IProfileList attribute on each concept instances
    • This is fully compliant with ArchiMate
    • Makes it easy to find all profiles (only one list)
    • Makes it possible to find all specializations (IProfileList#getSpecializationProfiles()) which could be useful from jArchi for analysis purposes or inside labels (think specializations label expression, note: plural). It's a filtered list
    • Makes it possible to get the primary specialization (IProfileList#getPrimarySpecializationProfile()) which is the one that will be used to get the image from (and could be used through a specialization label expression). I call this the implicit specialization, i.e. user simply defines profiles without having to care about their exact type (specialization or not). A very simple implementation is to have IProfileList#getPrimarySpecializationProfile() implemented as IProfileList#getSpecializationProfiles().get(0)
  2. Allow 0..many IProfile (thus including SpecializationProfile) in an profileList attribute, and only one IProfileSpecialization in another specialization attribute
    • This is still mostly compliant with ArchiMate
    • Makes it harder to list all profiles (requires to concat a list and another attribute)
    • Makes it harder (more code to write) to find all specializations
    • Makes it easier to find the main specialization. I call this the explicit specialization, i.e. the user explicitely define what specialization he uses (other specialization profiles are found as part of the profile list)

I have the feeling (1) is easier to implement and manage but I might be false.

But if one can have a Specialization without a set of Properties then we could separate out the two things with two eCore classes

Of course one can define a profile with no properties in it, but in this case it should only make sens if it is a specialization (no added value otherwise).

But surely you can make a Specialization without a set of Properties (Profile)?

Yes

what makes a concept a Specialization? Is it that it has a set of Properties or simply that we say it is a Specialization?

For me, it's just that we say it is a specialization

Then a Concept can have 0...1 reference to (1) and 0...many references to (2). Of course this is for internal eCore. We can enforce that a Concept has at least one type (2) if (1) is set.

This is of course possible, but I don't find it "elegant". Maybe this gets simplified if (as written in the beginning of this comment) we simply have a big list of IProfile from which we extract needed information.

Phillipus commented 3 years ago

For me, it's just that we say it is a specialization

That's why I'm not convinced by the linking of a Specialization with a "Profile".

The spec defines a Profile as a set of Attributes ("Properties" in Archi). OK. But I don't see how applying a set of attributes to a concept makes it a "Specialization". Surely I should just be able to denote that a particular concept is a Specialization of Business Actor called "Cat", and it doesn't require any additional attributes?

jbsarrodie commented 3 years ago

That's why I'm not convinced by the linking of a Specialization with a "Profile".

Specs are not perfectly clear and provides room for interpretation. This should be fixed as part of the next minor release of Archimate. Nonetheless, it provides the following definitions:

My interpretation is that a Specialization Profile is a (potentially "empty") Profile flagged as a such (thus the use of Specialization Profile in the spec and the mention of The name of the profile is the name of the specialization). But another interpretation could be that Specialization is define per se (with its restriction on concepts and image) and might be linked with a Profile defined on its own. The only limitation of this approach is that name of specialization and profile must be synced.

So...

Surely I should just be able to denote that a particular concept is a Specialization of Business Actor called "Cat", and it doesn't require any additional attributes?

Yes

Phillipus commented 3 years ago

A (MVP) Specializations Manager is in branch specialization.

As the Specializations Manager is a modal dialog you can access all things from here rather than opening a sub-dialog. Images are not allowed for relations and junctions.

spec manager

jbsarrodie commented 3 years ago

I'm testing it ASAP...

jbsarrodie commented 3 years ago

I've finally been able to test (thank you eclipse...).

Not much to say, except that at some point we'll have to make sure that definitions of specializations are taken into account when merging a model into another model (or else we might import elements which are linked to non existent specializations and images)

Phillipus commented 3 years ago

Next stage is deciding how/where to apply Profiles to a Concept and to display image and text in Views.

Because we can have more than one Profile for a Concept type we need to show the multiple Profiles on a Concept instance's main tab and keep them synchronized when they are edited or deleted.

Do we want to allow user to apply more than one Specialization Profile to a concept instance at this stage? That is the goal, but as we don't have Properties in the Profile now would it make sense to do so now? We can only display one image. But we could display more than one Specialization Profile name...

...How will we display the Specialization Profile names? Is this part of Label Expressions? Perhaps something like $profile{name}? But if more than one, how to show each one?

jbsarrodie commented 3 years ago

Do we want to allow user to apply more than one Specialization Profile to a concept instance at this stage? That is the goal, but as we don't have Properties in the Profile now would it make sense to do so now?

That could be useful in some rare occasions but could be ignored for the moment.

Next stage is deciding how/where to apply Profiles to a Concept and to display image and text in Views. Because we can have more than one Profile for a Concept type we need to show the multiple Profiles on a Concept instance's main tab and keep them synchronized when they are edited or deleted.

We're back at this discussion:

If a Concept can reference 0...many Profiles then there will be places in the code where we have to find the one where isSpecialization is set to true. Or we can have 0...1 reference to a Specialization type and 0...many to simple types.

There are two possible approaches:

  1. Allow 0..many IProfile (thus including SpecializationProfile) in an IProfileList attribute on each concept instances
    • This is fully compliant with ArchiMate
    • Makes it easy to find all profiles (only one list)
    • Makes it possible to find all specializations (IProfileList#getSpecializationProfiles()) which could be useful from jArchi for analysis purposes or inside labels (think specializations label expression, note: plural). It's a filtered list
    • Makes it possible to get the primary specialization (IProfileList#getPrimarySpecializationProfile()) which is the one that will be used to get the image from (and could be used through a specialization label expression). I call this the implicit specialization, i.e. user simply defines profiles without having to care about their exact type (specialization or not). A very simple implementation is to have IProfileList#getPrimarySpecializationProfile() implemented as IProfileList#getSpecializationProfiles().get(0)
  2. Allow 0..many IProfile (thus including SpecializationProfile) in an profileList attribute, and only one IProfileSpecialization in another specialization attribute
    • This is still mostly compliant with ArchiMate
    • Makes it harder to list all profiles (requires to concat a list and another attribute)
    • Makes it harder (more code to write) to find all specializations
    • Makes it easier to find the main specialization. I call this the explicit specialization, i.e. the user explicitely define what specialization he uses (other specialization profiles are found as part of the profile list)

I have the feeling (1) is easier to implement and manage but I might be false.

I tend to (only slightly) prefer the list approach, but this requires to be able to reorder the list in the UI because we want the first one to be the main one.

But if you think it's easy enough to have an attribute for the main specialization and a list of all assigned profiles (including specializations) and keep them in sync (ie. make sure to add/remove the main specialization to/from the list when the user un-set it), then we could start with only the main specialization in a list widget on top of the Name field (like Viewpoint in views).

We can only display one image. But we could display more than one Specialization Profile name... ...How will we display the Specialization Profile names? Is this part of Label Expressions?

For me:

Perhaps something like $profile{name} ? But if more than one, how to show each one?

I don't think having a $profile prefix makes sense because there's no need to reference the profiles themselves, we only want to know their names but are still refering to the concept itself, not the profiles.

Phillipus commented 3 years ago

The main development branch for this is now specialization. It was icons but that branch is deleted now as specialization supersedes it.

jbsarrodie commented 3 years ago

Hi Phil,

I did some test of latest specialization branch and that seems very good. The automatic usage of specialization's image is really nice and save lots of time. I have some comments though:

"Read Below" Section ;-)

I consider that we have two different use-cases involving images:

  1. Custom images added to a figure on a per view basis (let's call it "Custom image")
  2. Custom images inherited from the specialization (let's call it "Specialization image)

The first one (Custom Image) is just a mean for users to change the visual aspects without been restricted in any way by the underlying model. So if they want to show a picture of their cat, or a screenshot of Google Map, they can do it. User has full control of position (to be chosen between the 9 choices) and to whether or not show the ArchiMate Icon. That's a purely visual thing.

The second one (Specialization Image) is a mean for users to define a custom rendering for their "custom" types (ie. specializations). So this image should be seen (by default) on all concepts of the same specialization. This should allow users to somewhat define their own concepts and notation (based on existing native concepts and default figures).

So the question is: In which position do we show the specialization image? How does this affect native ArchiMate icon?

There's no right or wrong answer to this, and there's always some tradeoff. Here are some possible answers:

My personnal opinion is to keep it simple and to use the "Specialization Icon" paradigm and use the image as a (small) icon to show next to or in place of the ArchiMate Icon. The only issue or limitation I can see is that user might then expect to be able to set a specalization icon *and a custom image.

jbsarrodie commented 3 years ago

Hi Phil,

Thank you for our discussion last week, this helped me to better understand and explain what I think should be the best option.

First things first. To better understand the target for specialization, people have to understand what it's not:

Specialization is not a visual thing nor a mean to easily tune the way elements look in a view Specialization is only a way to define custom concepts based on real ArchiMate concepts. Of course, Archi being compliant with ArchiMate default notation, Archi's implementation for specialization should provide a way to slightly adapt such default notation by overriding the ArchiMate icon and using an specialization icon instead, in the same location (top-right corner). Nothing more!

Providing more visual customization based on specialization would no more be specialization but "styles" I've finally put a word on one of the feature I'm looking at: styles. I do think that several users would like to be able to define custom styles, i.e. a named set of visual attributes that could be defined centrally and dynamically applied on a concept instance in a view, or maybe inherited from the specialization. Styles are dynamic: when changing a style, all elements using it are rendered using the new visual settings. That would be a great feature for Archi, but this is absolutely not in the scope of this feature, so instead of trying to provide a bad, partial, hacky implementation working only for specialization, I prefer making sure everything related to "styles" is postponed. Why? because it makes it easier for people to understand what to expect from Archi and makes the border between features as clear as possible. And, btw, there are workarounds for styles through toolboxes or jArchi scripts.

Styles versus Defaults It is also important to explain the difference between styles and defaults. In Archi, defaults are default values used when elements or visual objects are first created. Once created, there is no more a link between those centrally defined defaults and elements or visual objects, ie. they are not dynamic. This is especially important for visual objects because if they were dynamic, there would be a high risk that changing defaults in preferences (or simply opening a model on someone else computer with different defaults) would lead to issues in views (color or font differences for exemple). I must admit that Archi is not alway consistent in this aspect (and because it used to be hard for me to understand this difference, I'm responsible for some of those inconsistencies):

So what do we do with specialization?

My personnal opinion is to keep it simple and to use the "Specialization Icon" paradigm and use the image as a (small) icon to show next to or in place of the ArchiMate Icon. The only issue or limitation I can see is that user might then expect to be able to set a specalization icon *and a custom image.

As said just before in this comment, we should limit ourselves to supporting only a custom specialization icon used instead of the ArchiMate one, on the top-right corner. In order to manage expectation and making it clear that it won't be possible to set both a specialization icon and a custom image, I suggest the following for the "Image" properties' tab:

With these options and these defaults, adding a new element in a view and later change its specialization makes the specialization icon visible instead of the ArchiMate one. Of course, people are free to customize it further and change the position, the image....

Phillipus commented 3 years ago

@jbsarrodie just a heads up: I rebased the specialization branch onto the latest master branch as I need it to be ahead of some of the changes in master.

Phillipus commented 3 years ago

Start with Show ArchiMate Icon option with three choices: Always, If no image defined (that's the default), or Never

I've implemented this now and it seems to work as expected

Then Use specialization Image option (simple check box, enabled by default) Then Position with top-right being the default.

OK. These two are already working.

Then Image which (if possible) should be grayed/disabled when Use specialization Image is enabled

Working on it. Should be possible.

Then Preview, which (if possible) would show the specialization image if defined and used.

Now we have a problem with this...

The Preview square is designed to only show the user image defined for the object (if any). Double-clicking on it also allows to set the image (same behaviour as the Image "Choose..." button). It was originally designed for Canvas images, and has been re-purposed here and so is limited to showing the image as set in image path for the object.

It might be possible to support this, but it would require a lot of refactoring to do so. Alternatively we could remove the Preview square as you able to see the image anyway in the diagram.

Phillipus commented 3 years ago

(Updated the last comment since it is possible to disable/enable the Image button)

Also, I'll take a closer look at the Preview square to see how hard it would be to change.

jbsarrodie commented 3 years ago

Also, I'll take a closer look at the Preview square to see how hard it would be to change.

Not really needed, this was just an idea based on user experience, but nothing mandatory. And Btw, that's questionable because if you did select a custom image before setting the stereotype it would also make sense to see it, so in short: keep it as it is ;-)

Maybe we could just rename Image to Custom Image, and Preview to Custom Image Preview. Should be enough to distinguish it from "specialization image".

Update: I'll test your changes tomorrow

Phillipus commented 3 years ago

It turns out I can enable/disable the Image button and set the Image Preview to the Specialization image if set. It depends whether we want to do that or use your last suggestion of renaming the controls to "Custom..."

Archi's implementation for specialization should provide a way to slightly adapt such default notation by overriding the ArchiMate icon and using an specialization icon instead, in the same location (top-right corner).

The Image Position applies to both the custom image and the profile image, so toggling the "Use Specialization Image" button will use the same Image Position as set in the combo. This is because it is getting the image position setting from the diagram object.

jbsarrodie commented 3 years ago

It turns out I can enable/disable the Image button and set the Image Preview to the Specialization image if set. It depends whether we want to do that or use your last suggestion of renaming the controls to "Custom..."

I think I prefer renaming the controls. What's your opinion on this ?

The Image Position applies to both the custom image and the profile image, so toggling the "Use Specialization Image" button will use the same Image Position as set in the combo. This is because it is getting the image position setting from the diagram object.

Yes, this quote was about the overall goal. The new configuration with its default setting has a similar end result. Of course if someone add a non specialized concept to a view, set an image and a custom position and only then set a specialization, of course the image defined in the specialization will be used but in the custom position. There's no magic ;-)

Phillipus commented 3 years ago

I think I prefer renaming the controls. What's your opinion on this ?

I think it might be confusing to disable the "Image" button because the user has to figure out that it is enabled only if "Use specialization Image" is unchecked. However, I do like to see the Preview image of the current image whether that's the Profile image or the custom image. But I'm not really sure either. I've pushed a temporary branch working where this is implemented if you want to try it.

Phillipus commented 3 years ago

Given this case:

Then the custom image is shown even though the "Use Specialization Image" option is checked

Do we want to show no image in this case? Or leave as is and show the custom image instead?