I'm starting to work with Enterprise Architect and I need to make a script to export all use cases and notes, from a diagram to Excel.
However, the provided CSV export only works for packages, not for diagrams like this:
If I use the option "view as list", the diagram will show all use cases.
I need something like that, but with Notes, and exported to CSV/Excel.
The only thing you need to do is to relate the export script to the diagram in question. The easiest would be to access the diagram with
var dia = Repository.GetCurrentDiagram();
which returns the object for the currently open diagram.
The next is to scan the diagram objects and finding the use cases:
var dObjs = dia.DiagramObjects; // collection of diagram objects
for (var i = 0 ; i < dObjs.Count ; i++) {
var dObj = dObjs.GetAt(i); // current diagram object
var obj = Repository.GetElementByID (dObj).ElementID; // related element
if (obj.Type == "UseCase") { // only interested in UCs
// this is a UC to export; do the magic here
}
}
Please note that the above was just written out of my head and might have syntax errors. But basically that's the way to go.
N.B.: The required csv export is easiest accomplished by using EAScriptLib's JScript-CSV.
Related
I'm a new dev coming from a Ruby background. Recently I've been working very hard in JS and I'm having some issues with class inheritance in the new ES 6. I feel like it may be an issue with my understanding of JS or conflating it to much to Ruby. I've been trying to translate a Ruby Project into JS to practice, but I'm now failing a feature test.
Failing Feature test when trying to initialize two instances of a class
const STATS = { str:1, dex:1, int:1 }
class Example {
constructor(race, clas) {
this.race = race,
this.clas = clas,
this.stats = this.add(STATS)
}
add(stats) {
if(this.race != 'empty'){
stats.str += this.race.str
stats.dex += this.race.dex
stats.int += this.race.int
}
if(this.clas != 'empty') {
stats.str += this.clas.str
stats.dex += this.clas.dex
stats.int += this.clas.int
}
return stats
}
}
var a = new Example({str: 1, dex:0, int:0}, 'empty');
var b = new Example('empty', {str: 0, dex:0, int:1});
console.log('Should be str:2 dex:1 int:1');
console.log(a.stats);
console.log('Should be str:1 dex:1 int:2');
console.log(b.stats);
My class has functions that change the state when constructed, but the issue is any time a new Class is called it retains the changes from the previous variable. It is only an issue on my feature test as it is the only time that class is called twice.
This is the link to my feature test https://github.com/RyanWolfen7/jsRPG/blob/master/cypress/integration/featureTest/characterFeature_test.js
And this is the class thats failing the tests
https://github.com/RyanWolfen7/jsRPG/blob/master/models/characters/character.js
Honestly I'm probably going to scrap my project and start fresh anyways, but I would like to understand what my issue is. I was taking an OOD approach to JS and translating my ruby project https://github.com/RyanWolfen7/ruby_rpg to JS. I'm not sure if its because I wrote the test wrong or a deep misunderstanding of how es-6 works.
Things I have tried:
Creating a new object
Assigning a newly created object to new class
It's not an inheritance issue. In fact, it has nothing to do with OO at all. What you are seeing is the result of the fact that most things in javascript are references (pointers) but you are writing code as if STATS is a value.
In your function add you do this:
add(stats) {
if(this.race != 'empty'){
// modifying passed in object, not creating new object
stats.str += this.race.str
stats.dex += this.race.dex
stats.int += this.race.int
}
if(this.clas != 'empty') {
// modifying passed in object, not creating new object
stats.str += this.clas.str
stats.dex += this.clas.dex
stats.int += this.clas.int
}
return stats
}
So no matter how many times you call add() and from whichever instance of Example you call it from you are only accessing and overwriting the single shared STATS object.
To create new copies of STATS on each function call you need to copy it to a new object. The fastest old-school way to do this is to serialise the object to a string then convert the string back to an object:
add (input) {
var stats = JSON.parse(JSON.stringify(input));
// ...
}
This feels ugly but multiple benchmarks really did show it to be the fastest method.
Modern javascript can do this using Object.assign:
add (input) {
var stats = Object.assign({},input);
// ...
}
However, I don't know if it is faster. You will have to benchmark it yourself. You can google the phrase "js clone object" for more info.
In my project I need to save the data to .txt or .xml or .json file. I could not find any answer from vis.js website/issues blog. It might be simple, do not know. Really helpful if anyone help me out with example code. Thank you so much in advance.
function saveData(data,callback) {
data.id = document.getElementById('node-id').value;
data.label = document.getElementById('node-label').value;
clearPopUp();
callback(data);
}
If I understand you correctly, you are looking for a way to save data and options of a graph. In my graph editor adaptation for TiddlyWiki Classic I use the following method to extract data (the full implementation can be found in the repo, see config.macros.graph.saveDataAndOptions, here's a simplified one):
config.macros.graph.saveDataAndOptions = function(network,newOptions) {
newOptions = newOptions || {};
// get nodes and edges
var nodes = network.body.data.nodes._data; // contains id, label, x,y, custom per-node options and doesn't contain options from options.nodes; presumably contains option values set when network was created, not current ones (it is so for x,y)
// no suitable getter unfortunately
var edges = network.body.data.edges._data; // map; for edges to/from? certain node use network.getConnectedNodes(id)
// network.body.data.edges._data is a hash of { id: , from: , to: }
// get node positions, options
var positions = network.getPositions(), // map
options = // get options stored previously
// merge newOptions into options
for(var nodeId in nodes) {
// nodes[nodeId].x is the initial value, positions[nodeId].x is the current one
if(positions[nodeId]) { // undefined for hidden
nodes[nodeId].x = positions[nodeId].x;
nodes[nodeId].y = positions[nodeId].y;
}
storedNode = copyObjectProperties(nodes[nodeId]);
storedNodes.push(storedNode);
}
//# do whatever you need with storedNodes, edges and options
// (pack them with JSON.stringify, store to a file etc)
};
However, while this works ok for storing data, this only helps to save options passed for storing explicitly which can be not very nice for some cases. I use this method in manipulation helpers and on dragEnd (network.on("dragEnd",this.saveToTiddlerAfterDragging), config.macros.graph.saveToTiddlerAfterDragging = function(stuff) { config.macros.graph.saveDataAndOptions(this,{ physics: false }); };). I haven't recieved any better suggestions, though.
If you need to get data and options reactively and setting such helper to handle certain edit events can't solve your problem, then I suggest wrapping nodes, edges and options as vis.DataSet and save those when needed. This is related too.
To answer the question about events/other ways to use such methods. Here's how I use them:
I save data after drag&drop moving of nodes, this is done using an event handler. Namely, I introduced
config.macros.graph.saveToTiddlerAfterDragging = function(stuff) {
config.macros.graph.saveDataAndOptions(this,{ physics: false });
};
(when drag&drop is used, physics should be switched off, otherwise coordinates won't be preserved anyway) and then I use
network.on("dragEnd",this.saveToTiddlerAfterDragging);
so that changes are saved.
As for saving after adding/editing a node/edge, I apply saving not by an event (although it's nice thinking, and you should try events of DataSet, since there's no special graph events for that). What I do is I add an elaborated hijack to the manipulation methods. Take a look at the source I've linked after the
var mSettings = options.manipulation;
line: for each manipulation method, like options.manipulation.addNode I hijack it so that its callback is hijacked to call config.macros.graph.saveDataAndOptions in the end. Here's a simplified version of what I'm doing:
var nonSaving_addNode = options.manipulation.addNode;
options.manipulation.addNode = function(data,callback) {
// hijack callback to add saving
arguments[1] = function() {
callback.apply(this,arguments); // preserve initial action
config.macros.graph.saveDataAndOptions(network); // add saving
};
nonSaving_addNode.apply(this,arguments);
}
The thing is, addNode is actually called when the add node button is clicked; though, I'm using a customized one to create a popup and apply changes once user is happy with the label they chose.
I am trying to use this conversationThreading-js code to group emails into threads but documentation is scant and/or I am not able to understand it. Has anyone used this bit of code before or used the JWZ email conversation threading algorithm on which it is based?
This is where I am so far:
using Electron I load and parse a local mbox using node-mbox and node-mailparser
I build an array of javascript objects which have key value pairs of messageId, inReplyTo and references.
Using example code from the test file for this lib I try to build the threads but apparently I am not doing it right. I get no errors but I also get no threads (and my test mbox does contain threaded conversations).
Maybe I am misunderstanding what the result should be? Or I am just "doing it wrong"? My end goal here is to be able to display the resulting threads in some sort of directed graph using D3 – but that is not going to happen if I can't get the data set up correctly.
function makeThread(emails) {
var thread = jwz.messageThread().thread(emails.map(
function (message) {
return jwz.message(message.subject, message.messageId, message.references);
}
));
console.log('thread',thread);
}
It's pretty unclear how it works, but I managed to write some code that prints the "thread tree":
function recurse(node, level) {
level = level || 0;
let prefix = '\t'.repeat(level);
(node.children || []).forEach(function(child) {
child.children = child.children || [];
console.log(prefix, level ? '' : '-', child.message ? child.message.subject : '??', `[${ child.children.length }]`);
return recurse(child, level + 1);
});
}
recurse(jwz.messageThread().thread(messages));
(messages is an array of jwz.message() objects, similar to how you're creating it)
In Screeps, I this code doesn't work:
var sources = creep.room.find(Game.FIND_SOURCES_ACTIVE);
It says this:
Cannot read property 'find' of undefined
I have been looking around and cannot find ANY other way to find sources.
Also I've noticed that most of other peoples code doesn't work and even the tutorial's code no longer works when put into the real game.
I can't be completely sure about your issue since I don't have your complete code to go off of but one issue could be that creepis not defined.
You need somewhere in your code to define creep such as a for loop to loop over each of your creeps in the game or room.
var roleMiner = require('role.miner') // role.miner being the module name for miner actions
for(var name in Game.creeps) {
var creep = Game.creeps[name];
//
// do whatever you wish with the current selected creep.
//
// most of the time you will call a module similar to what the tutorials suggest and put your actions for it in there
//
if(creep.memory.role == 'miner'){
roleMiner.run(creep); // passes the current selected creep to the run function in the module
}
}
So, in your roleMiner module you would have something that defines your miners actions.
var roleMiner = {
run: function(creep) {
// this one returns an array of the sources that are in the room with the creep
var sourcesRoom = creep.room.find(FIND_SOURCES);
// this one returns the source object which is closest to the creeps positon
var sourcesClose = creep.pos.findClosestByRange(FIND_SOURCES);
}
}
module.exports = roleMiner;
Hope this helps.
Screeps have some ... mechanism when sharing your data between each game tick.
If you store any thing in global Memory object, your data will lose all its prototype.
to restore your prototype use Object.setPrototypeOf(creep,Creep.prototype) or create new Creep object from your creep id.
I think what you are looking for is:
var sources = creep.pos.findClosestByRange(Game.SOURCES);
or
var sources = creep.pos.findClosestByPath(Game.SOURCES);
im a new player, not sure my code is efficient, i think the find method will be like this:
var sources = creep.room.find(FIND_SOURCES_ACTIVE)
creep will going to the active resource to harvester.
There is a code example on MSDN which uses WMI to enumerate all of the dependencies for a particular service: http://msdn.microsoft.com/en-us/library/aa393673(v=vs.85).aspx
This is great...but i've discovered that the dependencies it discovers might not all be of the same type. I was expecting all dependencies to be of type Win32_Service...but sometimes you will find that a dependency that is actually a driver (Win32_SystemDriver).
So..my question is simple - how do I adjust the MSDN code example to perform a check on each dependency and see if it's a Win32_Service or a Win32_SystemDriver so that I can handle it appropriately? Extra points if you provide the solution in jscript (the example on MSDN is vbscript, but i'm using jscript).
The Win32_DependentService association class represents dependent services using the Win32_BaseService base class. So, if you do not define a specific ResultClass in your ASSOCIATORS OR query (as in Uroc's answer), you'll get any Win32_BaseService subclasses - Win32_Service, Win32_SystemDriver as well as Win32_TerminalService.
To handle different object classes differently, you can check for the object's class name using the Path_.Class property. Here's sample JScript code that illustrates this approach:
var strComputer = ".";
var strServiceName = "RpcSs";
var oWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!//" + strComputer + "/root/cimv2");
var colItems = oWMI.ExecQuery("ASSOCIATORS OF {Win32_Service.Name='" + strServiceName + "'} WHERE AssocClass=Win32_DependentService Role=Antecedent");
var enumItems = new Enumerator(colItems);
var oItem;
for ( ; !enumItems.atEnd(); enumItems.moveNext()) {
oItem = enumItems.item();
switch (oItem.Path_.Class) {
case "Win32_Service":
...
break;
case "Win32_TerminalService":
...
break;
case "Win32_SystemDriver":
...
break;
default:
// another class
...
break;
}
}
Try using this query:
Associators of {Win32_Service.Name="dhcp"} Where AssocClass=Win32_DependentService ResultClass=Win32_SystemDriver
to get only Win32_SystemDriver instances, or
Associators of {Win32_Service.Name="dhcp"} Where AssocClass=Win32_DependentService ResultClass=Win32_Service
to get only Win32_Service instances.