@mx-sose-front/mx-sose-graph 1.0.0

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.
Files changed (337) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +343 -0
  3. package/dist/index.d.ts +3937 -0
  4. package/dist/index.esm.js +74367 -0
  5. package/dist/index.esm.js.map +1 -0
  6. package/dist/index.umd.js +38 -0
  7. package/dist/index.umd.js.map +1 -0
  8. package/dist/style.css +1 -0
  9. package/package.json +70 -0
  10. package/src/components/ContextMenu.vue +475 -0
  11. package/src/components/Diagram/StrategicTaxonomyDiagram.vue +141 -0
  12. package/src/components/Edge/Edge.vue +366 -0
  13. package/src/components/InteractionLayer.vue +2033 -0
  14. package/src/components/Label.vue +0 -0
  15. package/src/components/LineStyle/ConnectionLine.vue +126 -0
  16. package/src/components/LineStyle/LineStyleMarker.vue +87 -0
  17. package/src/components/Pin/Pin.vue +220 -0
  18. package/src/components/Pin/Port.vue +172 -0
  19. package/src/components/Shape/Action.vue +121 -0
  20. package/src/components/Shape/ActivityAction.vue +155 -0
  21. package/src/components/Shape/Block.vue +306 -0
  22. package/src/components/Shape/ConceptualRole.vue +266 -0
  23. package/src/components/Shape/Diagram.vue +220 -0
  24. package/src/components/Shape/DividingLine.vue +594 -0
  25. package/src/components/Shape/DogEar.vue +224 -0
  26. package/src/components/Shape/Package.vue +340 -0
  27. package/src/constants/edgeShapeKeys.ts +81 -0
  28. package/src/constants/index.ts +440 -0
  29. package/src/index.ts +28 -0
  30. package/src/render/shape-registry.ts +17 -0
  31. package/src/render/shape-renderer.ts +103 -0
  32. package/src/statics/icons/childIcons/relations@3x.png +0 -0
  33. package/src/statics/icons/childIcons/role@3x.png +0 -0
  34. package/src/statics/icons/childIcons//344/270/232/345/212/241/344/277/241/345/217/267@3x.png +0 -0
  35. package/src/statics/icons/childIcons//344/270/232/345/212/241/344/277/241/346/201/257@3x.png +0 -0
  36. package/src/statics/icons/childIcons//344/270/232/345/212/241/344/277/241/346/201/257/345/233/276@3x.png +0 -0
  37. package/src/statics/icons/childIcons//344/270/232/345/212/241/345/206/205/351/203/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  38. package/src/statics/icons/childIcons//344/270/232/345/212/241/345/206/205/351/203/250/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  39. package/src/statics/icons/childIcons//344/270/232/345/212/241/345/212/250/344/275/234@3x.png +0 -0
  40. package/src/statics/icons/childIcons//344/270/232/345/212/241/345/217/202/346/225/260@3x.png +0 -0
  41. package/src/statics/icons/childIcons//344/270/232/345/212/241/345/217/202/346/225/260/345/233/276@3x.png +0 -0
  42. package/src/statics/icons/childIcons//344/270/232/345/212/241/345/257/271/350/261/241/346/265/201@3x.png +0 -0
  43. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/211/247/350/241/214/350/200/205@3x.png +0 -0
  44. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/216/245/345/217/243@3x.png +0 -0
  45. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/216/247/345/210/266/346/265/201@3x.png +0 -0
  46. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  47. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  48. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/264/273/345/212/250@3x.png +0 -0
  49. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/264/273/345/212/250/344/270/216/350/203/275/345/212/233/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  50. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/264/273/345/212/250/345/212/250/344/275/234@3x.png +0 -0
  51. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/264/273/345/212/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  52. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/264/273/345/212/250/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  53. package/src/statics/icons/childIcons//344/270/232/345/212/241/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  54. package/src/statics/icons/childIcons//344/270/232/345/212/241/347/212/266/346/200/201/345/233/276@3x.png +0 -0
  55. package/src/statics/icons/childIcons//344/270/232/345/212/241/347/253/257/345/217/243@3x.png +0 -0
  56. package/src/statics/icons/childIcons//344/270/232/345/212/241/347/272/246/346/235/237@3x.png +0 -0
  57. package/src/statics/icons/childIcons//344/270/232/345/212/241/347/272/246/346/235/237/345/233/276@3x.png +0 -0
  58. package/src/statics/icons/childIcons//344/270/232/345/212/241/347/272/246/346/235/237/345/256/232/344/271/211/345/233/276@3x.png +0 -0
  59. package/src/statics/icons/childIcons//344/270/232/345/212/241/347/272/246/346/235/237/350/241/250@3x.png +0 -0
  60. package/src/statics/icons/childIcons//344/270/232/345/212/241/347/273/223/346/236/204@3x.png +0 -0
  61. package/src/statics/icons/childIcons//344/270/232/345/212/241/350/207/252/347/224/261/345/210/206/347/261/273/345/233/276@3x.png +0 -0
  62. package/src/statics/icons/childIcons//344/270/232/345/212/241/350/247/222/350/211/262@3x.png +0 -0
  63. package/src/statics/icons/childIcons//344/270/232/345/212/241/350/277/236/346/216/245/345/231/250@3x.png +0 -0
  64. package/src/statics/icons/childIcons//344/270/232/345/212/241/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  65. package/src/statics/icons/childIcons//344/270/232/345/212/241/350/277/236/351/200/232/350/241/250@3x.png +0 -0
  66. package/src/statics/icons/childIcons//344/270/232/345/212/241/351/253/230/347/272/247/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  67. package/src/statics/icons/childIcons//344/272/272/345/221/230@3x.png +0 -0
  68. package/src/statics/icons/childIcons//344/272/272/345/221/230/345/206/205/351/203/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  69. package/src/statics/icons/childIcons//344/272/272/345/221/230/345/206/205/351/203/250/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  70. package/src/statics/icons/childIcons//344/272/272/345/221/230/345/217/202/346/225/260/345/233/276@3x.png +0 -0
  71. package/src/statics/icons/childIcons//344/272/272/345/221/230/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  72. package/src/statics/icons/childIcons//344/272/272/345/221/230/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  73. package/src/statics/icons/childIcons//344/272/272/345/221/230/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  74. package/src/statics/icons/childIcons//344/272/272/345/221/230/347/212/266/346/200/201/345/233/276@3x.png +0 -0
  75. package/src/statics/icons/childIcons//344/272/272/345/221/230/347/272/246/346/235/237/345/233/276@3x-2.png +0 -0
  76. package/src/statics/icons/childIcons//344/272/272/345/221/230/347/272/246/346/235/237/345/233/276@3x.png +0 -0
  77. package/src/statics/icons/childIcons//344/272/272/345/221/230/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  78. package/src/statics/icons/childIcons//344/272/272/345/221/230/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  79. package/src/statics/icons/childIcons//344/272/272/345/221/230/350/277/236/351/200/232/350/241/250@3x.png +0 -0
  80. package/src/statics/icons/childIcons//344/273/267/345/200/274/346/265/201@3x.png +0 -0
  81. package/src/statics/icons/childIcons//344/273/273/346/204/217/345/205/263/347/263/273@3x.png +0 -0
  82. package/src/statics/icons/childIcons//344/273/273/346/204/217/350/277/236/346/216/245/345/231/250@3x.png +0 -0
  83. package/src/statics/icons/childIcons//344/274/201/344/270/232/344/275/277/345/221/275@3x.png +0 -0
  84. package/src/statics/icons/childIcons//344/274/201/344/270/232/345/205/250/347/224/237/345/221/275/345/221/250/346/234/237@3x.png +0 -0
  85. package/src/statics/icons/childIcons//344/274/201/344/270/232/346/204/277/346/231/257@3x.png +0 -0
  86. package/src/statics/icons/childIcons//344/274/201/344/270/232/347/233/256/346/240/207@3x.png +0 -0
  87. package/src/statics/icons/childIcons//344/275/215/347/275/256@3x.png +0 -0
  88. package/src/statics/icons/childIcons//344/275/223/347/263/273/346/236/266/346/236/204@3x.png +0 -0
  89. package/src/statics/icons/childIcons//344/276/235/350/265/226@3x.png +0 -0
  90. package/src/statics/icons/childIcons//344/277/235/346/212/244@3x.png +0 -0
  91. package/src/statics/icons/childIcons//344/277/241/346/201/257/346/250/241/345/236/213@3x.png +0 -0
  92. package/src/statics/icons/childIcons//345/210/233/351/200/240@3x.png +0 -0
  93. package/src/statics/icons/childIcons//345/212/237/350/203/275@3x.png +0 -0
  94. package/src/statics/icons/childIcons//345/212/237/350/203/275/344/270/216/344/270/232/345/212/241/346/264/273/345/212/250/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  95. package/src/statics/icons/childIcons//345/212/237/350/203/275/345/212/250/344/275/234@3x.png +0 -0
  96. package/src/statics/icons/childIcons//345/212/237/350/203/275/345/257/271/350/261/241/346/265/201@3x.png +0 -0
  97. package/src/statics/icons/childIcons//345/212/237/350/203/275/346/216/247/345/210/266/346/265/201@3x.png +0 -0
  98. package/src/statics/icons/childIcons//345/217/214/345/220/221/345/205/263/350/201/224@3x.png +0 -0
  99. package/src/statics/icons/childIcons//345/217/227/345/210/260/345/275/261/345/223/215@3x.png +0 -0
  100. package/src/statics/icons/childIcons//345/234/260/347/220/206/346/224/277/346/262/273/350/214/203/345/233/264/347/261/273/345/236/213@3x.png +0 -0
  101. package/src/statics/icons/childIcons//345/241/253/345/206/231/350/201/214/344/275/215/347/224/263/350/257/267@3x.png +0 -0
  102. package/src/statics/icons/childIcons//345/256/211/345/205/250/345/206/205/351/203/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  103. package/src/statics/icons/childIcons//345/256/211/345/205/250/346/216/247/345/210/266@3x.png +0 -0
  104. package/src/statics/icons/childIcons//345/256/211/345/205/250/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  105. package/src/statics/icons/childIcons//345/256/211/345/205/250/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  106. package/src/statics/icons/childIcons//345/256/211/345/205/250/346/265/201/347/250/213@3x.png +0 -0
  107. package/src/statics/icons/childIcons//345/256/211/345/205/250/346/265/201/347/250/213/345/212/250/344/275/234@3x.png +0 -0
  108. package/src/statics/icons/childIcons//345/256/211/345/205/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  109. package/src/statics/icons/childIcons//345/256/211/345/205/250/347/272/246/346/235/237@3x.png +0 -0
  110. package/src/statics/icons/childIcons//345/256/211/345/205/250/347/272/246/346/235/237/345/233/276@3x.png +0 -0
  111. package/src/statics/icons/childIcons//345/256/211/345/205/250/347/272/246/346/235/237/345/256/232/344/271/211/345/233/276@3x.png +0 -0
  112. package/src/statics/icons/childIcons//345/256/211/345/205/250/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  113. package/src/statics/icons/childIcons//345/256/211/345/205/250/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  114. package/src/statics/icons/childIcons//345/256/211/345/205/250/350/277/236/351/200/232/350/241/250@3x.png +0 -0
  115. package/src/statics/icons/childIcons//345/256/211/345/205/250/351/232/224/347/246/273@3x.png +0 -0
  116. package/src/statics/icons/childIcons//345/256/211/345/205/250/351/243/216/351/231/251@3x.png +0 -0
  117. package/src/statics/icons/childIcons//345/256/232/345/220/221/345/205/263/347/263/273@3x.png +0 -0
  118. package/src/statics/icons/childIcons//345/256/232/345/220/221/345/205/263/350/201/224@3x.png +0 -0
  119. package/src/statics/icons/childIcons//345/256/232/345/220/221/347/273/204/346/210/220@3x.png +0 -0
  120. package/src/statics/icons/childIcons//345/256/232/345/220/221/350/201/232/345/220/210@3x.png +0 -0
  121. package/src/statics/icons/childIcons//345/256/236/351/231/205/344/272/272/345/221/230@3x.png +0 -0
  122. package/src/statics/icons/childIcons//345/256/236/351/231/205/344/274/201/344/270/232/351/230/266/346/256/265@3x.png +0 -0
  123. package/src/statics/icons/childIcons//345/256/236/351/231/205/344/275/215/347/275/256@3x.png +0 -0
  124. package/src/statics/icons/childIcons//345/256/236/351/231/205/345/261/236/346/200/247/350/256/276/347/275/256@3x.png +0 -0
  125. package/src/statics/icons/childIcons//345/256/236/351/231/205/346/210/230/347/225/245/351/230/266/346/256/265/347/224/230/347/211/271/345/233/276@3x.png +0 -0
  126. package/src/statics/icons/childIcons//345/256/236/351/231/205/346/214/201/347/273/255/344/273/273/345/212/241@3x.png +0 -0
  127. package/src/statics/icons/childIcons//345/256/236/351/231/205/346/234/215/345/212/241@3x.png +0 -0
  128. package/src/statics/icons/childIcons//345/256/236/351/231/205/346/235/241/344/273/266@3x.png +0 -0
  129. package/src/statics/icons/childIcons//345/256/236/351/231/205/347/216/257/345/242/203@3x.png +0 -0
  130. package/src/statics/icons/childIcons//345/256/236/351/231/205/347/273/204/347/273/207@3x.png +0 -0
  131. package/src/statics/icons/childIcons//345/256/236/351/231/205/350/201/214/344/275/215@3x.png +0 -0
  132. package/src/statics/icons/childIcons//345/256/236/351/231/205/350/201/214/350/264/243@3x.png +0 -0
  133. package/src/statics/icons/childIcons//345/256/236/351/231/205/350/264/243/344/273/273@3x.png +0 -0
  134. package/src/statics/icons/childIcons//345/256/236/351/231/205/350/265/204/346/272/220@3x.png +0 -0
  135. package/src/statics/icons/childIcons//345/256/236/351/231/205/350/265/204/346/272/220/344/270/216/345/256/236/351/231/205/351/241/271/347/233/256/345/257/271/345/272/224/345/205/263/347/263/273/347/237/251/351/230/265@3x.png +0 -0
  136. package/src/statics/icons/childIcons//345/256/236/351/231/205/350/265/204/346/272/220/346/246/202/345/277/265/347/237/251/351/230/265@3x.png +0 -0
  137. package/src/statics/icons/childIcons//345/256/236/351/231/205/350/265/204/346/272/220/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  138. package/src/statics/icons/childIcons//345/256/236/351/231/205/350/265/204/346/272/220/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  139. package/src/statics/icons/childIcons//345/256/236/351/231/205/351/241/271/347/233/256@3x.png +0 -0
  140. package/src/statics/icons/childIcons//345/256/236/351/231/205/351/241/271/347/233/256/344/270/216/350/203/275/345/212/233/347/232/204/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  141. package/src/statics/icons/childIcons//345/256/236/351/231/205/351/241/271/347/233/256/351/207/214/347/250/213/347/242/221@3x.png +0 -0
  142. package/src/statics/icons/childIcons//345/256/236/351/231/205/351/241/271/347/233/256/351/207/214/347/250/213/347/242/221/346/261/207/346/200/273/350/241/250@3x.png +0 -0
  143. package/src/statics/icons/childIcons//345/256/236/351/231/205/351/243/216/351/231/251@3x.png +0 -0
  144. package/src/statics/icons/childIcons//345/261/225/347/244/272@3x.png +0 -0
  145. package/src/statics/icons/childIcons//345/267/262/347/237/245/350/265/204/346/272/220@3x.png +0 -0
  146. package/src/statics/icons/childIcons//345/274/200/345/261/225/345/267/245/344/275/234/350/203/275/345/212/233@3x.png +0 -0
  147. package/src/statics/icons/childIcons//345/274/225/347/224/250/345/261/236/346/200/247@3x.png +0 -0
  148. package/src/statics/icons/childIcons//345/275/261/345/223/215@3x-2.png +0 -0
  149. package/src/statics/icons/childIcons//345/275/261/345/223/215@3x.png +0 -0
  150. package/src/statics/icons/childIcons//346/204/277/346/231/257/345/256/243/350/250/200@3x.png +0 -0
  151. package/src/statics/icons/childIcons//346/210/230/347/225/245@3x.png +0 -0
  152. package/src/statics/icons/childIcons//346/210/230/347/225/245/344/277/241/346/201/257@3x.png +0 -0
  153. package/src/statics/icons/childIcons//346/210/230/347/225/245/344/277/241/346/201/257/345/233/276@3x-2.png +0 -0
  154. package/src/statics/icons/childIcons//346/210/230/347/225/245/344/277/241/346/201/257/345/233/276@3x.png +0 -0
  155. package/src/statics/icons/childIcons//346/210/230/347/225/245/345/217/202/346/225/260/345/233/276@3x.png +0 -0
  156. package/src/statics/icons/childIcons//346/210/230/347/225/245/345/256/236/351/231/205/346/210/230/347/225/245/351/230/266/346/256/265/345/210/206/347/261/273/350/241/250@3x.png +0 -0
  157. package/src/statics/icons/childIcons//346/210/230/347/225/245/345/256/236/351/231/205/351/203/250/347/275/262/345/233/276@3x.png +0 -0
  158. package/src/statics/icons/childIcons//346/210/230/347/225/245/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  159. package/src/statics/icons/childIcons//346/210/230/347/225/245/346/265/201/347/250/213/345/233/276@3x-2.png +0 -0
  160. package/src/statics/icons/childIcons//346/210/230/347/225/245/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  161. package/src/statics/icons/childIcons//346/210/230/347/225/245/347/212/266/346/200/201/345/233/276@3x.png +0 -0
  162. package/src/statics/icons/childIcons//346/210/230/347/225/245/347/272/246/346/235/237@3x.png +0 -0
  163. package/src/statics/icons/childIcons//346/210/230/347/225/245/347/272/246/346/235/237/345/233/276@3x.png +0 -0
  164. package/src/statics/icons/childIcons//346/210/230/347/225/245/347/272/246/346/235/237/345/256/232/344/271/211/345/233/276@3x.png +0 -0
  165. package/src/statics/icons/childIcons//346/210/230/347/225/245/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  166. package/src/statics/icons/childIcons//346/210/230/347/225/245/350/277/236/351/200/232/345/233/276@3x-2.png +0 -0
  167. package/src/statics/icons/childIcons//346/210/230/347/225/245/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  168. package/src/statics/icons/childIcons//346/210/230/347/225/245/350/277/236/351/200/232/347/237/251/351/230/265@3x-2.png +0 -0
  169. package/src/statics/icons/childIcons//346/210/230/347/225/245/350/277/236/351/200/232/347/237/251/351/230/265@3x.png +0 -0
  170. package/src/statics/icons/childIcons//346/210/230/347/225/245/351/230/266/346/256/265@3x.png +0 -0
  171. package/src/statics/icons/childIcons//346/211/247/350/241/214@3x.png +0 -0
  172. package/src/statics/icons/childIcons//346/211/247/350/241/214/350/200/205/345/206/205/351/203/250/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  173. package/src/statics/icons/childIcons//346/211/247/350/241/214/350/200/205/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  174. package/src/statics/icons/childIcons//346/211/247/350/241/214/350/200/205/347/273/223/346/236/204/345/233/276@3x-2.png +0 -0
  175. package/src/statics/icons/childIcons//346/211/247/350/241/214/350/200/205/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  176. package/src/statics/icons/childIcons//346/211/247/350/241/214/350/200/205/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  177. package/src/statics/icons/childIcons//346/211/277/346/213/205/351/243/216/351/231/251@3x.png +0 -0
  178. package/src/statics/icons/childIcons//346/212/200/346/234/257@3x.png +0 -0
  179. package/src/statics/icons/childIcons//346/213/245/346/234/211/346/265/201/347/250/213@3x.png +0 -0
  180. package/src/statics/icons/childIcons//346/217/220/344/276/233/346/235/203/351/231/220@3x.png +0 -0
  181. package/src/statics/icons/childIcons//346/227/266/346/234/272@3x.png +0 -0
  182. package/src/statics/icons/childIcons//346/234/215/345/212/241@3x.png +0 -0
  183. package/src/statics/icons/childIcons//346/234/215/345/212/241/344/270/216/344/270/232/345/212/241/346/264/273/345/212/250/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  184. package/src/statics/icons/childIcons//346/234/215/345/212/241/344/270/216/346/234/215/345/212/241/345/220/210/345/220/214/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  185. package/src/statics/icons/childIcons//346/234/215/345/212/241/344/270/216/350/203/275/345/212/233/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  186. package/src/statics/icons/childIcons//346/234/215/345/212/241/344/277/241/345/217/267@3x.png +0 -0
  187. package/src/statics/icons/childIcons//346/234/215/345/212/241/345/206/205/351/203/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  188. package/src/statics/icons/childIcons//346/234/215/345/212/241/345/206/205/351/203/250/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  189. package/src/statics/icons/childIcons//346/234/215/345/212/241/345/212/237/350/203/275@3x.png +0 -0
  190. package/src/statics/icons/childIcons//346/234/215/345/212/241/345/212/237/350/203/275/345/212/250/344/275/234@3x.png +0 -0
  191. package/src/statics/icons/childIcons//346/234/215/345/212/241/345/212/250/344/275/234@3x.png +0 -0
  192. package/src/statics/icons/childIcons//346/234/215/345/212/241/345/217/202/346/225/260@3x.png +0 -0
  193. package/src/statics/icons/childIcons//346/234/215/345/212/241/345/217/202/346/225/260/345/233/276@3x.png +0 -0
  194. package/src/statics/icons/childIcons//346/234/215/345/212/241/345/257/271/350/261/241/346/265/201@3x.png +0 -0
  195. package/src/statics/icons/childIcons//346/234/215/345/212/241/346/216/245/345/217/243@3x.png +0 -0
  196. package/src/statics/icons/childIcons//346/234/215/345/212/241/346/216/247/345/210/266/346/265/201@3x.png +0 -0
  197. package/src/statics/icons/childIcons//346/234/215/345/212/241/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  198. package/src/statics/icons/childIcons//346/234/215/345/212/241/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  199. package/src/statics/icons/childIcons//346/234/215/345/212/241/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  200. package/src/statics/icons/childIcons//346/234/215/345/212/241/347/212/266/346/200/201/345/233/276@3x.png +0 -0
  201. package/src/statics/icons/childIcons//346/234/215/345/212/241/347/253/257/345/217/243@3x.png +0 -0
  202. package/src/statics/icons/childIcons//346/234/215/345/212/241/347/272/246/346/235/237/345/233/276@3x.png +0 -0
  203. package/src/statics/icons/childIcons//346/234/215/345/212/241/347/272/246/346/235/237/345/256/232/344/271/211/345/233/276@3x.png +0 -0
  204. package/src/statics/icons/childIcons//346/234/215/345/212/241/347/273/223/346/236/204@3x.png +0 -0
  205. package/src/statics/icons/childIcons//346/234/215/345/212/241/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  206. package/src/statics/icons/childIcons//346/234/215/345/212/241/350/247/222/350/211/262@3x.png +0 -0
  207. package/src/statics/icons/childIcons//346/234/215/345/212/241/350/267/257/347/272/277/345/233/276@3x.png +0 -0
  208. package/src/statics/icons/childIcons//346/234/215/345/212/241/350/277/236/346/216/245/345/231/250@3x.png +0 -0
  209. package/src/statics/icons/childIcons//346/234/215/345/212/241/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  210. package/src/statics/icons/childIcons//346/234/215/345/212/241/350/277/236/351/200/232/350/241/250@3x-2.png +0 -0
  211. package/src/statics/icons/childIcons//346/234/215/345/212/241/350/277/236/351/200/232/350/241/250@3x.png +0 -0
  212. package/src/statics/icons/childIcons//346/235/203/351/231/220@3x.png +0 -0
  213. package/src/statics/icons/childIcons//346/235/241/344/273/266@3x.png +0 -0
  214. package/src/statics/icons/childIcons//346/240/207/345/207/206/344/270/232/345/212/241/346/264/273/345/212/250@3x.png +0 -0
  215. package/src/statics/icons/childIcons//346/240/207/345/207/206/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  216. package/src/statics/icons/childIcons//346/240/207/345/207/206/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  217. package/src/statics/icons/childIcons//346/240/207/345/207/206/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  218. package/src/statics/icons/childIcons//346/240/207/345/207/206/350/267/257/347/272/277/345/233/276@3x.png +0 -0
  219. package/src/statics/icons/childIcons//346/240/207/345/207/206/350/277/275/346/272/257/345/233/276@3x.png +0 -0
  220. package/src/statics/icons/childIcons//346/246/202/345/277/265/350/247/222/350/211/262@3x.png +0 -0
  221. package/src/statics/icons/childIcons//346/263/233/345/214/226@3x.png +0 -0
  222. package/src/statics/icons/childIcons//347/212/266/345/206/265@3x.png +0 -0
  223. package/src/statics/icons/childIcons//347/216/257/345/242/203@3x.png +0 -0
  224. package/src/statics/icons/childIcons//347/233/270/346/257/224@3x (1).png +0 -0
  225. package/src/statics/icons/childIcons//347/263/273/347/273/237@3x.png +0 -0
  226. package/src/statics/icons/childIcons//347/273/204/346/210/220@3x.png +0 -0
  227. package/src/statics/icons/childIcons//347/273/204/347/273/207@3x.png +0 -0
  228. package/src/statics/icons/childIcons//347/273/204/347/273/207/351/230/266/346/256/265@3x.png +0 -0
  229. package/src/statics/icons/childIcons//347/273/221/345/256/232/350/277/236/346/216/245/345/231/250@3x.png +0 -0
  230. package/src/statics/icons/childIcons//347/274/223/350/247/243@3x.png +0 -0
  231. package/src/statics/icons/childIcons//350/201/214/344/275/215@3x.png +0 -0
  232. package/src/statics/icons/childIcons//350/201/232/345/220/210@3x.png +0 -0
  233. package/src/statics/icons/childIcons//350/203/275/345/212/233@3x.png +0 -0
  234. package/src/statics/icons/childIcons//350/203/275/345/212/233/350/201/214/350/264/243@3x.png +0 -0
  235. package/src/statics/icons/childIcons//350/203/275/345/212/233/351/205/215/347/275/256@3x.png +0 -0
  236. package/src/statics/icons/childIcons//350/203/275/345/244/237/350/203/234/344/273/273@3x.png +0 -0
  237. package/src/statics/icons/childIcons//350/207/252/347/204/266/350/265/204/346/272/220@3x.png +0 -0
  238. package/src/statics/icons/childIcons//350/246/201/346/261/202@3x.png +0 -0
  239. package/src/statics/icons/childIcons//350/256/276/347/275/256/347/261/273/345/236/213.png +0 -0
  240. package/src/statics/icons/childIcons//350/264/237/350/264/243@3x.png +0 -0
  241. package/src/statics/icons/childIcons//350/264/243/344/273/273@3x.png +0 -0
  242. package/src/statics/icons/childIcons//350/265/204/344/272/247/351/243/216/351/231/251/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  243. package/src/statics/icons/childIcons//350/265/204/346/272/220/344/270/216/344/270/232/345/212/241/346/264/273/345/212/250/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  244. package/src/statics/icons/childIcons//350/265/204/346/272/220/344/270/216/350/203/275/345/212/233/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  245. package/src/statics/icons/childIcons//350/265/204/346/272/220/344/277/241/345/217/267@3x.png +0 -0
  246. package/src/statics/icons/childIcons//350/265/204/346/272/220/344/277/241/346/201/257@3x.png +0 -0
  247. package/src/statics/icons/childIcons//350/265/204/346/272/220/344/277/241/346/201/257/345/233/276@3x.png +0 -0
  248. package/src/statics/icons/childIcons//350/265/204/346/272/220/345/206/205/351/203/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  249. package/src/statics/icons/childIcons//350/265/204/346/272/220/345/206/205/351/203/250/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  250. package/src/statics/icons/childIcons//350/265/204/346/272/220/345/212/250/344/275/234@3x.png +0 -0
  251. package/src/statics/icons/childIcons//350/265/204/346/272/220/345/217/202/346/225/260@3x.png +0 -0
  252. package/src/statics/icons/childIcons//350/265/204/346/272/220/345/217/202/346/225/260/345/233/276@3x.png +0 -0
  253. package/src/statics/icons/childIcons//350/265/204/346/272/220/345/267/245/344/273/266@3x.png +0 -0
  254. package/src/statics/icons/childIcons//350/265/204/346/272/220/346/216/245/345/217/243@3x.png +0 -0
  255. package/src/statics/icons/childIcons//350/265/204/346/272/220/346/234/215/345/212/241@3x.png +0 -0
  256. package/src/statics/icons/childIcons//350/265/204/346/272/220/346/236/266/346/236/204@3x.png +0 -0
  257. package/src/statics/icons/childIcons//350/265/204/346/272/220/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  258. package/src/statics/icons/childIcons//350/265/204/346/272/220/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  259. package/src/statics/icons/childIcons//350/265/204/346/272/220/346/264/273/345/212/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  260. package/src/statics/icons/childIcons//350/265/204/346/272/220/346/264/273/345/212/250/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  261. package/src/statics/icons/childIcons//350/265/204/346/272/220/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  262. package/src/statics/icons/childIcons//350/265/204/346/272/220/347/212/266/346/200/201/345/233/276@3x.png +0 -0
  263. package/src/statics/icons/childIcons//350/265/204/346/272/220/347/253/257/345/217/243@3x.png +0 -0
  264. package/src/statics/icons/childIcons//350/265/204/346/272/220/347/272/246/346/235/237@3x.png +0 -0
  265. package/src/statics/icons/childIcons//350/265/204/346/272/220/347/273/223/346/236/204@3x.png +0 -0
  266. package/src/statics/icons/childIcons//350/265/204/346/272/220/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  267. package/src/statics/icons/childIcons//350/265/204/346/272/220/347/274/223/350/247/243/346/216/252/346/226/275@3x.png +0 -0
  268. package/src/statics/icons/childIcons//350/265/204/346/272/220/350/247/222/350/211/262@3x.png +0 -0
  269. package/src/statics/icons/childIcons//350/265/204/346/272/220/350/277/236/346/216/245/345/231/250@3x.png +0 -0
  270. package/src/statics/icons/childIcons//350/265/204/346/272/220/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  271. package/src/statics/icons/childIcons//350/265/204/346/272/220/350/277/236/351/200/232/350/241/250@3x.png +0 -0
  272. package/src/statics/icons/childIcons//350/275/257/344/273/266@3x.png +0 -0
  273. package/src/statics/icons/childIcons//350/276/223/345/205/245/346/240/223@3x.png +0 -0
  274. package/src/statics/icons/childIcons//350/276/223/345/207/272/346/240/223@3x.png +0 -0
  275. package/src/statics/icons/childIcons//350/276/276/345/210/260@3x.png +0 -0
  276. package/src/statics/icons/childIcons//350/277/236/346/216/245/345/231/250@3x.png +0 -0
  277. package/src/statics/icons/childIcons//350/277/236/347/272/277@3x.png +0 -0
  278. package/src/statics/icons/childIcons//351/207/214/347/250/213/347/242/221/344/276/235/350/265/226@3x.png +0 -0
  279. package/src/statics/icons/childIcons//351/230/266/346/256/265@3x.png +0 -0
  280. package/src/statics/icons/childIcons//351/234/200/346/261/202/346/235/203/351/231/220@3x.png +0 -0
  281. package/src/statics/icons/childIcons//351/241/266/347/272/247/344/270/232/345/212/241/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  282. package/src/statics/icons/childIcons//351/241/271/347/233/256@3x.png +0 -0
  283. package/src/statics/icons/childIcons//351/241/271/347/233/256/344/270/273/351/242/230@3x.png +0 -0
  284. package/src/statics/icons/childIcons//351/241/271/347/233/256/345/206/205/351/203/250/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  285. package/src/statics/icons/childIcons//351/241/271/347/233/256/346/246/202/345/277/265/345/233/276@3x.png +0 -0
  286. package/src/statics/icons/childIcons//351/241/271/347/233/256/346/246/202/345/277/265/350/241/250@3x.png +0 -0
  287. package/src/statics/icons/childIcons//351/241/271/347/233/256/346/264/273/345/212/250@3x.png +0 -0
  288. package/src/statics/icons/childIcons//351/241/271/347/233/256/346/264/273/345/212/250/344/270/216/350/203/275/345/212/233/347/232/204/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  289. package/src/statics/icons/childIcons//351/241/271/347/233/256/346/264/273/345/212/250/345/212/250/344/275/234@3x.png +0 -0
  290. package/src/statics/icons/childIcons//351/241/271/347/233/256/346/265/201/347/250/213/345/233/276@3x.png +0 -0
  291. package/src/statics/icons/childIcons//351/241/271/347/233/256/347/273/223/346/236/204/345/233/276@3x.png +0 -0
  292. package/src/statics/icons/childIcons//351/241/271/347/233/256/350/247/222/350/211/262@3x.png +0 -0
  293. package/src/statics/icons/childIcons//351/241/271/347/233/256/350/267/257/347/272/277/345/233/276@3x.png +0 -0
  294. package/src/statics/icons/childIcons//351/241/271/347/233/256/350/277/236/351/200/232/345/233/276@3x.png +0 -0
  295. package/src/statics/icons/childIcons//351/241/271/347/233/256/351/207/214/347/250/213/347/242/221@3x.png +0 -0
  296. package/src/statics/icons/childIcons//351/241/271/347/233/256/351/207/214/347/250/213/347/242/221/350/247/222/350/211/262@3x.png +0 -0
  297. package/src/statics/icons/childIcons//351/241/272/345/272/217@3x-2.png +0 -0
  298. package/src/statics/icons/childIcons//351/241/272/345/272/217@3x.png +0 -0
  299. package/src/statics/icons/childIcons//351/243/216/351/231/251@3x.png +0 -0
  300. package/src/statics/icons/childIcons//351/243/216/351/231/251/344/270/216/345/256/211/345/205/250/346/216/247/345/210/266/346/230/240/345/260/204/347/237/251/351/230/265@3x.png +0 -0
  301. package/src/statics/icons/childIcons//351/253/230/347/272/247/344/270/232/345/212/241/346/246/202/345/277/265@3x.png +0 -0
  302. package/src/statics/icons/createMenu/config.png +0 -0
  303. package/src/statics/icons/createMenu/contact.png +0 -0
  304. package/src/statics/icons/createMenu/copy.png +0 -0
  305. package/src/statics/icons/createMenu/delete.png +0 -0
  306. package/src/statics/icons/createMenu/diagram.png +0 -0
  307. package/src/statics/icons/createMenu/element.png +0 -0
  308. package/src/statics/icons/createMenu/locateChart.png +0 -0
  309. package/src/statics/icons/createMenu/paste.png +0 -0
  310. package/src/statics/icons/createMenu/rename.png +0 -0
  311. package/src/statics/icons/createMenu/scissors.png +0 -0
  312. package/src/store/eventBus.ts +38 -0
  313. package/src/store/graphStore.ts +782 -0
  314. package/src/store/index.ts +8 -0
  315. package/src/style/index.css +1 -0
  316. package/src/style/tailwind.css +33 -0
  317. package/src/types/index.ts +200 -0
  318. package/src/utils/autoExpandParent.ts +94 -0
  319. package/src/utils/colorUtils.ts +137 -0
  320. package/src/utils/compartment.ts +534 -0
  321. package/src/utils/containers.ts +910 -0
  322. package/src/utils/diagram.ts +403 -0
  323. package/src/utils/dom.ts +21 -0
  324. package/src/utils/drag.ts +224 -0
  325. package/src/utils/edgeUtils.ts +787 -0
  326. package/src/utils/geom.ts +177 -0
  327. package/src/utils/graphDragService.ts +329 -0
  328. package/src/utils/highlightUtils.ts +162 -0
  329. package/src/utils/hittest.ts +135 -0
  330. package/src/utils/iconLoader.ts +105 -0
  331. package/src/utils/index.ts +20 -0
  332. package/src/utils/packgeMap.ts +1 -0
  333. package/src/utils/pinUtils.ts +484 -0
  334. package/src/utils/policy.ts +212 -0
  335. package/src/utils/zorder.ts +39 -0
  336. package/src/view/graph.vue +419 -0
  337. package/src/vite-env.d.ts +33 -0
@@ -0,0 +1,484 @@
1
+ import type { Shape, Bounds } from '../types'
2
+ import { getBounds } from './geom'
3
+
4
+ const PortKeys = ['OperationalPort']
5
+ /**
6
+ * 计算点到矩形边的距离
7
+ */
8
+ function pointToEdgeDistance(
9
+ point: { x: number; y: number },
10
+ rect: { x: number; y: number; width: number; height: number },
11
+ edge: 'top' | 'right' | 'bottom' | 'left'
12
+ ): number {
13
+ const { x, y, width, height } = rect
14
+ const px = point.x
15
+ const py = point.y
16
+
17
+ switch (edge) {
18
+ case 'top':
19
+ return Math.abs(py - y)
20
+ case 'right':
21
+ return Math.abs(px - (x + width))
22
+ case 'bottom':
23
+ return Math.abs(py - (y + height))
24
+ case 'left':
25
+ return Math.abs(px - x)
26
+ default:
27
+ return Infinity
28
+ }
29
+ }
30
+
31
+ /**
32
+ * 找到距离鼠标点最近的边
33
+ */
34
+ export function findNearestEdge(
35
+ mousePoint: { x: number; y: number },
36
+ blockBounds: { x: number; y: number; width: number; height: number }
37
+ ): 'top' | 'right' | 'bottom' | 'left' {
38
+ const distances = {
39
+ top: pointToEdgeDistance(mousePoint, blockBounds, 'top'),
40
+ right: pointToEdgeDistance(mousePoint, blockBounds, 'right'),
41
+ bottom: pointToEdgeDistance(mousePoint, blockBounds, 'bottom'),
42
+ left: pointToEdgeDistance(mousePoint, blockBounds, 'left'),
43
+ }
44
+
45
+ // 找到距离最小的边
46
+ let nearestEdge: 'top' | 'right' | 'bottom' | 'left' = 'top'
47
+ let minDistance = distances.top
48
+
49
+ for (const [edge, distance] of Object.entries(distances) as Array<['top' | 'right' | 'bottom' | 'left', number]>) {
50
+ if (distance < minDistance) {
51
+ minDistance = distance
52
+ nearestEdge = edge
53
+ }
54
+ }
55
+
56
+ return nearestEdge
57
+ }
58
+
59
+ /**
60
+ * 计算 pin 附着在 block 边缘上的位置(完全贴边,且 pin 在父外侧露出)
61
+ * 不改变父元素的高宽
62
+ *
63
+ * 规则:
64
+ * - 右边:x = 父.x + 父.width,y 使用当前 pin 的 y(再按父高做约束)
65
+ * - 左边:x = 父.x - pin.width,y 使用当前 pin 的 y(再按父高做约束)
66
+ * - 上边:y = 父.y - pin.height,x 使用当前 pin 的 x(再按父宽做约束)
67
+ * - 下边:y = 父.y + 父.height,x 使用当前 pin 的 x(再按父宽做约束)
68
+ *
69
+ * @param pinBounds - pin 的 bounds
70
+ * @param blockBounds - block 的 bounds
71
+ * @param mousePoint - 鼠标位置(仅用于判定最近的边)
72
+ * @returns 计算后的 pin bounds(左上角坐标 + 宽高)
73
+ */
74
+ export function calculatePinAttachmentPosition(
75
+ pinShape: Shape,
76
+ blockBounds: Bounds,
77
+ mousePoint: { x: number; y: number },
78
+ _opts?: { overlap?: number }
79
+ ): Bounds {
80
+ const block = getBounds({ bounds: blockBounds })
81
+ const pin = getBounds(pinShape)
82
+
83
+ // 统一取整,避免亚像素导致的视觉缝隙/抖动
84
+ const bX = Math.round(block.x || 0)
85
+ const bY = Math.round(block.y || 0)
86
+ const bW = Math.max(1, Math.round(block.width || 0))
87
+ const bH = Math.max(1, Math.round(block.height || 0))
88
+ const pW = Math.max(1, Math.round(pin.width || 100))
89
+ const pH = Math.max(1, Math.round(pin.height || 40))
90
+ const pX = Math.round(pin.x || 0)
91
+ const pY = Math.round(pin.y || 0)
92
+
93
+ if (bW === 0 || bH === 0) {
94
+ return { x: pX, y: pY, width: pW, height: pH }
95
+ }
96
+
97
+ // 找到最近的边(基于鼠标点)
98
+ const nearestEdge = findNearestEdge(mousePoint, { x: bX, y: bY, width: bW, height: bH })
99
+ const isPort = PortKeys.includes((pinShape as any).shapeKey)
100
+
101
+ // 沿着该边的“平移方向”做范围约束,保证 pin 在该边范围内滑动
102
+ const clamp = (v: number, min: number, max: number) => Math.min(Math.max(v, min), max)
103
+
104
+ // 当 pin 尺寸大于父尺寸时,沿边滑动轴向无法形成 [min,max] 区间,退化为居中
105
+ const centerXOnEdge = () => bX + (bW - pW) / 2
106
+ const centerYOnEdge = () => bY + (bH - pH) / 2
107
+
108
+ let x = pX
109
+ let y = pY
110
+
111
+ // 用鼠标点来决定沿边方向的位置(新建时 pX/pY 常为 0,导致总贴在左/上角)
112
+ const mx = Math.round(mousePoint.x)
113
+ const my = Math.round(mousePoint.y)
114
+
115
+ switch (nearestEdge) {
116
+ case 'top': {
117
+ // 顶边:pin 完全在父外侧上方露出
118
+ const minX = bX
119
+ const maxX = bX + bW - pW
120
+ if (minX <= maxX) {
121
+ // 以鼠标为参考,让 pin 在该边“居中于鼠标”(左上为原点,需减半宽)
122
+ x = clamp(mx - Math.round(pW / 2), minX, maxX)
123
+ } else {
124
+ x = Math.round(centerXOnEdge())
125
+ }
126
+ y = bY - pH
127
+ break
128
+ }
129
+ case 'right': {
130
+ // 右边:pin 完全在父外侧右侧露出
131
+ const minY = bY
132
+ const maxY = bY + bH - pH
133
+ x = bX + bW
134
+ if (minY <= maxY) {
135
+ y = clamp(my - Math.round(pH / 2), minY, maxY)
136
+ } else {
137
+ y = Math.round(centerYOnEdge())
138
+ }
139
+ break
140
+ }
141
+ case 'bottom': {
142
+ // 底边:pin 完全在父外侧下方露出
143
+ const minX = bX
144
+ const maxX = bX + bW - pW
145
+ if (minX <= maxX) {
146
+ x = clamp(mx - Math.round(pW / 2), minX, maxX)
147
+ } else {
148
+ x = Math.round(centerXOnEdge())
149
+ }
150
+ y = bY + bH
151
+ break
152
+ }
153
+ case 'left': {
154
+ // 左边:pin 完全在父外侧左侧露出
155
+ const minY = bY
156
+ const maxY = bY + bH - pH
157
+ x = bX - pW
158
+ if (minY <= maxY) {
159
+ y = clamp(my - Math.round(pH / 2), minY, maxY)
160
+ } else {
161
+ y = Math.round(centerYOnEdge())
162
+ }
163
+ break
164
+ }
165
+ default: {
166
+ x = pX
167
+ y = pY
168
+ }
169
+ }
170
+
171
+ return {
172
+ x: Math.round(x),
173
+ y: Math.round(y),
174
+ width: pW,
175
+ height: pH,
176
+ }
177
+ }
178
+
179
+ /**
180
+ * 当拖动 pin 到 block 上时,计算附着位置
181
+ *
182
+ * @param pinShape - pin 的 shape 对象
183
+ * @param parentBlock - 父 block 的 shape 对象
184
+ * @param mousePoint - 鼠标位置(本地坐标)
185
+ * @returns 计算后的 pin bounds
186
+ */
187
+ export function attachPinToBlock(
188
+ pinShape: Shape,
189
+ parentBlock: Shape,
190
+ mousePoint: { x: number; y: number }
191
+ ): Bounds {
192
+ const blockBounds = getBounds(parentBlock)
193
+
194
+ return calculatePinAttachmentPosition(pinShape, blockBounds, mousePoint)
195
+ }
196
+
197
+ /**
198
+ * 吸附 pin 到父图元最近的边上,返回调整后的坐标
199
+ * 保持“完全贴边且在外侧露出”,不再做向内重叠缝隙处理
200
+ * @param dropPoint 落点坐标
201
+ * @param parentShape 父 shape
202
+ * @param pinShape pin shape
203
+ * @returns 调整后的 x, y 坐标
204
+ */
205
+ export function snapPinToParentEdge(
206
+ dropPoint: { x: number; y: number },
207
+ parentShape: Shape,
208
+ pinShape: Shape
209
+ ): { x: number; y: number } {
210
+ const attachedBounds = attachPinToBlock(pinShape, parentShape, dropPoint);
211
+
212
+ // 最近边用于判断箭头朝向
213
+ const nearestEdge = findNearestEdge(dropPoint, getBounds(parentShape))
214
+
215
+ // 如果是 Port,则调整其最终位置以使其居中
216
+ const isPort = PortKeys.includes((pinShape as any).shapeKey)
217
+ if (isPort) {
218
+ const parent = getBounds(parentShape)
219
+ const pin = getBounds(pinShape)
220
+ const pW = Math.max(1, Math.round(pin.width || 1))
221
+ const pH = Math.max(1, Math.round(pin.height || 1))
222
+
223
+ switch (nearestEdge) {
224
+ case 'top':
225
+ attachedBounds.y = parent.y - pH / 2
226
+ break
227
+ case 'bottom':
228
+ attachedBounds.y = parent.y + parent.height - pH / 2
229
+ break
230
+ case 'left':
231
+ attachedBounds.x = parent.x - pW / 2
232
+ break
233
+ case 'right':
234
+ attachedBounds.x = parent.x + parent.width - pW / 2
235
+ break
236
+ }
237
+ }
238
+
239
+ // 输出引脚始终朝外,输入引脚始终朝内
240
+ const isInput = (pinShape as any).shapeKey === 'InputPin'
241
+ const outward = !isInput
242
+
243
+ // 计算箭头方向(up/down/left/right)并写入 direction
244
+ let arrow: 'up' | 'down' | 'left' | 'right'
245
+ switch (nearestEdge) {
246
+ case 'top': arrow = outward ? 'up' : 'down'; break
247
+ case 'right': arrow = outward ? 'right' : 'left'; break
248
+ case 'bottom': arrow = outward ? 'down' : 'up'; break
249
+ case 'left': arrow = outward ? 'left' : 'right'; break
250
+ }
251
+ pinShape.direction = arrow
252
+
253
+ // 根据方向为 Pin 计算 nameBounds 与 nameStyle(用于 Pin.vue 定位名称)
254
+ try {
255
+ const pb = getBounds(pinShape)
256
+ const W = pb.width || (pinShape as any).bounds?.width || 100
257
+ const H = pb.height || (pinShape as any).bounds?.height || 40
258
+ const pad = 4
259
+ const fontH = Math.max(10, Math.min(14, Math.floor(H * 0.28)))
260
+
261
+ const key = String((pinShape as any).shapeKey || '').toLowerCase()
262
+ const isInputPin = key.includes('input')
263
+
264
+ let nx = W / 2
265
+ let ny = H + pad
266
+ let anchor: 'start' | 'middle' | 'end' = 'middle'
267
+ let baseline: 'alphabetic' | 'middle' | 'text-before-edge' | 'text-after-edge' = 'text-before-edge'
268
+
269
+ switch (pinShape.direction) {
270
+ case 'up': {
271
+ nx = W / 2
272
+ if (isInputPin) {
273
+ ny = H + pad
274
+ baseline = 'text-before-edge'
275
+ } else {
276
+ ny = -pad
277
+ baseline = 'text-after-edge'
278
+ }
279
+ anchor = 'middle'
280
+ break
281
+ }
282
+ case 'down': {
283
+ nx = W / 2
284
+ if (isInputPin) {
285
+ ny = -pad
286
+ baseline = 'text-after-edge'
287
+ } else {
288
+ ny = H + pad
289
+ baseline = 'text-before-edge'
290
+ }
291
+ anchor = 'middle'
292
+ break
293
+ }
294
+ case 'left': {
295
+ ny = H / 2
296
+ if (isInputPin) {
297
+ nx = W + pad
298
+ anchor = 'start'
299
+ } else {
300
+ nx = -pad
301
+ anchor = 'end'
302
+ }
303
+ baseline = 'middle'
304
+ break
305
+ }
306
+ case 'right': {
307
+ ny = H / 2
308
+ if (isInputPin) {
309
+ nx = -pad
310
+ anchor = 'end'
311
+ } else {
312
+ nx = W + pad
313
+ anchor = 'start'
314
+ }
315
+ baseline = 'middle'
316
+ break
317
+ }
318
+ }
319
+
320
+ ;(pinShape as any).nameBounds = {
321
+ x: Math.round(nx),
322
+ y: Math.round(ny),
323
+ width: 0,
324
+ height: fontH,
325
+ }
326
+ ;(pinShape as any).nameStyle = {
327
+ ...(pinShape as any).nameStyle,
328
+ textAnchor: anchor,
329
+ dominantBaseline: baseline,
330
+ }
331
+ } catch {}
332
+ console.log(dropPoint, attachedBounds)
333
+
334
+ // 直接返回“完全贴边并在外侧”的坐标(已在 calculatePinAttachmentPosition 中确定)
335
+ return { x: Math.round(attachedBounds.x || 0), y: Math.round(attachedBounds.y || 0) };
336
+ }
337
+
338
+ /**
339
+ * 仅用于“移动时”的吸附:
340
+ * - 计算 pin 应贴边后的目标左上角
341
+ * - 再加上拖拽偏移 dragOffset,返回“应当传给 moveDraggedShape 的指针坐标”
342
+ * 这样可避免直接把左上角传入导致的位移误差(产生你看到的缝隙)
343
+ */
344
+ export function snapPinPointerOnMove(
345
+ pointer: { x: number; y: number },
346
+ parentShape: Shape,
347
+ pinShape: Shape,
348
+ dragOffset?: { x: number; y: number }
349
+ ): { x: number; y: number } {
350
+ const parent = getBounds(parentShape)
351
+ const pin = getBounds(pinShape)
352
+ const ox = dragOffset?.x ?? 0
353
+ const oy = dragOffset?.y ?? 0
354
+ const right = parent.x + parent.width
355
+ const bottom = parent.y + parent.height
356
+ const pW = Math.max(1, Math.round(pin.width || 1))
357
+ const pH = Math.max(1, Math.round(pin.height || 1))
358
+ const clamp = (v: number, min: number, max: number) => Math.min(Math.max(v, min), max)
359
+
360
+ // 判定鼠标位置相对父元素的区域
361
+ const above = pointer.y < parent.y
362
+ const below = pointer.y > bottom
363
+ const leftOf = pointer.x < parent.x
364
+ const rightOf = pointer.x > right
365
+
366
+ let edge: 'top' | 'right' | 'bottom' | 'left'
367
+
368
+ // 核心逻辑:决定吸附到哪条边
369
+ if (above || below) {
370
+ // 场景:鼠标在父元素上方或下方
371
+ if (pointer.x >= parent.x && pointer.x <= right) {
372
+ // 子场景:鼠标X坐标在父元素宽度内 -> 吸附到上/下边
373
+ edge = above ? 'top' : 'bottom'
374
+ } else {
375
+ // 子场景:鼠标X坐标在父元素宽度外 -> 吸附到左/右边
376
+ edge = leftOf ? 'left' : 'right'
377
+ }
378
+ } else if (leftOf || rightOf) {
379
+ // 场景:鼠标在父元素左侧或右侧
380
+ edge = leftOf ? 'left' : 'right'
381
+ } else {
382
+ // 场景:鼠标在父元素内部 -> 按最近的边处理
383
+ edge = findNearestEdge(pointer, parent)
384
+ }
385
+
386
+ // 根据确定的 edge,计算 pin 的最终左上角坐标 (ltx, lty)
387
+ let ltx = 0, lty = 0
388
+ const isPort = PortKeys.includes((pinShape as any).shapeKey)
389
+ console.log(isPort, 111)
390
+
391
+ switch (edge) {
392
+ case 'top': {
393
+ const minX = parent.x
394
+ const maxX = parent.x + parent.width - pW
395
+ ltx = clamp(pointer.x - ox, minX, maxX)
396
+ lty = isPort ? parent.y - pH / 2 : parent.y - pH
397
+ break
398
+ }
399
+ case 'bottom': {
400
+ const minX = parent.x
401
+ const maxX = parent.x + parent.width - pW
402
+ ltx = clamp(pointer.x - ox, minX, maxX)
403
+ lty = isPort ? bottom - pH : bottom // NOTE: 按用户要求,port 在下边缘时,y = bottom - pH
404
+ break
405
+ }
406
+ case 'left': {
407
+ const minY = parent.y
408
+ const maxY = parent.y + parent.height - pH
409
+ ltx = isPort ? parent.x - pW / 2 : parent.x - pW
410
+ lty = clamp(pointer.y - oy, minY, maxY)
411
+ break
412
+ }
413
+ case 'right': {
414
+ const minY = parent.y
415
+ const maxY = parent.y + parent.height - pH
416
+ ltx = isPort ? right - pW / 2 : right
417
+ lty = clamp(pointer.y - oy, minY, maxY)
418
+ break
419
+ }
420
+ }
421
+
422
+ // 设置方向(输出 pin 朝外、输入 pin 朝内)
423
+ const isInput = (pinShape as any).shapeKey === 'InputPin'
424
+ const outward = !isInput
425
+ let arrow: 'up' | 'down' | 'left' | 'right'
426
+ switch (edge) {
427
+ case 'top': arrow = outward ? 'up' : 'down'; break
428
+ case 'right': arrow = outward ? 'right' : 'left'; break
429
+ case 'bottom': arrow = outward ? 'down' : 'up'; break
430
+ case 'left': arrow = outward ? 'left' : 'right'; break
431
+ }
432
+ pinShape.direction = arrow
433
+
434
+ // 同步名称定位(拖动中也更新)
435
+ try {
436
+ const W = pW
437
+ const H = pH
438
+ const pad = 4
439
+ const fontH = Math.max(10, Math.min(14, Math.floor(H * 0.28)))
440
+ const key = String((pinShape as any).shapeKey || '').toLowerCase()
441
+ const isInputPin = key.includes('input')
442
+
443
+ let nx = W / 2
444
+ let ny = H + pad
445
+ let anchor: 'start' | 'middle' | 'end' = 'middle'
446
+ let baseline: 'alphabetic' | 'middle' | 'text-before-edge' | 'text-after-edge' = 'text-before-edge'
447
+
448
+ switch (pinShape.direction) {
449
+ case 'up': {
450
+ nx = W / 2
451
+ if (isInputPin) { ny = H + pad; baseline = 'text-before-edge' } else { ny = -pad; baseline = 'text-after-edge' }
452
+ anchor = 'middle'
453
+ break
454
+ }
455
+ case 'down': {
456
+ nx = W / 2
457
+ if (isInputPin) { ny = -pad; baseline = 'text-after-edge' } else { ny = H + pad; baseline = 'text-before-edge' }
458
+ anchor = 'middle'
459
+ break
460
+ }
461
+ case 'left': {
462
+ ny = H / 2
463
+ if (isInputPin) { nx = W + pad; anchor = 'start' } else { nx = -pad; anchor = 'end' }
464
+ baseline = 'middle'
465
+ break
466
+ }
467
+ case 'right': {
468
+ ny = H / 2
469
+ if (isInputPin) { nx = -pad; anchor = 'end' } else { nx = W + pad; anchor = 'start' }
470
+ baseline = 'middle'
471
+ break
472
+ }
473
+ }
474
+
475
+ ;(pinShape as any).nameBounds = { x: Math.round(nx), y: Math.round(ny), width: 0, height: fontH }
476
+ ;(pinShape as any).nameStyle = { ...(pinShape as any).nameStyle, textAnchor: anchor, dominantBaseline: baseline }
477
+ } catch {}
478
+
479
+ // 返回“应传给 moveDraggedShape 的指针坐标”(pointer = leftTop + dragOffset)
480
+ return {
481
+ x: ltx + ox,
482
+ y: lty + oy,
483
+ }
484
+ }
@@ -0,0 +1,212 @@
1
+ import type { CheckNested, NestingConfig, Shape } from '@/types'
2
+ import type { EdgeFlags } from './geom'
3
+ import { eventBus } from '../store/eventBus'
4
+ import { getUuid } from './index'
5
+ // 元素行为策略
6
+ export type ElementPolicy = {
7
+ draggable: boolean
8
+ resizable: boolean
9
+ constrainToDiagram: EdgeFlags
10
+ }
11
+
12
+ // 默认策略
13
+ export const DEFAULT_POLICY: ElementPolicy = {
14
+ draggable: true,
15
+ resizable: true,
16
+ // 只限制左/上
17
+ constrainToDiagram: { left: true, top: true },
18
+ }
19
+
20
+ // 各类型差异化策略
21
+ export const POLICY_BY_TYPE: Record<string, Partial<ElementPolicy>> = {
22
+ diagram: { draggable: false, resizable: true, constrainToDiagram: {} },
23
+ shape: { draggable: true, resizable: true, constrainToDiagram: { left: true, top: true } },
24
+ port: { draggable: true, resizable: false, constrainToDiagram: { left: true, top: true, right: true, bottom: true } },
25
+ edge: { draggable: false, resizable: false, constrainToDiagram: {} },
26
+ }
27
+
28
+ // 根据 shape 读取策略
29
+ export function getPolicy(s: any): ElementPolicy {
30
+ const t = String(s?.shapeType ?? '').trim().toLowerCase()
31
+ const p = POLICY_BY_TYPE[t] || {}
32
+ return {
33
+ ...DEFAULT_POLICY,
34
+ ...p,
35
+ constrainToDiagram: { ...DEFAULT_POLICY.constrainToDiagram, ...(p.constrainToDiagram || {}) },
36
+ }
37
+ }
38
+
39
+ //判定元素是否可嵌套
40
+ export const nestingConfig: NestingConfig = {
41
+ // onlyUnderSameType: ['Strategic',],
42
+ // disallowSameType: ['EnterpriseGoal',],
43
+ // allowedParents: {
44
+ // geopoliticalextenttype: ['capability'],
45
+ // },
46
+ }
47
+ const getType = (s: any) => String(s?.shapeKey ?? s?.type ?? '').toLowerCase()
48
+
49
+ export function canNest(
50
+ child: Shape | null,
51
+ parent: Shape | null,
52
+ all: Shape[],
53
+ cfg: NestingConfig = nestingConfig
54
+ ): boolean {
55
+ if (!child || !parent) return false
56
+ if (child.id == parent.id) return false
57
+ const ct = getType(child)
58
+ const pt = getType(parent)
59
+ const sameType = ct === pt
60
+ // 全局禁同类互嵌
61
+ if (cfg.disallowSameTypeAll) return false
62
+ // 按类型禁同类互嵌
63
+ if (cfg.disallowSameTypeAll && sameType) return false
64
+ if (sameType && cfg.disallowSameType?.map(x => x.toLowerCase()).includes(ct)) return false
65
+ // 配置化硬规则
66
+ if (cfg.disallowAsChild?.map(x => x.toLowerCase()).includes(ct)) return false
67
+ if (cfg.disallowAsParent?.map(x => x.toLowerCase()).includes(pt)) return false
68
+ if (cfg.onlyUnderSameType?.map(x => x.toLowerCase()).includes(ct) && ct !== pt) return false
69
+
70
+ // 子→父 白名单
71
+ if (cfg.allowedParents?.[ct] && !cfg.allowedParents[ct].map(x => x.toLowerCase()).includes(pt)) {
72
+ return false
73
+ }
74
+ // 父→子 白/黑名单
75
+ if (cfg.allowedChildren?.[pt] && !cfg.allowedChildren[pt].map(x => x.toLowerCase()).includes(ct)) {
76
+ return false
77
+ }
78
+ if (cfg.rejectChildTypes?.[pt]?.map(x => x.toLowerCase()).includes(ct)) {
79
+ return false
80
+ }
81
+
82
+ // 容量限制(按父类型;固定 parenShapeId)
83
+ const parenField = 'parenShapeId' as const
84
+ if (typeof cfg.maxChildren?.[pt] === 'number') {
85
+ const pid = parent.id
86
+ const count = all.filter(s => (s as any)[parenField] === pid).length
87
+ if (count >= (cfg.maxChildren as any)[pt]) return false
88
+ }
89
+
90
+ // 与现有 policy 对接(
91
+ const pPol: any = getPolicy(parent)
92
+ if (Array.isArray(pPol.acceptChildTypes) &&
93
+ !pPol.acceptChildTypes.map((x: string) => x.toLowerCase()).includes(ct)) return false
94
+ if (Array.isArray(pPol.rejectChildTypes) &&
95
+ pPol.rejectChildTypes.map((x: string) => x.toLowerCase()).includes(ct)) return false
96
+ if (typeof pPol.maxChildren === 'number') {
97
+ const pid = parent.id
98
+ const cnt = all.filter(s => (s as any)[parenField] === pid).length
99
+ if (cnt >= pPol.maxChildren) return false
100
+ }
101
+
102
+ // 父不能是子孙
103
+ // if (collectDescendantIds(all as any, child.id).includes(parent.id)) return false
104
+
105
+ return true
106
+ }
107
+ /** ==================统一的“远端校验工具” ================== */
108
+ /** 画布的类型 key,作为“落到画布”的 parentType */
109
+ export const DIAGRAM_TYPE_KEY = 'diagram'
110
+
111
+ /** 解析 hover 目标:返回目标 id 与类型(shape 或 diagram) */
112
+ export type NestTarget =
113
+ | { kind: 'diagram'; parentId: null; parentType: typeof DIAGRAM_TYPE_KEY }
114
+ | { kind: 'shape'; parentId: string; parentType: string }
115
+
116
+ export function resolveNestTarget(hoverId: string | null, shapes: Shape[]): NestTarget {
117
+ if (!hoverId) return { kind: 'diagram', parentId: null, parentType: DIAGRAM_TYPE_KEY }
118
+ const p = shapes.find(s => s.id === hoverId)
119
+ if (!p) return { kind: 'diagram', parentId: null, parentType: DIAGRAM_TYPE_KEY }
120
+ return { kind: 'shape', parentId: p.id, parentType: getType(p) }
121
+ }
122
+
123
+ /**
124
+ * 统一入口:先做本地 canNest,再做远端校验。
125
+ * - hoverId 为空 => 落在画布(parentType = 'diagram')
126
+ * - 返回 true 表示“可以放”;返回 false 表示“不能放”(外部直接把 hoverNestable 置 false 即可)
127
+ */
128
+ export interface CheckNestedResult {
129
+ ok: boolean;
130
+ }
131
+ /** 组装后端需要的校验参数 */
132
+ // 组装后端需要的校验参数:支持 parent = null(表示画布)
133
+ export const buildCheckNestedPayload = (
134
+ dragged: Shape | null,
135
+ parent: Shape | null, // shape 父级,画布时为 null
136
+ diagram: Shape | null // 当前画布
137
+ ): CheckNested | null => {
138
+ // 1. 被拖动图元 和 画布 必须存在
139
+ if (!dragged || !diagram) return null
140
+ const modelId = dragged.modelId || ''
141
+
142
+ const modelType = String((dragged as any).shapeKey || '')
143
+ // 只要存在 inert 字段(不论 true/false),就清空 modelShapeId
144
+ const hasInertField = Object.prototype.hasOwnProperty.call(dragged as any, 'inert')
145
+ const modelShapeId = hasInertField ? '' : String((dragged as any).id || '')
146
+
147
+ let targetModelType = ''
148
+ let targetModelShapeId = ''
149
+
150
+ if (parent) {
151
+ // 2. 正常情况:挂到某个父 shape 下面
152
+ targetModelType = String((parent as any).shapeKey || '')
153
+ targetModelShapeId = String((parent as any).id || '')
154
+ } else {
155
+ // 3. parent 为空 => 落在画布根
156
+ // 用统一的 DIAGRAM_TYPE_KEY + diagram.id 通知后端“目标是画布”
157
+ targetModelType = diagram.shapeKey || '' // 'diagram'
158
+ targetModelShapeId = String((diagram as any).id || '')
159
+ }
160
+
161
+ const diagramCode = String(
162
+ (diagram as any)?.shapeKey || (diagram as any)?.diagramCode || ''
163
+ )
164
+
165
+ if (!modelType || !targetModelType || !targetModelShapeId || !diagramCode) return null
166
+
167
+ return {
168
+ modelType, // 被拖图元类型
169
+ modelShapeId, // 被拖图元 id(虚拟节点时可以为空)
170
+ targetModelType, // 目标类型:可能是具体 shapeType,或者 'diagram'
171
+ targetModelShapeId, // 目标 shapeId 或 diagramId
172
+ diagramCode, // 当前画布的业务编码
173
+ modelId,
174
+ }
175
+ }
176
+ /**
177
+ * front 去调后端进行“是否允许嵌套/放置”的校验。
178
+ * - front 侧约定:收到 'check-nest:req' 后调接口,回 'check-nest:ok' 时携带 { reqId, ok: boolean }
179
+ * - 若发生异常,front 回 'check-nest:err';若 front 没回,则超时返回 { ok:false }
180
+ */
181
+ export const checkNestViaFront = async (
182
+ dragged: Shape | null,
183
+ parent: Shape | null,
184
+ diagram: Shape | null,
185
+ timeout = 5000
186
+ ): Promise<CheckNestedResult> => {
187
+ const payload = buildCheckNestedPayload(dragged, parent, diagram)
188
+ if (!payload) return { ok: false }
189
+
190
+ const reqId = getUuid()
191
+
192
+ return new Promise<CheckNestedResult>((resolve) => {
193
+ const onOk = (res: { reqId: string; ok: boolean }) => {
194
+ if (res?.reqId !== reqId) return
195
+ cleanup(); resolve({ ok: !!res.ok })
196
+ }
197
+ const onErr = (res: { reqId: string }) => {
198
+ if (res?.reqId !== reqId) return
199
+ cleanup(); resolve({ ok: false })
200
+ }
201
+ const cleanup = () => {
202
+ clearTimeout(tid)
203
+ eventBus.off('check-nest:ok', onOk)
204
+ eventBus.off('check-nest:err', onErr)
205
+ }
206
+ const tid = setTimeout(() => { cleanup(); resolve({ ok: false }) }, timeout)
207
+
208
+ eventBus.emit('check-nest:req', { reqId, payload })
209
+ eventBus.on('check-nest:ok', onOk)
210
+ eventBus.on('check-nest:err', onErr)
211
+ })
212
+ }