Comments (3)
Unfortunately it's a bit complicated, but here are some basics:
- you should enable the grid and developer mode to track the coordinates/behavior easier
- the coordinates x y w h show where any element is placed and how width and high it is (visible blue border when dev mode is active). This is the same for all elements (classes, relations, ...)
- the coordinates change if the zoomlevel change (at 100% zoom its declared in 10px spaces).
- The shown grid changes according to the zoom, so at 80% zoom the grid is shown every 8px, at 100% it's at every 10px
- the additional_attributes are always stored as if the diagram was at 100% zoom (so 10px steps) and they contain coordinates of relation points in the format x1,y1,x2,y2,... so <additional_attributes>10.0;10.0;170.0;10.0</additional_attributes> means there is a point at 10/10 and a point at 170/10. The upper left corner of the relation element (blue box) is considered postion 0/0, so the example would look like this (the arrow is 1 grid down and 1 right from the upper left border, therefore 10/10. the other end is at 17 grid positions to the right and 1 down):
So as you see there is just positional information stored but no "connections". All of it is calculated on the fly for sticking behavior.
You can also check out the class https://github.com/umlet/umlet/blob/master/umlet-swing/src/main/java/com/baselet/element/old/element/Relation.java and search for code which handles sticking of relation ends to element borders and follow the Java code from there
from umlet.
Thank you for your detailed answer. I'll get to work and inspect the source code you provided. If I succed i'll share my implementation here as well.
from umlet.
I managed to get it working following your basic ideas, hopefully it will be useful for others in future.
Script at the end of the comment does the following;
- takes .uxf file as input with line (you can move it into an arg for whole script if you like to)
domtree = xml.dom.minidom.parse("new.uxf")
- lists relations as text input following the "[Source Concept] - Relation - [Target Concept]" format.
- I also interpret the relation tag using my own convention where label (panel_attribute text node) follows
lt=<<-\n{source_cardinality},{verb label etc},{target_cardinality},({preposition})
format, so if you need something else for your task, you need to alter that part.
I tested with a extensive design document, but I'll just share it with a toy example for privacy concerns here.
Script generates following output:
Example Output
Driver 140,240,0,30 [drive : lt=<. 40,20,10,10,150, 10] Car 0,100,0,30
Car 0,100,0,30 [belong : lt=<. 20,20,190,10,10, 10] Driver 140,240,0,30
using the uxf file
Example Input Diagram
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<diagram program="umlet" version="15.1">
<zoom_level>10</zoom_level>
<element>
<id>UMLClass</id>
<coordinates>
<x>0</x>
<y>0</y>
<w>100</w>
<h>30</h>
</coordinates>
<panel_attributes>Car</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>UMLClass</id>
<coordinates>
<x>140</x>
<y>0</y>
<w>100</w>
<h>30</h>
</coordinates>
<panel_attributes>Driver</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>40</x>
<y>20</y>
<w>170</w>
<h>90</h>
</coordinates>
<panel_attributes>lt=<.
1*,drive,1*</panel_attributes>
<additional_attributes>10.0;10.0;80.0;70.0;150.0;10.0</additional_attributes>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>20</x>
<y>20</y>
<w>220</w>
<h>150</h>
</coordinates>
<panel_attributes>lt=<.
1,belong,1,(to)</panel_attributes>
<additional_attributes>190.0;10.0;100.0;130.0;10.0;10.0</additional_attributes>
</element>
</diagram>
Script
import xml.dom.minidom
class ConceptXMLElement:
def __init__(self, kwargs):
self.label = kwargs[0]
self.xs = kwargs[1]
self.xe = kwargs[2]
self.ys = kwargs[3]
self.ye = kwargs[4]
def __str__(self):
concept_str = self.label.replace('\n', "")
concept_str = concept_str.replace('\t', "").lstrip(' ').rstrip(' ')
concept_str += " " + str(self.xs) + "," + str(self.xe)
concept_str += "," + str(self.ys) + "," + str(self.ye)
return concept_str
class RelationXMLElement:
def __init__(self, kwargs):
self.label = kwargs[0]
self.xs = kwargs[1]
self.ys = kwargs[2]
self.first_point_x = kwargs[3]
self.first_point_y = kwargs[4]
self.last_point_x = kwargs[5]
self.last_point_y = kwargs[6]
self.relType = kwargs[7]
def __str__(self):
relation_string = "[" + self.label + " : " + self.relType
relation_string += f" {self.xs},{self.ys},{self.first_point_x}"
relation_string += f",{self.first_point_y},{self.last_point_x}"
relation_string += f", {self.last_point_y}" + "]"
return relation_string
domtree = xml.dom.minidom.parse("new.uxf")
group = domtree.documentElement
elements = group.getElementsByTagName("element")
concepts = []
relations = []
for el in elements:
if el.childNodes[1].firstChild.nodeValue == "UMLClass":
label = el.childNodes[5].firstChild.nodeValue
xs = int(el.childNodes[3].childNodes[1].firstChild.nodeValue)
xe = xs + int(el.childNodes[3].childNodes[5].firstChild.nodeValue)
ys = int(el.childNodes[3].childNodes[3].firstChild.nodeValue)
ye = ys + int(el.childNodes[3].childNodes[7].firstChild.nodeValue)
# print(label, xs, xe, ys, ye)
concepts.append(ConceptXMLElement([label.strip('\n'), xs, xe, ys, ye]))
for el in elements:
if el.childNodes[1].firstChild.nodeValue == "Relation":
label = el.childNodes[5].firstChild.nodeValue
xs = int(float(el.childNodes[3].childNodes[1].firstChild.nodeValue))
ys = int(float(el.childNodes[3].childNodes[3].firstChild.nodeValue))
first_point_x = int(float(el.childNodes[7].childNodes[0].nodeValue.
split(';')[0]))
first_point_y = int(float(el.childNodes[7].childNodes[0].nodeValue.
split(';')[1]))
last_point_x = int(float(el.childNodes[7].childNodes[0].nodeValue.
split(';')[-2]))
last_point_y = int(float(el.childNodes[7].childNodes[0].nodeValue.
split(';')[-1]))
relType = label.split('\n')[0]
relType.strip(' ')
relType.strip('\t')
if relType == "<<-":
relType = "Relation"
elif relType == "<<<<-":
relType = "Aggregation"
elif relType == "<<." or relType == "<.":
relType = "Realization"
# print(label, xs, xe, ys, ye, relType)
if len(",".join(label.split('\n')[1:]).split(',')) > 1:
relations.append(RelationXMLElement(
[",".join(label.split('\n')[1:]).split(',')[1].strip('\t').
lstrip(' ').rstrip(' '),
xs, ys, first_point_x, first_point_y, last_point_x,
last_point_y, relType]))
else:
relations.append(RelationXMLElement(
[label.split('\n')[1].replace('\t', "").lstrip(' ').
rstrip(' '), xs, ys, first_point_x, first_point_y,
last_point_x, last_point_y, relType]))
for rel in relations:
source = None
target = None
for con in concepts:
if (rel.xs + rel.first_point_x >= con.xs and
con.xe >= rel.xs + rel.first_point_x and
rel.ys + rel.first_point_y >= con.ys and
rel.ys + rel.first_point_y <= con.ye):
target = con
break
for con in concepts:
if (rel.xs + rel.last_point_x >= con.xs and
con.xe >= rel.xs + rel.last_point_x and
rel.ys + rel.last_point_y >= con.ys and
rel.ys + rel.last_point_y <= con.ye and
target != con):
source = con
break
if source is not None and target is not None:
print(source, rel, target)
else:
print("Fail: ", source, rel, target)
from umlet.
Related Issues (20)
- Issues with the Initial/Final State Icons and Dark Mode HOT 1
- umlet 15 freeze: java.lang.NullPointerException: Cannot read field "x" because "center" is null HOT 1
- Umlet 15.0 not on Eclipse Marketplace HOT 2
- Dead Links On Umlet Home Page umlet.com HOT 2
- RuntimeException: Cannot load BuildInfo.properties HOT 2
- Feature Request: Small solid circle line end HOT 3
- Umlet freezes when dragging decision element into activity element HOT 1
- replace log4j1 with reload4j
- HandlerElementMap is never cleared HOT 5
- dead links due to website changes HOT 1
- After the newest update to vscode some of the coloring has changed making it hard to read HOT 3
- Can not export in vscode to PDF or PNG using ssh remote plugin
- UML Activity All-in-One no reaction for setting background and foreground color HOT 1
- No context-sensitive help showing after pressing cmd+ space in the text panel HOT 2
- Cannot zoom in by pressing key "+" (version 15.1) HOT 6
- Cannot use mail to function in Umlet 15.1 HOT 1
- Properties 'bg' inconsistent result based on values
- How can not Run the umlet extensions? HOT 3
- Shifted accent HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from umlet.