There are several ways to generate UML diagrams via texts such as PlantUML and mermaid.
One of Astah users, Evan Chen wrote a script to convert Astah diagrams for PlantUML and mermaid.js. Currently there are scripts for converting Sequence diagrams and Flowcharts.
Script Overview:Astah_Jude_UML_export_to_Markdown-mermaid-Plantuml-
Scripts:
To PlantUML:Sequence Diagrams
To mermaid:Sequence Diagrams / Flowcharts
How to use
- Create a Sequence Diagram in Astah
- Go to [Tool] – [Script Editor] to open the editor. (This menu exists only in version 7.2 or later. If you are using version 7.1 or earlier, install “Script Plug-in” first.)
- Paste a script to convert Sequence diagram to mermaid.js, then click the arrow icon.
- Text gets exported in the window below.
- Copy the output and paste in the mermaid.js editor to generate the diagram.
-
Here’s the sample on PlantUML using the script to convert to PlantUML.
Scripts
Convert Sequence diagrams to PlantUML
// This script convert Astah SequenceDiagram to plantuml fomat text // Author: Chen Zhi // E-mail: cz_666@qq.com // License: APACHE V2.0 (see license file) var ISequenceDiagram = Java.type('com.change_vision.jude.api.inf.model.ISequenceDiagram'); var ILifeline = Java.type('com.change_vision.jude.api.inf.model.ILifeline'); var IMessage = Java.type('com.change_vision.jude.api.inf.model.IMessage'); var HashMap = Java.type('java.util.HashMap'); run(); function run() { var diagramViewManager = astah.getViewManager().getDiagramViewManager(); var diagram = diagramViewManager.getCurrentDiagram(); if (!(diagram instanceof ISequenceDiagram)) { print('Open a ISequenceDiagram and run again.'); return; } var presentations = diagram.getPresentations(); var lifelinePresentations = getLifelinePresentations(presentations); var lifelineNames = getLifelineNames(lifelinePresentations); var messagePresentations = getMassagePresentations(presentations); print('@startuml'); printLifeline(lifelinePresentations, lifelineNames); printMessages(messagePresentations, lifelineNames); print('@enduml'); } function getLifelinePresentations(presentations) { var lifelinePresentations = new Array(); for (var i in presentations) { var presentation = presentations[i]; if (presentation.getModel() instanceof ILifeline) { lifelinePresentations[i] = presentation; } } lifelinePresentations.sort(orderOfLifelinePosition); return lifelinePresentations; } function orderOfLifelinePosition(a, b) { return a.getLocation().getX() - b.getLocation().getX(); } function getLifelineNames(lifelinePresentations) { var lifelineNames = new HashMap(); for (var i in lifelinePresentations) { var lifelineP = lifelinePresentations[i]; if (lifelineP == undefined) { continue; } var lifeline = lifelineP.getModel(); if (lifeline.getBase() != null) { lifelineNames.put(lifeline, lifeline.getName() + "_" + lifeline.getBase().getName()); } else { lifelineNames.put(lifeline, lifeline.getName()); } } return lifelineNames; } function printLifeline(lifelinePresentations, lifelineNames) { for (var i in lifelinePresentations) { var lifelineP = lifelinePresentations[i]; if (lifelineP == undefined) { continue; } var lifeline = lifelineP.getModel(); print("participant " + lifelineNames.get(lifeline)); } } function getMassagePresentations(presentations) { var messagePresentations = new Array(); for (var i in presentations) { var presentation = presentations[i]; if (presentation.getModel() instanceof IMessage) { messagePresentations[i] = presentation; } } messagePresentations.sort(orderOfMessagePosition); return messagePresentations; } function orderOfMessagePosition(a, b) { return a.getPoints()[0].getY() - b.getPoints()[0].getY(); } function printMessages(messagePresentations, lifelineNames) { for (var i in messagePresentations) { var messageP = messagePresentations[i]; if (messageP == undefined) { continue; } var message = messageP.getModel(); var sourceName = lifelineNames.get(message.getSource()); var targetName = lifelineNames.get(message.getTarget()); print(sourceName + getArrow(message) + targetName + ':' + getText(message)); } } function getArrow(message) { if (message.isReturnMessage()) { return " -->> "; } if (message.isAsynchronous()) { return " ->> "; } return " -> "; } function getText(message) { var index = message.getIndex(); if (message.isReturnMessage()) { index = "reply"; } var messageName = message.getName(); if (messageName == null) { messageName = ""; } return index + '.' + messageName; }
Convert Sequence Diagram to mermaid.js
// This script convert Astah SequenceDiagram to mermaid fomat text // Author: Chen Zhi // E-mail: cz_666@qq.com // License: APACHE V2.0 (see license file) var ISequenceDiagram = Java.type('com.change_vision.jude.api.inf.model.ISequenceDiagram'); var ArrayList = Java.type('java.util.ArrayList'); var Arrays = Java.type('java.util.Arrays'); var Comparator = Java.type('java.util.Comparator'); var Collections = Java.type('java.util.Collections'); var HashMap = Java.type('java.util.HashMap'); var INDENT = ' '; run(); function run() { var diagramViewManager = astah.getViewManager().getDiagramViewManager(); var diagram = diagramViewManager.getCurrentDiagram(); if (!(diagram instanceof ISequenceDiagram)) { print('Open a ISequenceDiagram and run again.'); return; } print(diagram + ' Sequence'); print('```mermaid'); print('sequenceDiagram;'); var lifelinePresentations = getLifelinePresentations(diagram); var lifelineNames = getLifelineNames(lifelinePresentations); printLifelines(lifelinePresentations, lifelineNames); var messagePresentations = getMessagePresentations(diagram); printMessages(messagePresentations, lifelineNames); print('```'); } function getLifelinePresentations(diagram) { var presentations = diagram.getPresentations(); var interaction = diagram.getInteraction(); var lifelines = interaction.getLifelines(); var lifelinePresentations = new ArrayList(); for (var i in presentations) { var presentation = presentations[i]; if (Arrays.asList(lifelines).contains(presentation.getModel())) { lifelinePresentations.add(presentation); } } Collections.sort(lifelinePresentations, new Comparator() { compare: function ( a, b ) { return a.getLocation().getX() - b.getLocation().getX(); } }); return lifelinePresentations; } function getLifelineNames(lifelinePresentations) { var lifelineNames = new HashMap(); for (var i in lifelinePresentations) { var lifeline = lifelinePresentations[i].getModel(); if (lifeline.getBase() != null) { lifelineNames.put(lifeline, lifeline.getName() + '_' + lifeline.getBase()); } else { lifelineNames.put(lifeline, lifeline.getName()); } } return lifelineNames; } function printLifelines(lifelinePresentations, lifelineNames) { for (var i in lifelinePresentations) { var lifeline = lifelinePresentations[i].getModel(); print(INDENT + 'participant ' + lifelineNames.get(lifeline) + ';'); } } function getMessagePresentations(diagram) { var interaction = diagram.getInteraction(); var msgs = interaction.getMessages(); var messagePresentations = new ArrayList(); var presentations = diagram.getPresentations(); for (var i in presentations) { var presentation = presentations[i]; if (Arrays.asList(msgs).contains(presentation.getModel())) { messagePresentations.add(presentation); } } Collections.sort(messagePresentations, new Comparator() { compare: function ( a, b ) { return a.getPoints()[0].getY() - b.getPoints()[0].getY(); } }); return messagePresentations; } function printMessages(messagePresentations, lifelineNames) { for (var i in messagePresentations) { var presentation = messagePresentations[i]; var model = presentation.getModel(); var source = model.getSource(); var target = model.getTarget(); print(INDENT + lifelineNames.get(source) + getArrowString(model) + lifelineNames.get(target) + ':' + getIndexString(model) + '.' + model.getName()); } } function getIndexString(model) { if (model.isReturnMessage()) { return 'reply'; } return model.getIndex(); } function getArrowString(model) { if (model.isReturnMessage()) { return '-->>'; } if (model.isAsynchronous()) { return '-x'; } return '->>'; }
Convert Flowcharts to mermaid.js
// This script convert Astah flowchart to mermaid fomat text // Author: Chen Zhi // E-mail: cz_666@qq.com // License: APACHE V2.0 (see license file) var IActivityDiagram = Java.type('com.change_vision.jude.api.inf.model.IActivityDiagram'); var IControlNode = Java.type('com.change_vision.jude.api.inf.model.IControlNode'); var HashMap = Java.type('java.util.HashMap'); var ID_PREFIX = 'A'; var REPLACEMENT_CHAR = '?'; var INDENT = ' '; run(); function run() { var diagramViewManager = astah.getViewManager().getDiagramViewManager(); var diagram = diagramViewManager.getCurrentDiagram(); if (!(diagram instanceof IActivityDiagram)) { print('Open a flowchart and run again.'); return; } if (!(diagram.isFlowChart())) { print('Open a flowchart and run again.'); return; } var activity = diagram.getActivity(); var activityNodes = activity.getActivityNodes(); var activityNodeIds = getActivityNodeIds(activityNodes); var flows = activity.getFlows(); print(diagram + ' Flowchart'); print('```mermaid'); print('graph TB'); printObjectDefine(activityNodes, activityNodeIds); printFlowchartLogic(flows, activityNodeIds); print('```'); } function getActivityNodeIds(activityNodes) { var activityNodeIds = new HashMap(); for (var i in activityNodes) { var nodeId = ID_PREFIX + i; var node = activityNodes[i]; activityNodeIds.put(node, nodeId); } return activityNodeIds; } function printObjectDefine(activityNodes, activityNodeIds) { for (var i in activityNodes) { var node = activityNodes[i]; var nodeId = activityNodeIds.get(node); if (isRhombus(node)) { print(INDENT + nodeId + '{' + replaceUnavailableCharacters(node.getName()) + '}'); continue; } if (isRectangle(node)) { print(INDENT + nodeId + '[' + replaceUnavailableCharacters(node.getName()) + ']'); continue; } print(INDENT + nodeId + '(' + replaceUnavailableCharacters(node.getName()) + ')'); } } function replaceUnavailableCharacters(string) { var newString = string.replace(/\n/g, ' '); newString = newString.replace(/\(/g, REPLACEMENT_CHAR); newString = newString.replace(/\)/g, REPLACEMENT_CHAR); newString = newString.replace(/\[/g, REPLACEMENT_CHAR); newString = newString.replace(/\]/g, REPLACEMENT_CHAR); newString = newString.replace(/\{/g, REPLACEMENT_CHAR); newString = newString.replace(/\}/g, REPLACEMENT_CHAR); newString = newString.replace(/\;/g, REPLACEMENT_CHAR); newString = newString.replace(/\|/g, REPLACEMENT_CHAR); newString = newString.replace(/E/g, REPLACEMENT_CHAR); return newString; } function printFlowchartLogic(flows, activityNodeIds) { for (var i in flows) { var flow = flows[i]; var sourceId = activityNodeIds.get(flow.getSource()); if (sourceId == null) { continue; } var targetId = activityNodeIds.get(flow.getTarget()); if (targetId == null) { continue; } if (flow.getGuard() != "") { print(INDENT + sourceId + "-->|" + replaceUnavailableCharacters(flow.getGuard()) + "| " + targetId); continue; } print(INDENT + sourceId + "-->" + targetId); } } function isRhombus(node) { if (node instanceof IControlNode && node.isDecisionMergeNode()) { return true; } var stereotypes = node.getStereotypes(); return stereotypes.length > 0 && 'judgement'.equals(stereotypes[0]); } function isRectangle(node) { var stereotypes = node.getStereotypes(); return stereotypes.length > 0 && 'flow_process'.equals(stereotypes[0]); }