@metadev/daga 4.2.7 → 4.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -381,7 +381,20 @@ const linePath = (shape, points, startDirection, endDirection, minimumDistanceBe
381
381
  result += `M ${points[0][0]} ${points[0][1]}`;
382
382
  for (let i = 1; i < points.length; ++i) {
383
383
  if (i + 1 >= points.length) {
384
- nextDirection = endDirection;
384
+ switch (endDirection) {
385
+ case Side.Bottom:
386
+ nextDirection = Side.Top;
387
+ break;
388
+ case Side.Top:
389
+ nextDirection = Side.Bottom;
390
+ break;
391
+ case Side.Right:
392
+ nextDirection = Side.Left;
393
+ break;
394
+ case Side.Left:
395
+ nextDirection = Side.Right;
396
+ break;
397
+ }
385
398
  } else {
386
399
  if (Math.abs(points[i][0] - points[i - 1][0]) < Math.abs(points[i][1] - points[i - 1][1])) {
387
400
  if (points[i][1] > points[i - 1][1]) {
@@ -417,16 +430,16 @@ const linePath = (shape, points, startDirection, endDirection, minimumDistanceBe
417
430
  }
418
431
  if (nextDirection !== undefined) {
419
432
  switch (nextDirection) {
420
- case Side.Bottom:
433
+ case Side.Top:
421
434
  controlPoint2 = `${points[i][0]} ${points[i][1] + controlPointDistance}`;
422
435
  break;
423
- case Side.Top:
436
+ case Side.Bottom:
424
437
  controlPoint2 = `${points[i][0]} ${points[i][1] - controlPointDistance}`;
425
438
  break;
426
- case Side.Right:
439
+ case Side.Left:
427
440
  controlPoint2 = `${points[i][0] + controlPointDistance} ${points[i][1]}`;
428
441
  break;
429
- case Side.Left:
442
+ case Side.Right:
430
443
  controlPoint2 = `${points[i][0] - controlPointDistance} ${points[i][1]}`;
431
444
  break;
432
445
  }
@@ -439,16 +452,16 @@ const linePath = (shape, points, startDirection, endDirection, minimumDistanceBe
439
452
  let controlPoint = '';
440
453
  const controlPointDistance = (Math.abs(points[i][0] - points[i - 1][0]) + Math.abs(points[i][1] - points[i - 1][1])) / 2;
441
454
  switch (nextDirection) {
442
- case Side.Bottom:
455
+ case Side.Top:
443
456
  controlPoint = `${points[i][0]} ${points[i][1] + controlPointDistance}`;
444
457
  break;
445
- case Side.Top:
458
+ case Side.Bottom:
446
459
  controlPoint = `${points[i][0]} ${points[i][1] - controlPointDistance}`;
447
460
  break;
448
- case Side.Right:
461
+ case Side.Left:
449
462
  controlPoint = `${points[i][0] + controlPointDistance} ${points[i][1]}`;
450
463
  break;
451
- case Side.Left:
464
+ case Side.Right:
452
465
  controlPoint = `${points[i][0] - controlPointDistance} ${points[i][1]}`;
453
466
  break;
454
467
  }
@@ -461,152 +474,443 @@ const linePath = (shape, points, startDirection, endDirection, minimumDistanceBe
461
474
  }
462
475
  break;
463
476
  case LineShape.Square:
477
+ currentDirection = startDirection;
464
478
  result += `M ${points[0][0]} ${points[0][1]}`;
465
- if (startDirection) {
466
- switch (startDirection) {
467
- case Side.Bottom:
468
- points.splice(1, 0, [points[0][0], points[0][1] + minimumDistanceBeforeTurn]);
469
- break;
470
- case Side.Top:
471
- points.splice(1, 0, [points[0][0], points[0][1] - minimumDistanceBeforeTurn]);
472
- break;
473
- case Side.Right:
474
- points.splice(1, 0, [points[0][0] + minimumDistanceBeforeTurn, points[0][1]]);
475
- break;
476
- case Side.Left:
477
- points.splice(1, 0, [points[0][0] - minimumDistanceBeforeTurn, points[0][1]]);
478
- break;
479
- }
480
- }
481
- if (endDirection) {
482
- switch (endDirection) {
483
- case Side.Bottom:
484
- points.splice(points.length - 1, 0, [points[points.length - 1][0], points[points.length - 1][1] + minimumDistanceBeforeTurn]);
485
- break;
486
- case Side.Top:
487
- points.splice(points.length - 1, 0, [points[points.length - 1][0], points[points.length - 1][1] - minimumDistanceBeforeTurn]);
488
- break;
489
- case Side.Right:
490
- points.splice(points.length - 1, 0, [points[points.length - 1][0] + minimumDistanceBeforeTurn, points[points.length - 1][1]]);
491
- break;
492
- case Side.Left:
493
- points.splice(points.length - 1, 0, [points[points.length - 1][0] - minimumDistanceBeforeTurn, points[points.length - 1][1]]);
494
- break;
495
- }
496
- }
497
479
  for (let i = 1; i < points.length; ++i) {
498
- if (currentDirection !== undefined) {
499
- switch (currentDirection) {
480
+ if (i + 1 >= points.length) {
481
+ switch (endDirection) {
500
482
  case Side.Bottom:
501
- if (points[i][1] < points[i - 1][1] && points[i][0] !== points[i - 1][0]) {
502
- // next point is behind, we turn around
503
- result += ` H ${points[i][0]}`;
504
- result += ` V ${points[i][1]}`;
505
- currentDirection = Side.Top;
506
- } else if (points[i][1] < points[i - 1][1] && points[i][0] === points[i - 1][0]) {
507
- // next point is behind on the same line, we turn around
508
- result += ` H ${points[i][0] + minimumDistanceBeforeTurn}`;
509
- result += ` V ${points[i][1]}`;
510
- result += ` H ${points[i][0]}`;
511
- currentDirection = Side.Left;
512
- } else if (points[i][1] === points[i - 1][1] && points[i][0] !== points[i - 1][0]) {
513
- // next point is perpendicular to us
514
- result += ` H ${points[i][0]}`;
515
- currentDirection = points[i][0] > points[i - 1][0] ? Side.Right : Side.Left;
516
- } else if (points[i][1] > points[i - 1][1] && points[i][0] !== points[i - 1][0]) {
517
- // next point is after us, we turn and continue
518
- result += ` H ${points[i][0]}`;
519
- result += ` V ${points[i][1]}`;
520
- } else if (points[i][1] > points[i - 1][1] && points[i][0] === points[i - 1][0]) {
521
- // next point is in the same direction, we continue straight
522
- result += ` V ${points[i][1]}`;
523
- }
483
+ nextDirection = Side.Top;
524
484
  break;
525
485
  case Side.Top:
526
- if (points[i][1] > points[i - 1][1] && points[i][0] !== points[i - 1][0]) {
527
- // next point is behind, we turn around
528
- result += ` H ${points[i][0]}`;
529
- result += ` V ${points[i][1]}`;
530
- currentDirection = Side.Bottom;
531
- } else if (points[i][1] > points[i - 1][1] && points[i][0] === points[i - 1][0]) {
532
- // next point is behind on the same line, we turn around
533
- result += ` H ${points[i][0] - minimumDistanceBeforeTurn}`;
534
- result += ` V ${points[i][1]}`;
535
- result += ` H ${points[i][0]}`;
536
- currentDirection = Side.Right;
537
- } else if (points[i][1] === points[i - 1][1] && points[i][0] !== points[i - 1][0]) {
538
- // next point is perpendicular to us
539
- result += ` H ${points[i][0]}`;
540
- currentDirection = points[i][0] > points[i - 1][0] ? Side.Right : Side.Left;
541
- } else if (points[i][1] < points[i - 1][1] && points[i][0] !== points[i - 1][0]) {
542
- // next point is after us, we turn and continue
543
- result += ` H ${points[i][0]}`;
544
- result += ` V ${points[i][1]}`;
545
- } else if (points[i][1] < points[i - 1][1] && points[i][0] === points[i - 1][0]) {
546
- // next point is in the same direction, we continue straight
547
- result += ` V ${points[i][1]}`;
548
- }
486
+ nextDirection = Side.Bottom;
549
487
  break;
550
488
  case Side.Right:
551
- if (points[i][0] < points[i - 1][0] && points[i][1] !== points[i - 1][1]) {
552
- // next point is behind, we turn around
553
- result += ` V ${points[i][1]}`;
554
- result += ` H ${points[i][0]}`;
555
- currentDirection = Side.Left;
556
- } else if (points[i][0] < points[i - 1][0] && points[i][1] === points[i - 1][1]) {
557
- // next point is behind on the same line, we turn around
558
- result += ` V ${points[i][1] + minimumDistanceBeforeTurn}`;
559
- result += ` H ${points[i][0]}`;
560
- result += ` V ${points[i][1]}`;
561
- currentDirection = Side.Top;
562
- } else if (points[i][0] === points[i - 1][0] && points[i][1] !== points[i - 1][1]) {
563
- // next point is perpendicular to us
564
- result += ` V ${points[i][1]}`;
565
- currentDirection = points[i][1] > points[i - 1][1] ? Side.Bottom : Side.Top;
566
- } else if (points[i][0] > points[i - 1][0] && points[i][1] !== points[i - 1][1]) {
567
- // next point is after us, we turn and continue
568
- result += ` V ${points[i][1]}`;
569
- result += ` H ${points[i][0]}`;
570
- } else if (points[i][0] > points[i - 1][0] && points[i][1] === points[i - 1][1]) {
571
- // next point is in the same direction, we continue straight
572
- result += ` H ${points[i][0]}`;
573
- }
489
+ nextDirection = Side.Left;
574
490
  break;
575
491
  case Side.Left:
576
- if (points[i][0] > points[i - 1][0] && points[i][1] !== points[i - 1][1]) {
577
- // next point is behind, we turn around
578
- result += ` V ${points[i][1]}`;
579
- result += ` H ${points[i][0]}`;
580
- currentDirection = Side.Right;
581
- } else if (points[i][0] > points[i - 1][0] && points[i][1] === points[i - 1][1]) {
582
- // next point is behind on the same line, we turn around
583
- result += ` V ${points[i][1] - minimumDistanceBeforeTurn}`;
492
+ nextDirection = Side.Right;
493
+ break;
494
+ }
495
+ }
496
+ switch (currentDirection) {
497
+ case Side.Bottom:
498
+ switch (nextDirection) {
499
+ case Side.Bottom:
500
+ if (points[i][1] > points[i - 1][1]) {
501
+ if (points[i][0] !== points[i - 1][0]) {
502
+ result += ` V ${(points[i][1] + points[i - 1][1]) / 2}`;
503
+ result += ` H ${points[i][0]}`;
504
+ result += ` V ${points[i][1]}`;
505
+ } else {
506
+ result += ` V ${points[i][1]}`;
507
+ }
508
+ currentDirection = nextDirection;
509
+ } else {
510
+ if (points[i][0] > points[i - 1][0]) {
511
+ result += ` V ${points[i - 1][1] + minimumDistanceBeforeTurn}`;
512
+ result += ` H ${Math.max(points[i - 1][0], points[i][0]) + minimumDistanceBeforeTurn}`;
513
+ result += ` V ${points[i][1] - minimumDistanceBeforeTurn}`;
514
+ result += ` H ${points[i][0]}`;
515
+ result += ` V ${points[i][1]}`;
516
+ } else {
517
+ result += ` V ${points[i - 1][1] + minimumDistanceBeforeTurn}`;
518
+ result += ` H ${Math.min(points[i - 1][0], points[i][0]) - minimumDistanceBeforeTurn}`;
519
+ result += ` V ${points[i][1] - minimumDistanceBeforeTurn}`;
520
+ result += ` H ${points[i][0]}`;
521
+ result += ` V ${points[i][1]}`;
522
+ }
523
+ }
524
+ break;
525
+ case Side.Top:
526
+ result += ` V ${Math.max(points[i - 1][1], points[i][1]) + minimumDistanceBeforeTurn}`;
584
527
  result += ` H ${points[i][0]}`;
585
528
  result += ` V ${points[i][1]}`;
586
- currentDirection = Side.Bottom;
587
- } else if (points[i][0] === points[i - 1][0] && points[i][1] !== points[i - 1][1]) {
588
- // next point is perpendicular to us
529
+ break;
530
+ case Side.Left:
531
+ if (points[i][1] > points[i - 1][1] + minimumDistanceBeforeTurn) {
532
+ if (points[i][0] < points[i - 1][0] - minimumDistanceBeforeTurn) {
533
+ result += ` V ${points[i][1]}`;
534
+ result += ` H ${points[i][0]}`;
535
+ } else {
536
+ result += ` V ${(points[i - 1][1] + points[i][1]) / 2}`;
537
+ result += ` H ${points[i][0] + minimumDistanceBeforeTurn}`;
538
+ result += ` V ${points[i][1]}`;
539
+ result += ` H ${points[i][0]}`;
540
+ }
541
+ } else {
542
+ if (points[i][0] < points[i - 1][0] - minimumDistanceBeforeTurn) {
543
+ result += ` V ${points[i - 1][1] + minimumDistanceBeforeTurn}`;
544
+ result += ` H ${(points[i - 1][0] + points[i][0]) / 2}`;
545
+ result += ` V ${points[i][1]}`;
546
+ result += ` H ${points[i][0]}`;
547
+ } else {
548
+ result += ` V ${points[i - 1][1] + minimumDistanceBeforeTurn}`;
549
+ result += ` H ${points[i][0] + minimumDistanceBeforeTurn}`;
550
+ result += ` V ${points[i][1]}`;
551
+ result += ` H ${points[i][0]}`;
552
+ }
553
+ }
554
+ break;
555
+ case Side.Right:
556
+ if (points[i][1] > points[i - 1][1] + minimumDistanceBeforeTurn) {
557
+ if (points[i][0] > points[i - 1][0] + minimumDistanceBeforeTurn) {
558
+ result += ` V ${points[i][1]}`;
559
+ result += ` H ${points[i][0]}`;
560
+ } else {
561
+ result += ` V ${(points[i - 1][1] + points[i][1]) / 2}`;
562
+ result += ` H ${points[i][0] - minimumDistanceBeforeTurn}`;
563
+ result += ` V ${points[i][1]}`;
564
+ result += ` H ${points[i][0]}`;
565
+ }
566
+ } else {
567
+ if (points[i][0] > points[i - 1][0] + minimumDistanceBeforeTurn) {
568
+ result += ` V ${points[i - 1][1] + minimumDistanceBeforeTurn}`;
569
+ result += ` H ${(points[i - 1][0] + points[i][0]) / 2}`;
570
+ result += ` V ${points[i][1]}`;
571
+ result += ` H ${points[i][0]}`;
572
+ } else {
573
+ result += ` V ${points[i - 1][1] + minimumDistanceBeforeTurn}`;
574
+ result += ` H ${points[i][0] - minimumDistanceBeforeTurn}`;
575
+ result += ` V ${points[i][1]}`;
576
+ result += ` H ${points[i][0]}`;
577
+ }
578
+ }
579
+ break;
580
+ default:
581
+ if (points[i][1] < points[i - 1][1] + minimumDistanceBeforeTurn) {
582
+ result += ` V ${points[i - 1][1] + minimumDistanceBeforeTurn}`;
583
+ if (points[i][0] !== points[i - 1][0]) {
584
+ result += ` H ${points[i][0]}`;
585
+ }
586
+ result += ` V ${points[i][1]}`;
587
+ currentDirection = Side.Top;
588
+ } else {
589
+ result += ` V ${points[i][1]}`;
590
+ currentDirection = Side.Bottom;
591
+ if (points[i][0] !== points[i - 1][0]) {
592
+ result += ` H ${points[i][0]}`;
593
+ currentDirection = points[i][0] > points[i - 1][0] ? Side.Right : Side.Left;
594
+ }
595
+ }
596
+ break;
597
+ }
598
+ break;
599
+ case Side.Top:
600
+ switch (nextDirection) {
601
+ case Side.Top:
602
+ if (points[i][1] < points[i - 1][1]) {
603
+ if (points[i][0] !== points[i - 1][0]) {
604
+ result += ` V ${(points[i][1] + points[i - 1][1]) / 2}`;
605
+ result += ` H ${points[i][0]}`;
606
+ result += ` V ${points[i][1]}`;
607
+ } else {
608
+ result += ` V ${points[i][1]}`;
609
+ }
610
+ currentDirection = nextDirection;
611
+ } else {
612
+ if (points[i][0] < points[i - 1][0]) {
613
+ result += ` V ${points[i - 1][1] - minimumDistanceBeforeTurn}`;
614
+ result += ` H ${Math.min(points[i - 1][0], points[i][0]) - minimumDistanceBeforeTurn}`;
615
+ result += ` V ${points[i][1] + minimumDistanceBeforeTurn}`;
616
+ result += ` H ${points[i][0]}`;
617
+ result += ` V ${points[i][1]}`;
618
+ } else {
619
+ result += ` V ${points[i - 1][1] - minimumDistanceBeforeTurn}`;
620
+ result += ` H ${Math.max(points[i - 1][0], points[i][0]) + minimumDistanceBeforeTurn}`;
621
+ result += ` V ${points[i][1] + minimumDistanceBeforeTurn}`;
622
+ result += ` H ${points[i][0]}`;
623
+ result += ` V ${points[i][1]}`;
624
+ }
625
+ }
626
+ break;
627
+ case Side.Bottom:
628
+ result += ` V ${Math.min(points[i - 1][1], points[i][1]) - minimumDistanceBeforeTurn}`;
629
+ result += ` H ${points[i][0]}`;
589
630
  result += ` V ${points[i][1]}`;
590
- currentDirection = points[i][1] > points[i - 1][1] ? Side.Bottom : Side.Top;
591
- } else if (points[i][0] < points[i - 1][0] && points[i][1] !== points[i - 1][1]) {
592
- // next point is after us, we turn and continue
631
+ break;
632
+ case Side.Right:
633
+ if (points[i][1] < points[i - 1][1] - minimumDistanceBeforeTurn) {
634
+ if (points[i][0] > points[i - 1][0] + minimumDistanceBeforeTurn) {
635
+ result += ` V ${points[i][1]}`;
636
+ result += ` H ${points[i][0]}`;
637
+ } else {
638
+ result += ` V ${(points[i - 1][1] + points[i][1]) / 2}`;
639
+ result += ` H ${points[i][0] - minimumDistanceBeforeTurn}`;
640
+ result += ` V ${points[i][1]}`;
641
+ result += ` H ${points[i][0]}`;
642
+ }
643
+ } else {
644
+ if (points[i][0] > points[i - 1][0] + minimumDistanceBeforeTurn) {
645
+ result += ` V ${points[i - 1][1] - minimumDistanceBeforeTurn}`;
646
+ result += ` H ${(points[i - 1][0] + points[i][0]) / 2}`;
647
+ result += ` V ${points[i][1]}`;
648
+ result += ` H ${points[i][0]}`;
649
+ } else {
650
+ result += ` V ${points[i - 1][1] - minimumDistanceBeforeTurn}`;
651
+ result += ` H ${points[i][0] - minimumDistanceBeforeTurn}`;
652
+ result += ` V ${points[i][1]}`;
653
+ result += ` H ${points[i][0]}`;
654
+ }
655
+ }
656
+ break;
657
+ case Side.Left:
658
+ if (points[i][1] < points[i - 1][1] - minimumDistanceBeforeTurn) {
659
+ if (points[i][0] < points[i - 1][0] - minimumDistanceBeforeTurn) {
660
+ result += ` V ${points[i][1]}`;
661
+ result += ` H ${points[i][0]}`;
662
+ } else {
663
+ result += ` V ${(points[i - 1][1] + points[i][1]) / 2}`;
664
+ result += ` H ${points[i][0] + minimumDistanceBeforeTurn}`;
665
+ result += ` V ${points[i][1]}`;
666
+ result += ` H ${points[i][0]}`;
667
+ }
668
+ } else {
669
+ if (points[i][0] < points[i - 1][0] - minimumDistanceBeforeTurn) {
670
+ result += ` V ${points[i - 1][1] - minimumDistanceBeforeTurn}`;
671
+ result += ` H ${(points[i - 1][0] + points[i][0]) / 2}`;
672
+ result += ` V ${points[i][1]}`;
673
+ result += ` H ${points[i][0]}`;
674
+ } else {
675
+ result += ` V ${points[i - 1][1] - minimumDistanceBeforeTurn}`;
676
+ result += ` H ${points[i][0] + minimumDistanceBeforeTurn}`;
677
+ result += ` V ${points[i][1]}`;
678
+ result += ` H ${points[i][0]}`;
679
+ }
680
+ }
681
+ break;
682
+ default:
683
+ if (points[i][1] > points[i - 1][1] - minimumDistanceBeforeTurn) {
684
+ result += ` V ${points[i - 1][1] - minimumDistanceBeforeTurn}`;
685
+ if (points[i][0] !== points[i - 1][0]) {
686
+ result += ` H ${points[i][0]}`;
687
+ }
688
+ result += ` V ${points[i][1]}`;
689
+ currentDirection = Side.Bottom;
690
+ } else {
691
+ result += ` V ${points[i][1]}`;
692
+ currentDirection = Side.Top;
693
+ if (points[i][0] !== points[i - 1][0]) {
694
+ result += ` H ${points[i][0]}`;
695
+ currentDirection = points[i][0] > points[i - 1][0] ? Side.Right : Side.Left;
696
+ }
697
+ }
698
+ break;
699
+ }
700
+ break;
701
+ case Side.Left:
702
+ switch (nextDirection) {
703
+ case Side.Left:
704
+ if (points[i][0] < points[i - 1][0]) {
705
+ if (points[i][1] !== points[i - 1][1]) {
706
+ result += ` H ${(points[i][0] + points[i - 1][0]) / 2}`;
707
+ result += ` V ${points[i][1]}`;
708
+ result += ` H ${points[i][0]}`;
709
+ } else {
710
+ result += ` H ${points[i][0]}`;
711
+ }
712
+ currentDirection = nextDirection;
713
+ } else {
714
+ if (points[i][1] < points[i - 1][1]) {
715
+ result += ` H ${points[i - 1][0] - minimumDistanceBeforeTurn}`;
716
+ result += ` V ${Math.min(points[i - 1][1], points[i][1]) - minimumDistanceBeforeTurn}`;
717
+ result += ` H ${points[i][0] + minimumDistanceBeforeTurn}`;
718
+ result += ` V ${points[i][1]}`;
719
+ result += ` H ${points[i][0]}`;
720
+ } else {
721
+ result += ` H ${points[i - 1][0] - minimumDistanceBeforeTurn}`;
722
+ result += ` V ${Math.max(points[i - 1][1], points[i][1]) + minimumDistanceBeforeTurn}`;
723
+ result += ` H ${points[i][0] + minimumDistanceBeforeTurn}`;
724
+ result += ` V ${points[i][1]}`;
725
+ result += ` H ${points[i][0]}`;
726
+ }
727
+ }
728
+ break;
729
+ case Side.Right:
730
+ result += ` H ${Math.min(points[i - 1][0], points[i][0]) - minimumDistanceBeforeTurn}`;
593
731
  result += ` V ${points[i][1]}`;
594
732
  result += ` H ${points[i][0]}`;
595
- } else if (points[i][0] < points[i - 1][0] && points[i][1] === points[i - 1][1]) {
596
- // next point is in the same direction, we continue straight
733
+ break;
734
+ case Side.Bottom:
735
+ if (points[i][0] < points[i - 1][0] - minimumDistanceBeforeTurn) {
736
+ if (points[i][1] > points[i - 1][1] + minimumDistanceBeforeTurn) {
737
+ result += ` H ${points[i][0]}`;
738
+ result += ` V ${points[i][1]}`;
739
+ } else {
740
+ result += ` H ${(points[i - 1][0] + points[i][0]) / 2}`;
741
+ result += ` V ${points[i][1] - minimumDistanceBeforeTurn}`;
742
+ result += ` H ${points[i][0]}`;
743
+ result += ` V ${points[i][1]}`;
744
+ }
745
+ } else {
746
+ if (points[i][1] > points[i - 1][1] + minimumDistanceBeforeTurn) {
747
+ result += ` H ${points[i - 1][0] - minimumDistanceBeforeTurn}`;
748
+ result += ` V ${(points[i - 1][1] + points[i][1]) / 2}`;
749
+ result += ` H ${points[i][0]}`;
750
+ result += ` V ${points[i][1]}`;
751
+ } else {
752
+ result += ` H ${points[i - 1][0] - minimumDistanceBeforeTurn}`;
753
+ result += ` V ${points[i][1] - minimumDistanceBeforeTurn}`;
754
+ result += ` H ${points[i][0]}`;
755
+ result += ` V ${points[i][1]}`;
756
+ }
757
+ }
758
+ break;
759
+ case Side.Top:
760
+ if (points[i][0] < points[i - 1][0] - minimumDistanceBeforeTurn) {
761
+ if (points[i][1] < points[i - 1][1] - minimumDistanceBeforeTurn) {
762
+ result += ` H ${points[i][0]}`;
763
+ result += ` V ${points[i][1]}`;
764
+ } else {
765
+ result += ` H ${(points[i - 1][0] + points[i][0]) / 2}`;
766
+ result += ` V ${points[i][1] + minimumDistanceBeforeTurn}`;
767
+ result += ` H ${points[i][0]}`;
768
+ result += ` V ${points[i][1]}`;
769
+ }
770
+ } else {
771
+ if (points[i][1] < points[i - 1][1] - minimumDistanceBeforeTurn) {
772
+ result += ` H ${points[i - 1][0] - minimumDistanceBeforeTurn}`;
773
+ result += ` V ${(points[i - 1][1] + points[i][1]) / 2}`;
774
+ result += ` H ${points[i][0]}`;
775
+ result += ` V ${points[i][1]}`;
776
+ } else {
777
+ result += ` H ${points[i - 1][0] - minimumDistanceBeforeTurn}`;
778
+ result += ` V ${points[i][1] + minimumDistanceBeforeTurn}`;
779
+ result += ` H ${points[i][0]}`;
780
+ result += ` V ${points[i][1]}`;
781
+ }
782
+ }
783
+ break;
784
+ default:
785
+ if (points[i][0] > points[i - 1][0] - minimumDistanceBeforeTurn) {
786
+ result += ` H ${points[i - 1][0] - minimumDistanceBeforeTurn}`;
787
+ if (points[i][1] !== points[i - 1][1]) {
788
+ result += ` V ${points[i][1]}`;
789
+ }
790
+ result += ` H ${points[i][0]}`;
791
+ currentDirection = Side.Right;
792
+ } else {
793
+ result += ` H ${points[i][0]}`;
794
+ currentDirection = Side.Left;
795
+ if (points[i][1] !== points[i - 1][1]) {
796
+ result += ` V ${points[i][1]}`;
797
+ currentDirection = points[i][1] > points[i - 1][1] ? Side.Bottom : Side.Top;
798
+ }
799
+ }
800
+ break;
801
+ }
802
+ break;
803
+ case Side.Right:
804
+ switch (nextDirection) {
805
+ case Side.Right:
806
+ if (points[i][0] > points[i - 1][0]) {
807
+ if (points[i][1] !== points[i - 1][1]) {
808
+ result += ` H ${(points[i][0] + points[i - 1][0]) / 2}`;
809
+ result += ` V ${points[i][1]}`;
810
+ result += ` H ${points[i][0]}`;
811
+ } else {
812
+ result += ` H ${points[i][0]}`;
813
+ }
814
+ currentDirection = nextDirection;
815
+ } else {
816
+ if (points[i][1] > points[i - 1][1]) {
817
+ result += ` H ${points[i - 1][0] + minimumDistanceBeforeTurn}`;
818
+ result += ` V ${Math.max(points[i - 1][1], points[i][1]) + minimumDistanceBeforeTurn}`;
819
+ result += ` H ${points[i][0] - minimumDistanceBeforeTurn}`;
820
+ result += ` V ${points[i][1]}`;
821
+ result += ` H ${points[i][0]}`;
822
+ } else {
823
+ result += ` H ${points[i - 1][0] + minimumDistanceBeforeTurn}`;
824
+ result += ` V ${Math.min(points[i - 1][1], points[i][1]) - minimumDistanceBeforeTurn}`;
825
+ result += ` H ${points[i][0] - minimumDistanceBeforeTurn}`;
826
+ result += ` V ${points[i][1]}`;
827
+ result += ` H ${points[i][0]}`;
828
+ }
829
+ }
830
+ break;
831
+ case Side.Left:
832
+ result += ` H ${Math.max(points[i - 1][0], points[i][0]) + minimumDistanceBeforeTurn}`;
833
+ result += ` V ${points[i][1]}`;
597
834
  result += ` H ${points[i][0]}`;
598
- }
599
- break;
600
- }
601
- } else {
602
- if (points[i][0] !== points[i - 1][0]) {
603
- result += ` H ${points[i][0]}`;
604
- currentDirection = points[i][0] > points[i - 1][0] ? Side.Right : Side.Left;
605
- }
606
- if (points[i][1] !== points[i - 1][1]) {
607
- result += ` V ${points[i][1]}`;
608
- currentDirection = points[i][1] > points[i - 1][1] ? Side.Bottom : Side.Top;
609
- }
835
+ break;
836
+ case Side.Top:
837
+ if (points[i][0] > points[i - 1][0] + minimumDistanceBeforeTurn) {
838
+ if (points[i][1] < points[i - 1][1] - minimumDistanceBeforeTurn) {
839
+ result += ` H ${points[i][0]}`;
840
+ result += ` V ${points[i][1]}`;
841
+ } else {
842
+ result += ` H ${(points[i - 1][0] + points[i][0]) / 2}`;
843
+ result += ` V ${points[i][1] + minimumDistanceBeforeTurn}`;
844
+ result += ` H ${points[i][0]}`;
845
+ result += ` V ${points[i][1]}`;
846
+ }
847
+ } else {
848
+ if (points[i][1] < points[i - 1][1] - minimumDistanceBeforeTurn) {
849
+ result += ` H ${points[i - 1][0] + minimumDistanceBeforeTurn}`;
850
+ result += ` V ${(points[i - 1][1] + points[i][1]) / 2}`;
851
+ result += ` H ${points[i][0]}`;
852
+ result += ` V ${points[i][1]}`;
853
+ } else {
854
+ result += ` H ${points[i - 1][0] + minimumDistanceBeforeTurn}`;
855
+ result += ` V ${points[i][1] + minimumDistanceBeforeTurn}`;
856
+ result += ` H ${points[i][0]}`;
857
+ result += ` V ${points[i][1]}`;
858
+ }
859
+ }
860
+ break;
861
+ case Side.Bottom:
862
+ if (points[i][0] > points[i - 1][0] + minimumDistanceBeforeTurn) {
863
+ if (points[i][1] > points[i - 1][1] + minimumDistanceBeforeTurn) {
864
+ result += ` H ${points[i][0]}`;
865
+ result += ` V ${points[i][1]}`;
866
+ } else {
867
+ result += ` H ${(points[i - 1][0] + points[i][0]) / 2}`;
868
+ result += ` V ${points[i][1] - minimumDistanceBeforeTurn}`;
869
+ result += ` H ${points[i][0]}`;
870
+ result += ` V ${points[i][1]}`;
871
+ }
872
+ } else {
873
+ if (points[i][1] > points[i - 1][1] + minimumDistanceBeforeTurn) {
874
+ result += ` H ${points[i - 1][0] + minimumDistanceBeforeTurn}`;
875
+ result += ` V ${(points[i - 1][1] + points[i][1]) / 2}`;
876
+ result += ` H ${points[i][0]}`;
877
+ result += ` V ${points[i][1]}`;
878
+ } else {
879
+ result += ` H ${points[i - 1][0] + minimumDistanceBeforeTurn}`;
880
+ result += ` V ${points[i][1] - minimumDistanceBeforeTurn}`;
881
+ result += ` H ${points[i][0]}`;
882
+ result += ` V ${points[i][1]}`;
883
+ }
884
+ }
885
+ break;
886
+ default:
887
+ if (points[i][0] < points[i - 1][0] + minimumDistanceBeforeTurn) {
888
+ result += ` H ${points[i - 1][0] + minimumDistanceBeforeTurn}`;
889
+ if (points[i][1] !== points[i - 1][1]) {
890
+ result += ` V ${points[i][1]}`;
891
+ }
892
+ result += ` H ${points[i][0]}`;
893
+ currentDirection = Side.Left;
894
+ } else {
895
+ result += ` H ${points[i][0]}`;
896
+ currentDirection = Side.Right;
897
+ if (points[i][1] !== points[i - 1][1]) {
898
+ result += ` V ${points[i][1]}`;
899
+ currentDirection = points[i][1] > points[i - 1][1] ? Side.Bottom : Side.Top;
900
+ }
901
+ }
902
+ break;
903
+ }
904
+ break;
905
+ default:
906
+ if (points[i][0] !== points[i - 1][0]) {
907
+ result += ` H ${points[i][0]}`;
908
+ currentDirection = points[i][0] > points[i - 1][0] ? Side.Right : Side.Left;
909
+ }
910
+ if (points[i][1] !== points[i - 1][1]) {
911
+ result += ` V ${points[i][1]}`;
912
+ currentDirection = points[i][1] > points[i - 1][1] ? Side.Bottom : Side.Top;
913
+ }
610
914
  }
611
915
  }
612
916
  break;
@@ -904,13 +1208,14 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
904
1208
  const extractLooksFromConfig = lookConfig => {
905
1209
  const {
906
1210
  selected,
907
- highlighted
1211
+ highlighted,
1212
+ selectedAndHighlighted
908
1213
  } = lookConfig,
909
- rest = __rest(lookConfig, ["selected", "highlighted"]);
1214
+ rest = __rest(lookConfig, ["selected", "highlighted", "selectedAndHighlighted"]);
910
1215
  const defaultLook = rest;
911
1216
  const selectedLook = Object.assign(Object.assign({}, defaultLook), selected);
912
1217
  const highlightedLook = Object.assign(Object.assign({}, defaultLook), highlighted);
913
- const selectedAndHighlightedLook = Object.assign(Object.assign(Object.assign({}, defaultLook), highlighted), selected);
1218
+ const selectedAndHighlightedLook = Object.assign(Object.assign(Object.assign(Object.assign({}, defaultLook), highlighted), selected), selectedAndHighlighted);
914
1219
  return {
915
1220
  defaultLook,
916
1221
  selectedLook,
@@ -3088,6 +3393,7 @@ const DIAGRAM_NODE_TYPE_DEFAULTS = {
3088
3393
  minHeight: 1,
3089
3394
  resizableX: false,
3090
3395
  resizableY: false,
3396
+ snapToGridOffset: [0, 0, 0, 0],
3091
3397
  padding: 0,
3092
3398
  label: null,
3093
3399
  ports: [],
@@ -3116,6 +3422,7 @@ class DiagramNodeType {
3116
3422
  this.minHeight = values.minHeight;
3117
3423
  this.resizableX = values.resizableX;
3118
3424
  this.resizableY = values.resizableY;
3425
+ this.snapToGridOffset = values.snapToGridOffset;
3119
3426
  this.bottomPadding = getBottomPadding(values);
3120
3427
  this.leftPadding = getLeftPadding(values);
3121
3428
  this.rightPadding = getRightPadding(values);
@@ -7489,7 +7796,9 @@ class DiagramCanvas {
7489
7796
  if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
7490
7797
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7491
7798
  if (this.snapToGrid) {
7492
- pointerCoords = this.getClosestGridPoint(pointerCoords);
7799
+ pointerCoords = this.getClosestGridPoint([pointerCoords[0] - d.type.snapToGridOffset[0], pointerCoords[1] - d.type.snapToGridOffset[1]]);
7800
+ pointerCoords[0] += d.type.snapToGridOffset[0];
7801
+ pointerCoords[1] += d.type.snapToGridOffset[1];
7493
7802
  }
7494
7803
  d.stretch(Side.Left, d.coords[0] - pointerCoords[0]);
7495
7804
  this.currentAction.to = d.getGeometry();
@@ -7523,7 +7832,9 @@ class DiagramCanvas {
7523
7832
  if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
7524
7833
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7525
7834
  if (this.snapToGrid) {
7526
- pointerCoords = this.getClosestGridPoint(pointerCoords);
7835
+ pointerCoords = this.getClosestGridPoint([pointerCoords[0] - d.type.snapToGridOffset[0], pointerCoords[1] - d.type.snapToGridOffset[1]]);
7836
+ pointerCoords[0] += d.type.snapToGridOffset[0];
7837
+ pointerCoords[1] += d.type.snapToGridOffset[1];
7527
7838
  }
7528
7839
  d.stretch(Side.Top, d.coords[1] - pointerCoords[1]);
7529
7840
  this.currentAction.to = d.getGeometry();
@@ -7557,7 +7868,9 @@ class DiagramCanvas {
7557
7868
  if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableX && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
7558
7869
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7559
7870
  if (this.snapToGrid) {
7560
- pointerCoords = this.getClosestGridPoint(pointerCoords);
7871
+ pointerCoords = this.getClosestGridPoint([pointerCoords[0] - d.type.snapToGridOffset[2], pointerCoords[1] - d.type.snapToGridOffset[3]]);
7872
+ pointerCoords[0] += d.type.snapToGridOffset[2];
7873
+ pointerCoords[1] += d.type.snapToGridOffset[3];
7561
7874
  }
7562
7875
  d.stretch(Side.Right, pointerCoords[0] - (d.coords[0] + d.width));
7563
7876
  this.currentAction.to = d.getGeometry();
@@ -7591,7 +7904,11 @@ class DiagramCanvas {
7591
7904
  if (this.canUserPerformAction(DiagramActions.StretchNode) && d.type.resizableY && !d.removed && this.currentAction instanceof SetGeometryAction && this.currentAction.intent === DiagramActions.StretchNode) {
7592
7905
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
7593
7906
  if (this.snapToGrid) {
7594
- pointerCoords = this.getClosestGridPoint(pointerCoords);
7907
+ if (this.snapToGrid) {
7908
+ pointerCoords = this.getClosestGridPoint([pointerCoords[0] - d.type.snapToGridOffset[2], pointerCoords[1] - d.type.snapToGridOffset[3]]);
7909
+ pointerCoords[0] += d.type.snapToGridOffset[2];
7910
+ pointerCoords[1] += d.type.snapToGridOffset[3];
7911
+ }
7595
7912
  }
7596
7913
  d.stretch(Side.Bottom, pointerCoords[1] - (d.coords[1] + d.height));
7597
7914
  this.currentAction.to = d.getGeometry();
@@ -8841,7 +9158,9 @@ class DiagramCanvas {
8841
9158
  if (this.draggingFrom[0] !== event.x || this.draggingFrom[1] !== event.y) {
8842
9159
  let newNodeCoords = [event.x - d.width / 2, event.y - d.height / 2];
8843
9160
  if (this.snapToGrid) {
8844
- newNodeCoords = this.getClosestGridPoint(newNodeCoords);
9161
+ newNodeCoords = this.getClosestGridPoint([newNodeCoords[0] - d.type.snapToGridOffset[0], newNodeCoords[1] - d.type.snapToGridOffset[1]]);
9162
+ newNodeCoords[0] += d.type.snapToGridOffset[0];
9163
+ newNodeCoords[1] += d.type.snapToGridOffset[1];
8845
9164
  }
8846
9165
  if (this.currentAction instanceof MoveAction) {
8847
9166
  const movingFrom = this.currentAction.delta;
@@ -9535,7 +9854,9 @@ class ForceLayout {
9535
9854
  }
9536
9855
  if (model.canvas && model.canvas.snapToGrid) {
9537
9856
  for (const node of model.nodes) {
9538
- const snappedCoords = model.canvas.getClosestGridPoint(node.coords);
9857
+ const snappedCoords = model.canvas.getClosestGridPoint([node.coords[0] - node.type.snapToGridOffset[0], node.coords[1] - node.type.snapToGridOffset[1]]);
9858
+ snappedCoords[0] += node.type.snapToGridOffset[0];
9859
+ snappedCoords[1] += node.type.snapToGridOffset[1];
9539
9860
  node.move(snappedCoords);
9540
9861
  }
9541
9862
  }