« Back

Multiple Objects on Connector, Positioning?

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Multiple Objects on Connector, Positioning?
community relation documentation
Answer
3/27/14 12:32 PM
Based on the recommendation in a previous thread, a connector has been implemented, which draws an object on top of it. All seems to be working for a single object, but if multiple objects are to be added on top of the connector it becomes problematic. There are two possibilities to add multiple objects on top of the connector - in series and in parallel. Adding second concept is accomplished by using GraphRep's MIDDLE, but offsetting y or x axis accordingly. Usually if connector is drawn on the drawing area in a horizontal direction this implementation seems to work, but changing connector's direction to, for example, vertical the other objects than first one appear on the connector's side. This is probably because of the hard-coded y and x offsets. Is it possible to make offsets flexibel and variable to the connector position?
Attachment

Attachments: Question-1a.png (62.9k)

RE: Multiple Objects on Connector, Positioning?
Answer
3/19/13 12:27 PM as a reply to Anonymous.
By determining the position of the end-point objects (start object and end object), a flexible/variable alignment of the objects at the MIDDLE is possible. As an example implementation, see the 2 figures below, the position of the element is dynamically determined and the GraphRep implementation takes it into account when re-arranging the model content.

IMPLEMENTATION/PROPOSAL:
Expression attributes (as hidden attributes of the relation class) are setup to dynamically determine the actual position of start and end-point. Calculation of a quotient to adjust the position of MIDDLE elments accordingly is performed. The same quotient is also used to identify whether a horizontal or vertical alignment should be done.

endX, endY, startX, startY …. Retrieve start and end object and parse X and Y coordinates
LengthA, LengthB, LengthC … Calculation of lengths of triangle (Pytagoras) used for quotient calculation in GraphRep
NumberOfObjects … simulate the objects on the relation class

endX:
1EXPR type:string expr:fixed: (replall (replall (token (replall (aval (ctobj(), "Position"), "NODE ", ""), 0, " "), "x:", ""), "cm", ""))

endY:
1EXPR type:string expr:fixed: (replall (replall (token (replall (aval (ctobj(), "Position"), "NODE ", ""), 1, " "), "y:", ""), "cm", ""))

startX:
1EXPR type:string expr:fixed: (replall (replall (token (replall (aval (cfobj(), "Position"), "NODE ", ""), 0, " "), "x:", ""), "cm", ""))

startY:
1EXPR type:string expr:fixed: (replall (replall (token (replall (aval (cfobj(), "Position"), "NODE ", ""), 1, " "), "y:", ""), "cm", ""))

LengthA (as the X Axis)
1EXPR type:double expr:fixed: (VAL aval("startX") - VAL aval("endX"))

LengthB (as the Y Axis)
1EXPR type:double expr:fixed: (VAL aval("startY") - VAL aval("endY"))

LengthC (not used, just to show Expression Functionality)
1EXPR type:double expr:fixed: (sqrt(pow(aval("LengthA"), 2) + pow(aval("LengthB"), 2)))


GRAPHREP IMPLEMENTATION
 1# no shadow graphrep, since the shadow disturbs to a certain extend the alignment visually
 2GRAPHREP SHADOW off
 3# ready in values from the object. all elements are calculating information from the object positioning
 4AVAL set-default:"3" numberOfObjects:"NumberOfObjects"
 5AVAL startX:"startX"
 6AVAL startY:"startY"
 7AVAL endX:"endX"
 8AVAL endY:"endY"
 9AVAL lengthA:"LengthA" #x-axis
10AVAL lengthB:"LengthB" #y-axis
11# IMPORTANT to adjust the position of the connector marks
12SET quotient: (VAL lengthB/VAL lengthA)
13SET quotientInverse: (VAL lengthA/VAL lengthB )
14# draw the edge
15EDGE
16# draw on the middle position
17MIDDLE
18SET t:0
19# highly recommended to use a while loop, for loop crashes under certain circumstances the environment
20WHILE (t < VAL numberOfObjects) {
21  # calculate the position of the "on-connector" elements based on start and end position
22  IF (quotient >= -1 AND quotient <= 1) {
23    # case: vertically aligned
24    SET x:0
25    SET y: (((VAL numberOfObjects-1)/2)-t)
26  }
27  ELSE {
28   # case: hoirzontal aligned
29   SET x: (((VAL numberOfObjects-1)/2)-t)
30   SET y:0
31  }   
32  # if more than 1 object, draw the connecting lines to the connector marks
33  IF (VAL numberOfObjects > 1) {
34    IF (quotient >= -1 AND quotient <= 1) {
35      POLYLINE 3 x1:0.5cm y1:0cm x2:0.5cm y2: (CM y) x3: (CM x) y3: (CM y)
36      POLYLINE 3 x1:-0.5cm y1:0cm x2:-0.5cm y2: (CM y) x3: (CM x) y3: (CM y)
37    }
38    ELSE {
39      POLYLINE 3 x1:0cm y1:0.5cm x2: (CM x) y2:0.5cm x3: (CM x) y3: (CM y)
40      POLYLINE 3 x1:0cm y1:-0.5cm x2: (CM x) y2:-0.5cm x3: (CM x) y3: (CM y)   
41    }
42  }
43  # draw the elements on the connector
44  FILL color:red
45  ELLIPSE x: (CM x) y: (CM y) rx:0.2cm ry:0.2cm
46  # write numbering in object
47  FONT h:8pt
48  TEXT (t) x: (CM x) y: (CM y) w:c h:c
49  # update while counter
50  SET t: (t + 1)
51}
52# draw the connector marks
53FILL color:white
54
55IF (quotient >= -1 AND quotient <= 1) {
56  SET yMarkPos: (quotient*0.5)
57  SET yMarkNeg: (-1*quotient*0.5)
58  ELLIPSE rx:0.1cm ry:0.1cm x:0.5cm y: (CM yMarkPos)
59  ELLIPSE rx:0.1cm ry:0.1cm x:-0.5cm y: (CM yMarkNeg)
60}
61ELSE {
62  SET xMarkPos: (quotientInverse*0.5)
63  SET xMarkNeg: (-1*quotientInverse*0.5)
64  ELLIPSE rx:0.1cm ry:0.1cm y:0.5cm x: (CM xMarkPos)
65  ELLIPSE rx:0.1cm ry:0.1cm y:-0.5cm x: (CM xMarkNeg)
66
67}
68# DEBUG to display the quotient calculated
69#TEXT (STR quotient)



LIMITATIONS:
- Currently bendpoints are not considered in the implementation, in case bendpoints are created by the user, a strategy to eighter read-out the position of the bend-point and compare to the MIDDEL position has to be added
- Merging/Parallel markers: the repositioning is not smooth but happens when the user releases the move action and the panel is drawn.
Attachment

Attachments: DEMO Alignment Library.abl (14.5k), DynamicAlignment.png (39.5k), Graphrep Alignment LEO.leo (2.3k)