@@ -335,118 +335,165 @@ function createCircularClosedPathString(link, arrowLen) {
335
335
var pathString = '' ;
336
336
var offset = link . width / 2 ;
337
337
var coords = link . circularPathData ;
338
- if ( link . circularLinkType === 'top' ) {
339
- // Top path
338
+ var isSourceBeforeTarget = coords . sourceX + coords . verticalBuffer < coords . targetX ;
339
+ var isPathOverlapped = ( coords . rightFullExtent - coords . rightLargeArcRadius - arrowLen ) <= ( coords . leftFullExtent - offset )
340
+ var diff = Math . abs ( coords . rightFullExtent - coords . leftFullExtent - offset ) < offset ;
341
+ if ( link . circularLinkType === 'top' ) {
340
342
pathString =
341
- // start at the left of the target node
342
- 'M ' +
343
- ( coords . targetX - arrowLen ) + ' ' + ( coords . targetY + offset ) + ' ' +
344
- 'L' +
345
- ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . targetY + offset ) +
346
- 'A' +
347
- ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightSmallArcRadius + offset ) + ' 0 0 1 ' +
348
- ( coords . rightFullExtent - offset - arrowLen ) + ' ' + ( coords . targetY - coords . rightSmallArcRadius ) +
349
- 'L' +
350
- ( coords . rightFullExtent - offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent +
351
- 'A' +
352
- ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 1 ' +
353
- ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . verticalFullExtent - offset ) +
354
- 'L' +
355
- coords . leftInnerExtent + ' ' + ( coords . verticalFullExtent - offset ) +
356
- 'A' +
357
- ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftLargeArcRadius + offset ) + ' 0 0 1 ' +
358
- ( coords . leftFullExtent + offset ) + ' ' + coords . verticalLeftInnerExtent +
359
- 'L' +
360
- ( coords . leftFullExtent + offset ) + ' ' + ( coords . sourceY - coords . leftSmallArcRadius ) +
361
- 'A' +
362
- ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftSmallArcRadius + offset ) + ' 0 0 1 ' +
363
- coords . leftInnerExtent + ' ' + ( coords . sourceY + offset ) +
364
- 'L' +
365
- coords . sourceX + ' ' + ( coords . sourceY + offset ) +
366
-
367
- // Walking back
368
- 'L' +
369
- coords . sourceX + ' ' + ( coords . sourceY - offset ) +
370
- 'L' +
371
- coords . leftInnerExtent + ' ' + ( coords . sourceY - offset ) +
372
- 'A' +
373
- ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftSmallArcRadius - offset ) + ' 0 0 0 ' +
374
- ( coords . leftFullExtent - offset ) + ' ' + ( coords . sourceY - coords . leftSmallArcRadius ) +
375
- 'L' +
376
- ( coords . leftFullExtent - offset ) + ' ' + coords . verticalLeftInnerExtent +
377
- 'A' +
378
- ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftLargeArcRadius - offset ) + ' 0 0 0 ' +
379
- coords . leftInnerExtent + ' ' + ( coords . verticalFullExtent + offset ) +
380
- 'L' +
381
- ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . verticalFullExtent + offset ) +
382
- 'A' +
383
- ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightLargeArcRadius - offset ) + ' 0 0 0 ' +
384
- ( coords . rightFullExtent + offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent +
385
- 'L' +
386
- ( coords . rightFullExtent + offset - arrowLen ) + ' ' + ( coords . targetY - coords . rightSmallArcRadius ) +
387
- 'A' +
388
- ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightSmallArcRadius - offset ) + ' 0 0 0 ' +
389
- ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . targetY - offset ) +
390
- 'L' +
391
- ( coords . targetX - arrowLen ) + ' ' + ( coords . targetY - offset ) +
392
- ( arrowLen > 0 ? 'L' + coords . targetX + ' ' + ( coords . targetY ) : '' ) +
393
- 'Z' ;
343
+ // start at the left of the target node
344
+ 'M ' +
345
+ ( coords . targetX - arrowLen ) + ' ' + ( coords . targetY + offset ) + ' ' +
346
+ 'L ' +
347
+ ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . targetY + offset ) +
348
+ 'A ' +
349
+ ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightSmallArcRadius + offset ) + ' 0 0 1 ' +
350
+ ( coords . rightFullExtent - offset - arrowLen ) + ' ' + ( coords . targetY - coords . rightSmallArcRadius ) +
351
+ 'L ' + ( coords . rightFullExtent - offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent ;
352
+
353
+ if ( isSourceBeforeTarget && isPathOverlapped ) {
354
+ pathString += ' A ' +
355
+ ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 1 ' +
356
+ ( coords . rightFullExtent + offset - arrowLen - ( coords . rightLargeArcRadius - offset ) ) + ' ' +
357
+ ( coords . verticalRightInnerExtent - ( coords . rightLargeArcRadius + offset ) ) +
358
+ ' L ' +
359
+ ( coords . rightFullExtent + offset - ( coords . rightLargeArcRadius - offset ) - arrowLen ) + ' ' +
360
+ ( coords . verticalRightInnerExtent - ( coords . rightLargeArcRadius + offset ) ) +
361
+ ' A ' +
362
+ ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftLargeArcRadius + offset ) + ' 0 0 1 ' +
363
+ ( coords . leftFullExtent + offset ) + ' ' + coords . verticalRightInnerExtent ;
364
+ } else if ( isSourceBeforeTarget ) {
365
+ pathString += ' A ' +
366
+ ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightLargeArcRadius - offset ) + ' 0 0 0 ' +
367
+ ( coords . rightFullExtent - offset - arrowLen - ( coords . rightLargeArcRadius - offset ) ) + ' ' +
368
+ ( coords . verticalRightInnerExtent - ( coords . rightLargeArcRadius - offset ) ) +
369
+ ' L ' +
370
+ ( coords . leftFullExtent + offset + ( coords . rightLargeArcRadius - offset ) ) + ' ' +
371
+ ( coords . verticalRightInnerExtent - ( coords . rightLargeArcRadius - offset ) ) +
372
+ ' A ' +
373
+ ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftLargeArcRadius - offset ) + ' 0 0 0 ' +
374
+ ( coords . leftFullExtent + offset ) + ' ' + coords . verticalLeftInnerExtent ;
375
+ } else {
376
+ pathString += ' A ' +
377
+ ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 1 ' +
378
+ ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . verticalFullExtent - offset ) +
379
+ ' L ' +
380
+ coords . leftInnerExtent + ' ' + ( coords . verticalFullExtent - offset ) +
381
+ ' A ' +
382
+ ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftLargeArcRadius + offset ) + ' 0 0 1 ' +
383
+ ( coords . leftFullExtent + offset ) + ' ' + coords . verticalLeftInnerExtent ;
384
+ }
385
+
386
+ pathString += ' L ' +
387
+ ( coords . leftFullExtent + offset ) + ' ' + ( coords . sourceY - coords . leftSmallArcRadius ) +
388
+ ' A ' +
389
+ ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftSmallArcRadius + offset ) + ' 0 0 1 ' +
390
+ coords . leftInnerExtent + ' ' + ( coords . sourceY + offset ) +
391
+ ' L ' +
392
+ coords . sourceX + ' ' + ( coords . sourceY + offset ) +
393
+
394
+ // Walking back
395
+ ' L ' +
396
+ coords . sourceX + ' ' + ( coords . sourceY - offset ) +
397
+ ' L ' +
398
+ coords . leftInnerExtent + ' ' + ( coords . sourceY - offset ) +
399
+ ' A ' +
400
+ ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftSmallArcRadius - offset ) + ' 0 0 0 ' +
401
+ ( coords . leftFullExtent - offset ) + ' ' + ( coords . sourceY - coords . leftSmallArcRadius ) +
402
+ ' L ' +
403
+ ( coords . leftFullExtent - offset ) + ' ' + coords . verticalLeftInnerExtent ;
404
+
405
+ if ( isSourceBeforeTarget && isPathOverlapped ) {
406
+ pathString += ' A ' +
407
+ ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftSmallArcRadius + offset ) + ' 0 0 0 ' +
408
+ ( coords . leftFullExtent - offset ) + ' ' + ( coords . verticalFullExtent + offset ) +
409
+ 'L' + ( coords . rightFullExtent + offset - arrowLen ) + ' ' + ( coords . verticalFullExtent + offset ) +
410
+ ' A ' +
411
+ ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftSmallArcRadius + offset ) + ' 0 0 0 ' +
412
+ ( coords . rightFullExtent + offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent ;
413
+ } else if ( isSourceBeforeTarget ) {
414
+ pathString += ' A ' +
415
+ ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftSmallArcRadius + offset ) + ' 0 0 1 ' +
416
+ ( coords . leftFullExtent + offset ) + ' ' + ( coords . verticalFullExtent - offset ) +
417
+ ' L ' +
418
+ ( coords . rightFullExtent - offset - arrowLen ) + ' ' + ( coords . verticalFullExtent - offset ) +
419
+ ' A ' +
420
+ ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftSmallArcRadius + offset ) + ' 0 0 1 ' +
421
+ ( coords . rightFullExtent + offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent ;
422
+ } else {
423
+ pathString += ' A ' +
424
+ ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftLargeArcRadius - offset ) + ' 0 0 0 ' +
425
+ coords . leftInnerExtent + ' ' + ( coords . verticalFullExtent + offset ) +
426
+ ' L ' +
427
+ ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . verticalFullExtent + offset ) +
428
+ ' A ' +
429
+ ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightLargeArcRadius - offset ) + ' 0 0 0 ' +
430
+ ( coords . rightFullExtent + offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent ;
431
+ }
432
+
433
+ pathString += ' L ' +
434
+ ( coords . rightFullExtent + offset - arrowLen ) + ' ' + ( coords . targetY - coords . rightSmallArcRadius ) +
435
+ ' A ' +
436
+ ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightSmallArcRadius - offset ) + ' 0 0 0 ' +
437
+ ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . targetY - offset ) +
438
+ ' L ' +
439
+ ( coords . targetX - arrowLen ) + ' ' + ( coords . targetY - offset ) +
440
+ ( arrowLen > 0 ? ' L ' + coords . targetX + ' ' + coords . targetY : '' ) +
441
+ 'Z' ;
394
442
} else {
395
- // Bottom path
396
443
pathString =
397
- // start at the left of the target node
398
- 'M ' +
399
- ( coords . targetX - arrowLen ) + ' ' + ( coords . targetY - offset ) + ' ' +
400
- 'L ' +
401
- ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . targetY - offset ) +
402
- 'A' +
403
- ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightSmallArcRadius + offset ) + ' 0 0 0 ' +
404
- ( coords . rightFullExtent - offset - arrowLen ) + ' ' + ( coords . targetY + coords . rightSmallArcRadius ) +
405
- 'L' +
406
- ( coords . rightFullExtent - offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent +
407
- 'A ' +
408
- ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 0 ' +
409
- ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . verticalFullExtent + offset ) +
410
- 'L' +
411
- coords . leftInnerExtent + ' ' + ( coords . verticalFullExtent + offset ) +
412
- 'A ' +
413
- ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftLargeArcRadius + offset ) + ' 0 0 0 ' +
414
- ( coords . leftFullExtent + offset ) + ' ' + coords . verticalLeftInnerExtent +
415
- 'L' +
416
- ( coords . leftFullExtent + offset ) + ' ' + ( coords . sourceY + coords . leftSmallArcRadius ) +
417
- 'A ' +
418
- ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftSmallArcRadius + offset ) + ' 0 0 0 ' +
419
- coords . leftInnerExtent + ' ' + ( coords . sourceY - offset ) +
420
- 'L' +
421
- coords . sourceX + ' ' + ( coords . sourceY - offset ) +
422
-
423
- // Walking back
424
- 'L' +
425
- coords . sourceX + ' ' + ( coords . sourceY + offset ) +
426
- 'L' +
427
- coords . leftInnerExtent + ' ' + ( coords . sourceY + offset ) +
428
- 'A ' +
429
- ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftSmallArcRadius - offset ) + ' 0 0 1 ' +
430
- ( coords . leftFullExtent - offset ) + ' ' + ( coords . sourceY + coords . leftSmallArcRadius ) +
431
- 'L' +
432
- ( coords . leftFullExtent - offset ) + ' ' + coords . verticalLeftInnerExtent +
433
- 'A' +
434
- ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftLargeArcRadius - offset ) + ' 0 0 1 ' +
435
- coords . leftInnerExtent + ' ' + ( coords . verticalFullExtent - offset ) +
436
- 'L ' +
437
- ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . verticalFullExtent - offset ) +
438
- 'A' +
439
- ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightLargeArcRadius - offset ) + ' 0 0 1 ' +
440
- ( coords . rightFullExtent + offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent +
441
- 'L' +
442
- ( coords . rightFullExtent + offset - arrowLen ) + ' ' + ( coords . targetY + coords . rightSmallArcRadius ) +
443
- 'A' +
444
- ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightSmallArcRadius - offset ) + ' 0 0 1 ' +
445
- ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . targetY + offset ) +
446
- 'L' +
447
- ( coords . targetX - arrowLen ) + ' ' + ( coords . targetY + offset ) +
448
- ( arrowLen > 0 ? 'L ' + coords . targetX + ' ' + ( coords . targetY ) : '' ) +
449
- 'Z' ;
444
+ 'M ' + ( coords . targetX - arrowLen ) + ' ' + ( coords . targetY - offset ) + ' ' +
445
+ ' L ' + ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . targetY - offset ) +
446
+ ' A ' + ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightSmallArcRadius + offset ) + ' 0 0 0 ' + ( coords . rightFullExtent - offset - arrowLen ) + ' ' + ( coords . targetY + coords . rightSmallArcRadius ) +
447
+ ' L ' + ( coords . rightFullExtent - offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent ;
448
+
449
+ if ( isSourceBeforeTarget && isPathOverlapped ) {
450
+ pathString += ' A ' + ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 0 ' +
451
+ ( coords . rightInnerExtent - offset - arrowLen ) + ' ' + ( coords . verticalFullExtent + offset ) +
452
+ ' L ' + ( coords . rightFullExtent + offset - arrowLen - ( coords . rightLargeArcRadius - offset ) ) + ' ' + ( coords . verticalFullExtent + offset ) +
453
+ ' A ' + ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 0 ' +
454
+ ( coords . leftFullExtent + offset ) + ' ' + coords . verticalLeftInnerExtent ;
455
+ } else if ( isSourceBeforeTarget ) {
456
+ pathString += ' A ' + ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightSmallArcRadius - offset ) + ' 0 0 1 ' +
457
+ ( coords . rightFullExtent - arrowLen - offset - ( coords . rightLargeArcRadius - offset ) ) + ' ' + ( coords . verticalFullExtent - offset ) +
458
+ ' L ' + ( coords . leftFullExtent + offset + ( coords . rightLargeArcRadius - offset ) ) + ' ' + ( coords . verticalFullExtent - offset ) +
459
+ ' A ' + ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightSmallArcRadius - offset ) + ' 0 0 1 ' +
460
+ ( coords . leftFullExtent + offset ) + ' ' + coords . verticalLeftInnerExtent ;
461
+ } else {
462
+ pathString += ' A ' + ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 0 ' + ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . verticalFullExtent + offset ) +
463
+ ' L ' + coords . leftInnerExtent + ' ' + ( coords . verticalFullExtent + offset ) +
464
+ ' A ' + ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftLargeArcRadius + offset ) + ' 0 0 0 ' + ( coords . leftFullExtent + offset ) + ' ' + coords . verticalLeftInnerExtent ;
465
+ }
466
+
467
+ pathString += ' L ' + ( coords . leftFullExtent + offset ) + ' ' + ( coords . sourceY + coords . leftSmallArcRadius ) +
468
+ ' A ' + ( coords . leftLargeArcRadius + offset ) + ' ' + ( coords . leftSmallArcRadius + offset ) + ' 0 0 0 ' + coords . leftInnerExtent + ' ' + ( coords . sourceY - offset ) +
469
+ ' L ' + coords . sourceX + ' ' + ( coords . sourceY - offset ) +
470
+
471
+ // Walking back
472
+ ' L ' + coords . sourceX + ' ' + ( coords . sourceY + offset ) +
473
+ ' L ' + coords . leftInnerExtent + ' ' + ( coords . sourceY + offset ) +
474
+ ' A ' + ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftSmallArcRadius - offset ) + ' 0 0 1 ' + ( coords . leftFullExtent - offset ) + ' ' + ( coords . sourceY + coords . leftSmallArcRadius ) +
475
+ ' L ' + ( coords . leftFullExtent - offset ) + ' ' + coords . verticalLeftInnerExtent ;
476
+
477
+ if ( isSourceBeforeTarget && isPathOverlapped ) {
478
+ pathString +=
479
+ ' A ' + ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightSmallArcRadius - offset ) + ' 0 0 1 ' +
480
+ ( coords . leftFullExtent - offset - ( coords . rightLargeArcRadius - offset ) ) + ' ' + ( coords . verticalFullExtent - offset ) +
481
+ ' L ' + ( coords . rightFullExtent + offset - arrowLen + ( coords . rightLargeArcRadius - offset ) ) + ' ' + ( coords . verticalFullExtent - offset ) +
482
+ ' A ' + ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightSmallArcRadius - offset ) + ' 0 0 1 ' +
483
+ ( coords . rightFullExtent + offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent ;
484
+ } else if ( isSourceBeforeTarget ) {
485
+ pathString += ' A ' + ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 0 ' + ( coords . leftFullExtent + offset ) + ' ' + ( coords . verticalFullExtent + offset ) +
486
+ ' L ' + ( coords . rightFullExtent - arrowLen - offset ) + ' ' + ( coords . verticalFullExtent + offset ) +
487
+ ' A ' + ( coords . rightLargeArcRadius + offset ) + ' ' + ( coords . rightLargeArcRadius + offset ) + ' 0 0 0 ' + ( coords . rightFullExtent + offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent ;
488
+ } else {
489
+ pathString += ' A ' + ( coords . leftLargeArcRadius - offset ) + ' ' + ( coords . leftLargeArcRadius - offset ) + ' 0 0 1 ' + coords . leftInnerExtent + ' ' + ( coords . verticalFullExtent - offset ) +
490
+ ' L ' + ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . verticalFullExtent - offset ) +
491
+ ' A ' + ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightLargeArcRadius - offset ) + ' 0 0 1 ' + ( coords . rightFullExtent + offset - arrowLen ) + ' ' + coords . verticalRightInnerExtent ;
492
+ }
493
+
494
+ pathString += ' L ' + ( coords . rightFullExtent + offset - arrowLen ) + ' ' + ( coords . targetY + coords . rightSmallArcRadius ) +
495
+ ' A ' + ( coords . rightLargeArcRadius - offset ) + ' ' + ( coords . rightSmallArcRadius - offset ) + ' 0 0 1 ' + ( coords . rightInnerExtent - arrowLen ) + ' ' + ( coords . targetY + offset ) +
496
+ ' L ' + ( coords . targetX - arrowLen ) + ' ' + ( coords . targetY + offset ) + ( arrowLen > 0 ? ' L ' + coords . targetX + ' ' + coords . targetY : '' ) + 'Z' ;
450
497
}
451
498
return pathString ;
452
499
}
0 commit comments