Hi,
Created a simple script to make a copy of an existing view. It works voor elements, but when I copy the relationships, the scripts crashes with a type-error on linenumber 43.
selection.filter("view").each(function(view) {
var viw = model.createArchimateView(view.name+"_copy");
viw.documentation = view.documentation;
viw.viewpoint = "layered";
console.log("Added view - ", view.model, view.name, view.documentation);
// add visual elements
const visuals = $(view).find('element'); // This gets the list of visual objects on view
for(var ve = 0; ve < visuals.length; ve++) {
var obj=visuals[ve].concept;
var x = visuals[ve].bounds.x;
var y = visuals[ve].bounds.y;
var width = visuals[ve].bounds.width;
var height = visuals[ve].bounds.height;
viw.add(obj, x, y, width, height);
console.log( obj, x, y, width, height);
};
// add visual relationships
const visualrels = $(view).find('relationship'); // This gets the list of visual relations on view
for(var vr = 0; vr < visualrels.length; vr++) {
var rel = visualrels[vr].concept
var obj1 = visualrels[vr].concept.source; //its source
var obj2 = visualrels[vr].concept.target; //its target
viw.add(rel, obj1, obj2);
};
});
I believe I did exactly the same as the example-script Create Views and Visual Objects, more general. What am I doing wrong?
Thanks, Gerald
Hi,
obj1 and obj2 must be visual objects, not model concepts ;-)
(that's because the same model concept can appear several time in a same view)
Regards,
JB
Thanks JB for the swift response. Appreciate it very much.
I took this approach: storing the id's of original visual elements and their copy in the array pairs and using array.find to lookup the visual elements on the new view copy. I believe obj1 and obj2 are visuals elements now.
However, the result is unchanged, I find the same error.
// Show output in the console
console.show();
console.clear()
console.log("> Starting copy");
selection.filter("view").each(function(view) {
var viw = model.createArchimateView(view.name+"_copy");
// array for storing id of original and copy in pairs.
const pairs = [] ;
// add visual elements
const visuals = $(view).find('element'); // This gets the list of visual objects on original view
for(var ve = 0; ve < visuals.length; ve++) {
var obj=visuals[ve].concept;
var x = visuals[ve].bounds.x;
var y = visuals[ve].bounds.y;
var width = visuals[ve].bounds.width;
var height = visuals[ve].bounds.height;
obj_copy=viw.add(obj, x, y, width, height);
console.log( obj, x, y, width, height);
pairs.push( {orig: visuals[ve].id,copy: obj_copy.id});
};
for(var i = 0; i < pairs.length; i++) {
console.log (pairs[i]);
}
// add visual relationships
const visualrels = $(view).find('relationship'); // This gets the list of visual relations on original view
for(var vr = 0; vr < visualrels.length; vr++) {
var rel = visualrels[vr].concept;
let src_id = pairs.find(src_id => src_id.orig === visualrels[vr].source.id); //its source - id (visual)
let tar_id = pairs.find(tar_id => tar_id.orig === visualrels[vr].target.id); //its target - id (visual)
console.log (rel, src_id.copy, tar_id.copy);
let obj1 = $("#"+src_id.copy); // find the visual element with id
let obj2 = $("#"+tar_id.copy); // find the visual element with id
console.log (rel, obj1, obj2);
var connection=viw.add(rel, obj1, obj2);
};
});
Again, any suggestions?
Thanks, Gerald
Hi,
You can't find visual objects by #id. Your 'Pairs' list should point to objects, not ids.
So:
pairs.push( {orig: visuals[ve].id,copy: obj_copy.id});
should become:
pairs.push( {orig: visuals[ve].id,copy: obj_copy});
And change the second part accordingly.
Btw, it is usually easier to declare pairs as an object and use the id of the source visual object as key:
pairs[visuals[ve].id] = obj_copy;
So (with other small changes) your code becomes:
// Show output in the console
console.show();
console.clear()
console.log("> Starting copy");
selection.filter("view").each(function(view) {
var viw = model.createArchimateView(view.name+"_copy");
// array for storing id of original and copy in pairs.
var pairs = {} ;
// add visual elements
$(view).find('element').each(function(ve) {
var obj=ve.concept;
var bounds = ve.bounds;
obj_copy=viw.add(obj, bounds.x, bounds.y, bounds.width, bounds.height);
console.log( obj, bounds.x, bounds.y, bounds.width, bounds.height);
pairs[ve.id] = obj_copy;
});
console.log (pairs);
// add visual relationships
$(view).find('relationship').each(function(vr) {
var rel = vr.concept;
var connection=viw.add(rel, pairs[vr.source.id], pairs[vr.target.id]);
});
});
Next challenges for you: manager relationships to relationships, and bendpoints :-)
Regards,
JB
Many thanks. I am going to use this tomorrow. I'll get back.
Gerald
It works. You have improved my code a lot.
Quote from: Gerald Groot Roessink on November 28, 2022, 09:29:15 AMIt works. You have improved my code a lot.
Hi Gerald,
I'm looking for something similar. Any chance you can share your work?
Kind regards,
Michael
Hi Michael,
This is the script I am using to make an copy of an existing view. It is basic. Not all properties of visual objects are copied but can be added.
Good luck.
Gerald
/*
* Copy a View
*
* Copy visual elements and relations from the original view to a newly created view
*
* (c) 2022 Archi community
*
* This work is licensed under the HUMANS Licence described below.
*
* The HUMANS (Help Us Make Archi Noteworthy & Sustainable) licence goal is to bring happiness
* to both Archi users and developers.
*
* The only restrictions that apply are:
* - You can't redistribute this script.
* - You can't use this script for commercial purposes
*
*/
// Show output in the console
console.show();
console.clear();
var select=false;
selection.filter("view").each(function(view) {
var view_copy = model.createArchimateView(view.name+"_copy");
view_copy.documentation = view.documentation;
view_copy.viewpoint = "layered";
console.log("Copied view - ", view.name, " --> ", view_copy.name);
// Copy properties belonging to view.
for(var j = 0; j < $(view).prop().length; j++) {
var key = $(view).prop()[j];
var val = $(view).prop($(view).prop()[j]);
view_copy.prop(key, val );
};
// add objects like grouping
// note: it should also apply to notes but that isn't working
var obj_copy = {} ;
$(view).find('object').each(function(vo) {
var obj=vo.concept;
var bounds = vo.bounds;
//calculate the absolute xy coordinates of nested elements.
var x=bounds.x;
var y=bounds.y;
$(vo).parents().not('folder').not('archimate-diagram-model').each(function(mum){
x=x+mum.bounds.x;
y=y+mum.bounds.y;
});
//declare copy of visual as an object and use the id of the source visual object as key
obj_copy[vo.id]=view_copy.createObject(obj, x, y, bounds.width, bounds.height, "true"); //autoNest=true
// if need be: add other attributes
});
// add visual elements
var obj_copy = {} ;
$(view).find('element').each(function(ve) {
var obj=ve.concept;
var bounds = ve.bounds;
//calculate the absolute xy coordinates of nested elements.
var x=bounds.x;
var y=bounds.y;
$(ve).parents().not('folder').not('archimate-diagram-model').each(function(mum){
x=x+mum.bounds.x;
y=y+mum.bounds.y;
});
//declare copy of visual as an object and use the id of the source visual object as key
obj_copy[ve.id]=view_copy.add(obj, x, y, bounds.width, bounds.height, "true"); //autoNest=true
// if need be: add other attributes
});
// add visual relationships
$(view).find('relationship').each(function(vr) {
var rel = vr.concept;
var connection=view_copy.add(rel, obj_copy[vr.source.id], obj_copy[vr.target.id]);
// bending of relations.
var bendpoints = vr.getRelativeBendpoints();
for(var k = 0; k < bendpoints.length; k++) {
connection.addRelativeBendpoint(bendpoints[k],k)
};
// if need be: add other attributes
// may be later: relationship to relationship
});
select=true;
});
if(!select) {
console.log("Nothing to be copied. Please select a view");
}