jArchi view.add bug?

Started by steverumsby, May 31, 2019, 10:33:13 AM

Previous topic - Next topic

steverumsby

[Posting here to check if this is a misunderstanding on my part, or a bug. Will post to GitHub issue tracker if ut turns out to be a bug!]

I'm writing a script to copy a view. The main part of it looks like this ("view" is the view to be copied):


var newView = model.createArchimateView(view.name + " copy");

$(view).children().forEach(function (c) {
    if(c.type.indexOf("-relationship") > -1) {
        newView.add(c.concept, c.source, c.target);
    } else {
        var bounds = c.bounds;

        newView.add(c.concept, bounds.x, bounds.y, bounds.width, bounds.height);
    }
});


This mostly does what I expect. A new view is created. All the elements are added in the new view in the same positions as in the old view. So far, so good. But, the relationships are added in the original (currently selected) view rather than in the new copy. Am I misunderstanding something?

Thanks,
Steve.

Phil Beauvoir

May 31, 2019, 11:14:26 AM #1 Last Edit: May 31, 2019, 12:11:27 PM by Phil Beauvoir
Hi Steve,

I just checked this and the answer is "both".

In your snippet variable "c" is a diagram component that is a child of the original view. When you have a connection (has "-relationship" in the type) "c.source" and "c.target" are the diagram components of the original view not the copied view.

jArchi should check whether "c.source" and "c.target" are indeed members of the correct view and I'll add a check for this in the next version.

As for your code snippet, using "c.concept" is correct but what you need to do is get the copied "c.source" and "c.target" from the newly created View. Not sure exactly the best way to do this, but might involve adding the elements first, and then adding the connections afterwards.

If the aim is to create a copy of a View, this might be something that we could add to the API at some point.

Phil
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate

steverumsby

So view.add is adding the relationship between the source and target in their view, even when that's not the view object add was called on. I can see why that would happen, and yes, a check to prevent that would make sense. Thanks. Do you want a Github issue for this?

The simplest thing that immediately occurs to me is, as you say, to add the elements first and maintain a map from the original "c" to the copy (return value from view.add), and then add the relationships, mapping c.source and c.target. That sounds like it would work? Is there a simpler way?

Yes, I am trying to copy a view from a script. More specifically I want to make multiple copies of the same view, which I will then format differently based on properties of the elements. I have a master view of an architecture and several departments that use different subsets of that architecture, with the departments listed as properties of the elements. I want a script that produces subset diagrams for the departments (in the subsets, the unused elements have the background set to white so the whole architecture is visible but the used subset very obvious).

An API to copy a view would certainly be nice, but if the above works OK I wouldn't give it high priority. I'll post it as a gist once it works!

Steve.

Phil Beauvoir

No need for GH issue as I've already submitted a fix.

You'll need to track what boxes get added to the new view and then add the connections.

I'll take a look at implementing view.copy() as API.
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate

steverumsby

This works just fine, so long as there are no objects nested visually inside other objects:

var newView = model.createArchimateView(view.name + " copy");
var map = [];

$(view).children().forEach(function (c) {
    if(c.type.indexOf("-relationship") > -1) {
        newView.add(c.concept, map[c.source], map[c.target]);
    } else {
        var bounds = c.bounds;

        map[c] = newView.add(c.concept, bounds.x, bounds.y, bounds.width, bounds.height);
    }
});


In all of my views, children() seems to produce the elements first and the relationships afterwards, so the map[] is complete before I need to use it. I don't know if that is guaranteed, but I should probably add an appropriate sort in there, just to be sure.

But the particular view I'm building this for has elements visually nested inside other elements, and getting that to work is too much for my brain on a Friday afternoon:) Something odd is happening with notes and their connections to elements, too. I'll return to it on Monday.

view.copy() would be very nice...  :D

Thanks,
Steve.

steverumsby

Small follow-on question - how to I get the text from a note object? I'm obviously missing something obvious - I really need to stop writing code late on a Friday  :D

Steve.

Phil Beauvoir

var text = note.text;

or

var text = note.getText();

I've added this to the wiki now.
If you value and use Archi please consider making a donation! https://www.archimatetool.com/donate