@@ -40,10 +40,9 @@ class Link {
4040 this . svgTexts = [ ] ;
4141 }
4242
43- init ( svg , words ) {
43+ init ( svg ) {
4444 this . mainSVG = svg ;
4545 this . svg = svg . group ( ) . addClass ( this . top ? 'link' : 'link syntax-link' ) ;
46- this . recalculateSlots ( words ) ;
4746
4847 // init handles
4948 // get location of trigger
@@ -81,7 +80,6 @@ class Link {
8180
8281 this . line = this . svg . path ( )
8382 . addClass ( 'polyline' ) ;
84- this . draw ( ) ;
8583 }
8684
8785 toggle ( ) {
@@ -286,38 +284,50 @@ class Link {
286284 this . arguments . forEach ( arg => detachLink ( arg . anchor ) ) ;
287285 }
288286
287+ resetSlotRecalculation ( ) {
288+ this . isRecalculated = false ;
289+ }
290+
289291 recalculateSlots ( words ) {
290292 // reorganize slots
291- let self = this ;
292293 let ep = this . endpoints ;
293- let wordArray = words . slice ( this . endpoints [ 0 ] . idx , this . endpoints [ 1 ] . idx + 1 ) ;
294+ if ( this . isRecalculated ) { return [ { slot : this . slot , endpoints : ep } ] ; }
294295
295- // recursively increase the slots of l
296- function incrementSlot ( l , top ) {
297- l . slot += top ? 1 : - 1 ;
298- l . links . forEach ( incrementSlot ) ;
299- }
296+ this . isRecalculated = true ;
297+ let wordArray = words . slice ( ep [ 0 ] . idx , ep [ 1 ] . idx + 1 ) ;
298+ let self = this ;
300299
301- // recursively check for collisions
302- function checkCollision ( l ) {
303- if ( l !== self && l . slot === self . slot ) {
304- if ( l . endpoints [ 0 ] <= ep [ 0 ] && l . endpoints [ 1 ] >= ep [ 0 ] ) {
305- incrementSlot ( l , self . top ) ;
306- l . recalculateSlots ( words ) ;
307- }
308- else if ( l . endpoints [ 0 ] >= ep [ 0 ] && l . endpoints [ 0 ] <= ep [ 1 ] ) {
309- // TODO: properly handle slots of self
310- incrementSlot ( self , self . top ) ;
300+ let slots = [ ] ;
301+
302+ // get all interfering slots
303+ wordArray . forEach ( word => {
304+ word . links . forEach ( l => {
305+ if ( l !== self &&
306+ l . top === self . top &&
307+ ! ( l . endpoints [ 0 ] . idx >= ep [ 1 ] . idx ||
308+ l . endpoints [ 1 ] . idx <= ep [ 0 ] . idx ) ) {
309+ [ ] . push . apply ( slots , l . recalculateSlots ( words ) ) ;
311310 }
312- l . links . forEach ( checkCollision ) ;
311+ } ) ;
312+ } ) ;
313+
314+ // find a slot to place this link
315+ function incrementSlot ( l ) {
316+ while ( slots . find ( s => s . slot === l . slot &&
317+ ! ( s . endpoints [ 0 ] . idx >= l . endpoints [ 1 ] . idx ||
318+ s . endpoints [ 1 ] . idx <= l . endpoints [ 0 ] . idx ) ) ) {
319+ l . slot += l . top ? 1 : - 1 ;
313320 }
321+ slots . push ( { slot : l . slot , endpoints : l . endpoints } ) ;
322+ l . links . forEach ( link => {
323+ if ( link . top === l . top ) {
324+ incrementSlot ( link ) ;
325+ }
326+ } ) ;
314327 }
328+ incrementSlot ( this ) ;
315329
316- wordArray . forEach ( w => {
317- // get relevant links
318- w . links . forEach ( checkCollision ) ;
319- } ) ;
320-
330+ return slots ;
321331 }
322332
323333 getEndpoints ( ) {
0 commit comments