11class Link {
2- constructor ( eventId , trigger , args , reltype ) {
2+ constructor ( eventId , trigger , args , reltype , top = true ) {
33 this . eventId = eventId ;
44 this . trigger = trigger ;
55 this . arguments = args . sort ( ( a , b ) => a . anchor . idx - b . anchor . idx ) ;
66 this . links = [ ] ;
77 this . reltype = reltype ;
8+ this . top = top ;
89
910 this . slot = 0 ;
1011
11- if ( this . trigger ) {
12- this . trigger . links . push ( this ) ;
13- this . slot = this . trigger . slot ;
14- }
15- this . arguments . forEach ( arg => {
16- arg . anchor . links . push ( this )
17- if ( arg . anchor . slot > this . slot ) {
18- this . slot = arg . anchor . slot ;
12+ if ( this . top ) {
13+ // top links
14+ if ( this . trigger ) {
15+ this . trigger . links . push ( this ) ;
16+ this . slot = this . trigger . slot ;
1917 }
20- } ) ;
18+ this . arguments . forEach ( arg => {
19+ arg . anchor . links . push ( this ) ;
20+ if ( arg . anchor . slot > this . slot ) {
21+ this . slot = arg . anchor . slot ;
22+ }
23+ } ) ;
2124
22- this . slot += 1 ;
25+ this . slot += 1 ;
26+ }
27+ else {
28+ // bottom links
29+ this . trigger . links . push ( this ) ;
30+ this . slot = - 1 ;
31+ this . arguments . forEach ( arg => arg . anchor . links . push ( this ) ) ;
32+ }
2333 this . endpoints = this . getEndpoints ( ) ;
2434
2535 this . mainSVG = null ;
@@ -31,8 +41,7 @@ class Link {
3141
3242 init ( svg , words ) {
3343 this . mainSVG = svg ;
34- this . svg = svg . group ( ) . addClass ( 'link' ) ;
35-
44+ this . svg = svg . group ( ) . addClass ( this . top ? 'link' : 'link syntax-link' ) ;
3645 this . recalculateSlots ( words ) ;
3746
3847 // init handles
@@ -41,9 +50,9 @@ class Link {
4150 // draw trigger
4251 if ( this . trigger ) {
4352 // draw a diamond at the location of the trigger
44- let offset = this . trigger . links . indexOf ( this ) ;
53+ let offset = this . trigger . links . filter ( l => l . top == this . top ) . indexOf ( this ) ;
4554 let x = this . trigger . cx + 8 * offset ;
46- let y = this . trigger . absoluteY ;
55+ let y = this . top ? this . trigger . absoluteY : this . trigger . absoluteDescent ;
4756
4857 let handle = this . svg . path ( `M${ s } ,0L0,${ s } L${ - s } ,0L0,${ - s } Z` )
4958 . x ( x - s )
@@ -54,11 +63,15 @@ class Link {
5463 // draw arguments
5564 this . arguments . forEach ( arg => {
5665 // draw a triangle at the location of the argument
57- let offset = arg . anchor . links . indexOf ( this ) ;
66+ let offset = arg . anchor . links . filter ( l => l . top == this . top ) . indexOf ( this ) ;
5867 let x = arg . anchor . cx + 8 * offset ;
59- let y = arg . anchor . absoluteY ;
68+ let y = this . top ? arg . anchor . absoluteY : arg . anchor . absoluteDescent ;
6069
61- let handle = this . svg . path ( `M${ [ s , - s / 2 ] } L${ [ - s , - s / 2 ] } L0,${ s } ` )
70+ let handle = (
71+ this . top ?
72+ this . svg . path ( `M${ [ s , - s / 2 ] } L${ [ - s , - s / 2 ] } L0,${ s } ` ) :
73+ this . svg . path ( `M0,${ - s / 2 } L${ [ - s , s ] } L${ [ s , s ] } ` )
74+ )
6275 . x ( x - s )
6376 . y ( y - s ) ;
6477 this . handles . push ( { anchor : arg . anchor , handle, x, y, offset } ) ;
@@ -91,7 +104,7 @@ class Link {
91104 this . handles . forEach ( h => {
92105 if ( anchor === h . anchor ) {
93106 h . x = anchor . cx + 8 * h . offset ;
94- h . y = anchor . absoluteY ;
107+ h . y = this . top ? anchor . absoluteY : anchor . absoluteDescent ;
95108 h . handle
96109 . x ( h . x - s )
97110 . y ( h . y - s ) ;
@@ -233,7 +246,9 @@ class Link {
233246 // helper function to calculate line-height in draw()
234247 getY ( handle ) {
235248 let r = handle . anchor . row ;
236- return r . rh + r . ry - 45 - 15 * this . slot ;
249+ return this . top ?
250+ r . rh + r . ry - 45 - 15 * this . slot
251+ : r . rh + r . ry + 25 - 15 * this . slot ;
237252 }
238253
239254 remove ( ) {
@@ -260,21 +275,21 @@ class Link {
260275 let wordArray = words . slice ( this . endpoints [ 0 ] . idx , this . endpoints [ 1 ] . idx + 1 ) ;
261276
262277 // recursively increase the slots of l
263- function incrementSlot ( l ) {
264- l . slot += 1 ;
278+ function incrementSlot ( l , top ) {
279+ l . slot += top ? 1 : - 1 ;
265280 l . links . forEach ( incrementSlot ) ;
266281 }
267282
268283 // recursively check for collisions
269284 function checkCollision ( l ) {
270285 if ( l !== self && l . slot === self . slot ) {
271286 if ( l . endpoints [ 0 ] <= ep [ 0 ] && l . endpoints [ 1 ] >= ep [ 0 ] ) {
272- incrementSlot ( l ) ;
287+ incrementSlot ( l , self . top ) ;
273288 l . recalculateSlots ( words ) ;
274289 }
275290 else if ( l . endpoints [ 0 ] >= ep [ 0 ] && l . endpoints [ 0 ] <= ep [ 1 ] ) {
276- // TODO: increase the slots of self
277- incrementSlot ( self ) ;
291+ // TODO: properly handle slots of self
292+ incrementSlot ( self , self . top ) ;
278293 }
279294 l . links . forEach ( checkCollision ) ;
280295 }
0 commit comments