Author Topic: MDG - Calculating a tagged value from other tags  (Read 676 times)

tjlindsay

  • EA User
  • **
  • Posts: 21
  • Karma: +2/-0
    • View Profile
MDG - Calculating a tagged value from other tags
« on: June 30, 2017, 04:28:45 pm »

Hi all,


[size=78%]Business problem - I've created my own MDG profile which extends the ArchiMate 3 language to include tagged values.  One of the elements extended is 'Capability'.  A capability has different maturity levels across the organisation ranging from 0-5.  I have 3 business units within the organisation.  Each business unit differs in maturity for a given capability.  Unit A has a maturity of 3, unit B is 2 and unit C is 4.  These are all recorded as separate tagged values.[/size]


[/size][size=78%]For executive reporting and decision making I want to be able to report on the lowest maturity level.  Is it possible to create a tagged value in my MDG which calculates the lowest number across all three business units please?  If so, what is the best way to make it work?  Script?[/size]


I can then use the filter option for reporting purposes.


Any help / guidance would be greatly received.


TJ.

Sunshine

  • EA User
  • **
  • Posts: 500
  • Karma: +33/-1
  • Amicorum omnia communia
    • View Profile
Re: MDG - Calculating a tagged value from other tags
« Reply #1 on: June 30, 2017, 05:20:33 pm »
I've had a similar problem. Tag values being used as inputs into calculation and the result captured in another tagged value. The only way I managed to get it to work was via a script.
So what I did was create the various tagged values including the result as a tagged value in my MDG. Then I created a jscript that navigated through the elements and filled in the calculated value for each element.
Store the script in a project script folder so it can be accessed via the UI via the context menu>Script>CalculateBusinessTechnicalRisk
for instance  the following attributes have values of 0 to 5
-Business criticality,
-Customer experience - business,
-Customer experience - technical,
-Efficiency and contribution,
-Future effectiveness,
-Utilisation
The result is which totals the values for the above then finds the average and stores the value in Business Value tagged value. Similar calculations for technical condition and risk values in the script below.

Here is the JScript - hope it helps
Code: [Select]
!INC Local Scripts.EAConstants-JScript

/*
 * Script Name:CalculateBusinessTechnicalRiskValues
 * Purpose: Used to scan through the work packages and calculate the totals business value,
 * technical condition and risk values to help prioritise work packages
 * Date: 17-09-2015
 */

/*
 * Project Browser Script main function
 */
function OnProjectBrowserScript()
{
// Get the type of element selected in the Project Browser
var treeSelectedType = Repository.GetTreeSelectedItemType();

// Handling Code: Uncomment any types you wish this script to support
// NOTE: You can toggle comments on multiple lines that are currently
// selected with [CTRL]+[SHIFT]+[C].
switch ( treeSelectedType )
{
case otElement :
{
// Code for when an element is selected
var theElement as EA.Element;
theElement = Repository.GetTreeSelectedObject();
CalculateElementTotals("    ",theElement);
break;
}
case otPackage :
{
// Code for when a package is selected
var thePackage as EA.Package;
thePackage = Repository.GetTreeSelectedObject();
NavigatePackage("    ",thePackage);
break;
}
default:
{
// Error message
Session.Prompt( "This script does not support items of this type.", promptOK );
}
}
Session.Prompt( "Application Portofolio Management Calculations Complete", promptOK );
}

//
// Navigates through the packages calling Calculate Element Totals in each package
//
// Parameters:
// - indent A string representing the current level of indentation
// - thePackage The package object to be processed
//
function NavigatePackage( indent, thePackage )
{
    // Cast thePackage to EA.Package so we get intellisense
    var currentPackage as EA.Package;
    currentPackage = thePackage;
   
    // Add the current package's name to the list
    Session.Output( indent + currentPackage.Name + " (PackageID=" +
        currentPackage.PackageID + ")" );
   
    // Convert the elements this package contains
    CalculateElementsTotalsInPackage( indent + "    ", currentPackage );
   
    // Recursively process any child packages
    var childPackageEnumerator = new Enumerator( currentPackage.Packages );
    while ( !childPackageEnumerator.atEnd() )
    {
        var childPackage as EA.Package;
        childPackage = childPackageEnumerator.item();
        NavigatePackage( indent + "    ", childPackage );
       
        childPackageEnumerator.moveNext();
    }
}

//
// Calculates element totals in the package
//
// Parameters:
// - indent A string representing the current level of indentation
// - thePackage The package object to be processed
//
function CalculateElementsTotalsInPackage( indent, thePackage )
{
    // Cast thePackage to EA.Package so we get intellisense
    var currentPackage as EA.Package;
    currentPackage = thePackage;
   
    // Iterate through all elements and add them to the list
    var elementEnumerator = new Enumerator( currentPackage.Elements );
    while ( !elementEnumerator.atEnd() )
    {
        var currentElement as EA.Element;
        currentElement = elementEnumerator.item();
        CalculateElementTotals(indent+"    ",currentElement );
        elementEnumerator.moveNext();
    }
}

//
// Calculates element totals for business and technical values along with risk
//
// Parameters:
// - indent A string representing the current level of indentation
// - thePackage The package object to be processed
//
function CalculateElementTotals( indent, theElement )
{
var businessValueTotal = "Business Value";
var businessValuetags = new Array ("Business criticality","Customer experience - business",
"Customer experience - technical","Efficiency and contribution",
"Future effectiveness","Utilisation");

var technicalValueTotal ="Technical Condition";
var technnicalValuetags = new Array ("Architecture","Database / Data Model","Development Language",
"Hardware Platform","Security Design","Operating System","Service Level Performance",
"Vendor Support");

var riskValueTotal ="Risk Value";
var riskValuetags = new Array ("Availability (DR)","Info Mgmt / Confidentiality",
"IT Staffing / Skills","Privacy","Security","Vendor Viability");

    // Cast theElement to EA.Element so we get intellisense
    var currentElement as EA.Element;
    currentElement = theElement;
 
    CalculateTotals(indent+"    ",currentElement,businessValueTotal,businessValuetags);
    CalculateTotals(indent+"    ",currentElement,technicalValueTotal,technnicalValuetags);
    CalculateTotals(indent+"    ",currentElement,riskValueTotal,riskValuetags);

    // Iterate through all embedded elements and add them to the list
    var elementEnumerator = new Enumerator( currentElement.Elements );
    while ( !elementEnumerator.atEnd() )
    {
        var currentElement as EA.Element;
        currentElement = elementEnumerator.item();
        CalculateElementTotals(indent+"    ",currentElement );
        elementEnumerator.moveNext();
    }
}

// 
//Calculate the total and store for tag values passed
// Parameters:
// - indent A string representing the current level of indentation
// - theElement The element object to be processed
function CalculateTotals( indent, theElement, theTotal, theValueTags )
{
// Debug Comment out when run for real
    Session.Output( indent + "CALLED: CalculateTotals with " + theElement.Name + " (" + theElement.Type + ", " + theElement.Stereotype + " )" );
    Session.Output( indent+"   " + "theTotal=" + theTotal );
    Session.Output( indent+"   " + "theValueTags=" + theValueTags );

var total = 0.0;
var tagEnumerator = new Enumerator( theValueTags );

while ( !tagEnumerator.atEnd() )
    {
  var tagValue as EA.TaggedValue;
tagValue = theElement.TaggedValues.GetByName(tagEnumerator.item());
var totalTag  as EA.TaggedValue;

if ( (tagValue !=null) && (tagValue.Value !=""))
{
Session.Output( indent + "    " + "Tag:" + tagValue.Name + " = " + tagValue.Value );
total = total+parseFloat(tagValue.Value);
}

totalTag = theElement.TaggedValues.GetByName(theTotal);
if (totalTag != null)
{
totalTag.Value=total/theValueTags.length;
totalTag.Update();
}
  Session.Output( indent + "    " + "Subtotal =" + total );
tagEnumerator.moveNext();
    }

Session.Output( indent + "    " + "length=" + theValueTags.length );
Session.Output( indent + "    " + theTotal +"= " + total/theValueTags.length );
}

OnProjectBrowserScript();

« Last Edit: June 30, 2017, 05:28:39 pm by Sunshine »

tjlindsay

  • EA User
  • **
  • Posts: 21
  • Karma: +2/-0
    • View Profile
Re: MDG - Calculating a tagged value from other tags
« Reply #2 on: July 03, 2017, 04:18:06 pm »
Excellent thanks for the response and code snippet Sunshine.  8)


TJ





Ian Mitchell

  • EA User
  • **
  • Posts: 237
  • Karma: +2/-0
    • View Profile
Re: MDG - Calculating a tagged value from other tags
« Reply #3 on: July 21, 2017, 12:49:56 am »
I've seem variations of this problem in lots of places, especially with Archimate models which have lots of quantity values at the lower levels. I guess SysML users have the same challenge.
It would be great if EA did this simple arithmetic for us, supporting 'virtual TVs' in parent elements which aggregate the values of the children. We'd need to be able to say if aggregation is valid (e.g. can't aggregate averages), but it's a well bounded problem. It would open up a whole new world for EA users .
@Sparx - has anyone thought  of such a 'Quantitative EA' ??
Ian Mitchell, Designer, eaDocX

www.eaDocX.com
www.theartfulmodeller.com

ducatiross

  • EA User
  • **
  • Posts: 79
  • Karma: +0/-0
    • View Profile
Re: MDG - Calculating a tagged value from other tags
« Reply #4 on: November 16, 2017, 09:44:18 pm »
@Ian - this seems a real gap in EA's functionality and I would whole-heartedly support it. Providing the ability to calculate a TV's value from a user-entered formulae would open up a huge number of reasons to bother enriching EA models. Modelling risk for instance, would need a simple Probability TV (0-5) and Impact TV (0-5) that then results in a Risk x Impact score calculated and saved into another TV. If you could then aggregate these up a model hierarchy so that parent level element scores were the sum of child elements, that would be SO useful.

@TJ - thanks for raising the question. Saved me doing it !

@Sunshine - until Sparx provide this within the toolset natively, I'll try to re-work your code - thanks for posting.

Now, the next item on my hitlist is a method for tree walking a model - starting at one element, then walking up/down the relationships listing the relationship type and element it is linked to in a recursive fashion, perhaps looking for a target element type that could be many relations distant from the original, but linked through a series of other elements.

This would replicate a similar functionality in BEASI where an ArchiMate model can be automatically drawn using derived relations from one element all the way up to another.

I would use BEASI, but a) I don't want to be forced to use custom ArchiMate elements - it must work with standard ArchiMate elements and b) I want to do this for other models, not just ArchiMate.

Anyone got any ideas (ooops -  :-[ I realise I have done a major hijack of this thread - sorry. I'll post it separately 0)

Uffe

  • EA Practitioner
  • ***
  • Posts: 1073
  • Karma: +81/-5
  • Flutes: 1; Clarinets: 1; Saxes: 5 and counting
    • View Profile
Re: MDG - Calculating a tagged value from other tags
« Reply #5 on: November 16, 2017, 11:00:06 pm »
I've had clients ask about this as well. I've done some thinking, and with some limitations it shouldn't be that hard to do.
I could cobble something together within a couple of weeks I think.

Is there interest?
(I've no idea if Sparx are planning to address this.)

/Uffe
My theories are always correct, just apply them to the right reality.

ducatiross

  • EA User
  • **
  • Posts: 79
  • Karma: +0/-0
    • View Profile
Re: MDG - Calculating a tagged value from other tags
« Reply #6 on: November 16, 2017, 11:04:28 pm »
What are you thinking of Uffe - doing something to help the calculation of TVs ? I'm sure there would be interest in that.

Uffe

  • EA Practitioner
  • ***
  • Posts: 1073
  • Karma: +81/-5
  • Flutes: 1; Clarinets: 1; Saxes: 5 and counting
    • View Profile
Re: MDG - Calculating a tagged value from other tags
« Reply #7 on: November 17, 2017, 07:44:43 pm »
Yes, it would be an Add-In that calculates tagged values based on the tagged values of related elements.

There are always going to be limitations to something like this: since EA has no server1 you can't get true automation, you can only do client-side automation. And since the client-side automation API is limited in what it alerts an Add-In about, there will be cases where you will need to invoke a refresh function, kind of like Sunshine's script.

But I can make it pretty seamless for most cases, meaning updating one element would automatically trigger recalculation of tagged values in others.


/Uffe



1 I haven't investigated the possibilities the pro cloud server affords. "Developers are invited to contact Sparx Systems Support to reveive[sic] API documentation", so it may be it's now possible to do proper server-side automation.
My theories are always correct, just apply them to the right reality.