添加节点

业务数据

  1. // 添加默认节点
  2. addNode() {
  3. this.graph.centerContent()
  4. // TODO 添加节点位置的计算
  5. // 生成随机数
  6. this.graph.addNode({
  7. shape: 'rect', // 指定使用何种图形,默认值为 'rect'
  8. x: 10,
  9. y: 50,
  10. width: 110,
  11. height: 38,
  12. // html | svg DOM 结构
  13. markup: [
  14. // svg 矩形 边框
  15. {
  16. tagName: 'rect',
  17. selector: 'body'
  18. },
  19. // svg text 放置实体名称
  20. {
  21. tagName: 'text',
  22. selector: 'label'
  23. },
  24. // svg text 放置实体属性
  25. {
  26. tagName: 'text',
  27. selector: 'subLabel'
  28. }
  29. ],
  30. // 业务数据
  31. // data: {
  32. // label: 'label',
  33. // attributes: [{ key: '', value: '' }]
  34. // },
  35. // 默认样式属性
  36. attrs: defaultNodeAttrs,
  37. // 链接桩
  38. ports: {
  39. // 链接桩组定义
  40. groups: {
  41. left: {
  42. position: 'left',
  43. attrs: defaultPortAttrs
  44. },
  45. top: {
  46. position: 'top',
  47. attrs: defaultPortAttrs
  48. },
  49. right: {
  50. position: 'right',
  51. attrs: defaultPortAttrs
  52. },
  53. bottom: {
  54. position: 'bottom',
  55. attrs: defaultPortAttrs
  56. }
  57. },
  58. // 链接桩
  59. items: [
  60. {
  61. id: 'port1',
  62. group: 'left', // 指定分组名称
  63. islined: false
  64. },
  65. {
  66. id: 'port2',
  67. group: 'top' // 指定分组名称
  68. },
  69. {
  70. id: 'port3',
  71. group: 'bottom' // 指定分组名称
  72. },
  73. {
  74. id: 'port4',
  75. group: 'right' // 指定分组名称
  76. }
  77. ]
  78. }
  79. })
  80. },
  1. import i18n from '@/lang'
  2. const $t = i18n.global.t
  3. // 默认节点宽高
  4. export const DEFAULT_NODE_WIDTH = 110
  5. export const DEFAULT_NODE_HEIGHT = 38
  6. // 配置后节点宽度
  7. export const CONFIG_NODE_WIDTH = 144
  8. // 配置后高度根据属性行动态计算
  9. export const MAX_ATTRIBUTE_LINES = 5 + 1 // 最多显示的属性行数 + 溢出行...
  10. export const LINE_HEIGHT = 22
  11. export const LABEL_FONT_SIZE = 14
  12. export const ATTR_FONT_SIZE = 12
  13. // 发现对象起始点标记图标svg path 路径
  14. export const START_POINT_ICON_PATH =
  15. 'M227.2 374.4c57.6-57.6 121.6-54.4 195.2-16l272-150.4-16-105.6 240 240-105.6-16-150.4 272c38.4 76.8 41.6 140.8-16 195.2L480 627.2l-345.6 256 256-348.8c-73.6-70.4-163.2-160-163.2-160z M134.4 905.6c-6.4 0-9.6-3.2-16-6.4-6.4-6.4-9.6-19.2-3.2-28.8l246.4-332.8c-70.4-67.2-150.4-147.2-150.4-147.2-9.6-9.6-9.6-22.4 0-28.8 57.6-57.6 124.8-64 211.2-25.6L672 195.2l-12.8-89.6c0-9.6 3.2-19.2 12.8-22.4 9.6-3.2 19.2-3.2 25.6 3.2l240 240c6.4 6.4 9.6 16 3.2 25.6-3.2 9.6-12.8 12.8-22.4 12.8l-89.6-12.8-137.6 249.6c28.8 57.6 51.2 140.8-25.6 211.2-9.6 6.4-22.4 6.4-28.8 0l-153.6-153.6-336 240c-3.2 3.2-9.6 6.4-12.8 6.4z m124.8-531.2c28.8 28.8 92.8 92.8 147.2 144 6.4 6.4 9.6 19.2 3.2 28.8l-172.8 233.6 233.6-172.8c9.6-6.4 19.2-6.4 28.8 3.2l150.4 150.4c32-41.6 32-86.4-3.2-153.6-3.2-6.4-3.2-12.8 0-19.2l150.4-272c3.2-6.4 12.8-12.8 22.4-9.6l41.6 6.4-147.2-147.2 6.4 41.6c0 9.6-3.2 16-9.6 22.4l-272 150.4c-6.4 3.2-12.8 3.2-19.2 0-70.4-38.4-118.4-38.4-160-6.4z'
  16. // 无添加按钮的节点 markup 结构
  17. const defaultNodeMarkup = [
  18. // svg 矩形 边框
  19. {
  20. tagName: 'rect',
  21. selector: 'body'
  22. },
  23. // svg text 放置实体名称
  24. {
  25. tagName: 'text',
  26. selector: 'label'
  27. },
  28. // svg text 放置实体属性
  29. {
  30. tagName: 'text',
  31. selector: 'attrs'
  32. }
  33. ]
  34. // 有添加按钮的节点markup结构
  35. const hasAddBtnNodeMarkup = [
  36. // svg 矩形 边框
  37. {
  38. tagName: 'rect',
  39. selector: 'body'
  40. },
  41. // svg text 放置实体名称
  42. {
  43. tagName: 'text',
  44. selector: 'label'
  45. },
  46. // svg text 放置实体属性
  47. {
  48. tagName: 'text',
  49. selector: 'attrs'
  50. },
  51. // 右侧添加按钮
  52. {
  53. tagName: 'g',
  54. attrs: {
  55. class: 'btn add'
  56. },
  57. children: [
  58. // 为优化移动端,增大点击触发范围的不可见圆环
  59. {
  60. tagName: 'circle',
  61. attrs: {
  62. class: 'hidden-circle'
  63. }
  64. },
  65. // 圆环
  66. {
  67. tagName: 'circle',
  68. attrs: {
  69. class: 'add-circle'
  70. }
  71. },
  72. // + 号
  73. {
  74. tagName: 'text',
  75. attrs: {
  76. class: 'add'
  77. }
  78. }
  79. ]
  80. }
  81. ]
  82. // 默认节点的 attrs 样式: 虚线边框 无右侧添加按钮
  83. const defaultNodeAttrs = {
  84. body: {
  85. fill: 'var(--gray-3)',
  86. stroke: 'var(--gray-6)',
  87. strokeWidth: 1,
  88. strokeDasharray: '4,3',
  89. event: 'label:modal' //自定义点击事件,点击时触发弹窗编辑
  90. },
  91. label: {
  92. textAnchor: 'middle',
  93. textVerticalAnchor: 'middle',
  94. refX: '50%',
  95. refY: '50%',
  96. text: $t('dataSource.prepare.entityWaitEdit'),
  97. fill: 'var(--gray-7)',
  98. fontSize: LABEL_FONT_SIZE,
  99. textWrap: {
  100. ellipsis: true,
  101. width: DEFAULT_NODE_WIDTH - 24,
  102. height: LINE_HEIGHT
  103. },
  104. event: 'label:modal' // 自定义点击事件,点击时触发弹窗编辑
  105. },
  106. attrs: {
  107. textWrap: {
  108. ellipsis: true,
  109. width: CONFIG_NODE_WIDTH - 24
  110. },
  111. event: 'label:modal'
  112. }
  113. }
  114. // 默认节点配置数据后的样式
  115. const hasDataNodeAttrs = JSON.parse(JSON.stringify(defaultNodeAttrs))
  116. hasDataNodeAttrs.body.fill = 'var(--gray-1)'
  117. hasDataNodeAttrs.body.stroke = 'var(--primary)'
  118. hasDataNodeAttrs.label.fill = 'var(--primary)'
  119. // 默认节点在连线模式下 点击选中时的 attrs 样式
  120. const selectionNodeAttrs = JSON.parse(JSON.stringify(defaultNodeAttrs))
  121. selectionNodeAttrs.body.fill = 'var(--primary)'
  122. selectionNodeAttrs.body.stroke = 'var(--primary)'
  123. selectionNodeAttrs.body.strokeDasharray = 'none'
  124. selectionNodeAttrs.label.fill = 'var(--gray-1)'
  125. // 有右侧添加按钮的节点 attr 样式
  126. const hasAddBtnNodeAttrs = {
  127. body: {
  128. fill: 'var(--gray-1)',
  129. stroke: 'var(--primary)',
  130. strokeWidth: 1,
  131. strokeDasharray: '4,3',
  132. event: 'label:modal'
  133. },
  134. label: {
  135. textAnchor: 'middle',
  136. textVerticalAnchor: 'middle',
  137. refX: '50%',
  138. refY: '50%',
  139. text: $t('dataSource.prepare.entityWaitEdit'),
  140. fill: 'var(--primary)',
  141. fontSize: LABEL_FONT_SIZE,
  142. event: 'label:modal' // 自定义点击事件,点击时触发属性编辑弹窗
  143. },
  144. attrs: {
  145. textWrap: {
  146. ellipsis: true,
  147. width: DEFAULT_NODE_WIDTH - 24
  148. },
  149. fill: 'var(--primary)',
  150. event: 'label:modal'
  151. },
  152. '.btn.add': {
  153. refDx: 0,
  154. refY: '50%',
  155. event: 'node:add' // 自定义点击事件,点击时添加节点
  156. },
  157. '.btn.add > .hidden-circle': {
  158. r: 16,
  159. fill: 'transparent',
  160. stroke: 'var(--primary)',
  161. strokeWidth: 0
  162. },
  163. '.btn.add > .add-circle': {
  164. r: 7,
  165. fill: 'var(--gray-1)',
  166. stroke: 'var(--primary)',
  167. strokeWidth: 1
  168. },
  169. '.btn.add > text': {
  170. fontSize: 12,
  171. stroke: 'var(--primary)',
  172. strokeWidth: 1.5,
  173. refDx: '-150%',
  174. refY: '0%',
  175. fontFamily: 'Times New Roman',
  176. text: '+'
  177. }
  178. }
  179. export default {
  180. defaultNodeMarkup,
  181. hasAddBtnNodeMarkup,
  182. defaultNodeAttrs,
  183. hasDataNodeAttrs,
  184. hasAddBtnNodeAttrs,
  185. selectionNodeAttrs
  186. }

markup 节点结构

markup 自定义事件

  1. // 监听自定义事件
  2. this.graph.on('node:add', ({ e, node }) => {
  3. console.log('e=>', e)
  4. if (node.id == 1) {
  5. this.graph.addNode({
  6. id: 2,
  7. shape: 'rect',
  8. width: 110,
  9. height: 38,
  10. x: 400,
  11. y: 100,
  12. // 节点 html | svg DOM 结构
  13. markup: NODE.hasAddBtnNodeMarkup,
  14. attrs: NODE.hasAddBtnNodeAttrs
  15. })
  16. this.graph.addEdge({
  17. source: 1,
  18. target: 2,
  19. labels: EDGE.defaultEdge.labels,
  20. attrs: EDGE.defaultEdge.attrs
  21. })
  22. this.graph.centerContent()
  23. this.addIconSrc = require('@/assets/add2x_disabled.png')
  24. this.lineIconSrc = require('@/assets/lined2x.png')
  25. this.$refs.lineIcon.style.cursor = 'pointer'
  26. this.$refs.addIcon.style.cursor = 'not-allowed'
  27. console.log(this.graph.getNodes())
  28. } else {
  29. this.graph.addNode({
  30. id: 1,
  31. shape: 'rect',
  32. width: 110,
  33. height: 38,
  34. x: 100,
  35. y: 100,
  36. // 节点 html | svg DOM 结构
  37. markup: NODE.hasAddBtnNodeMarkup,
  38. attrs: NODE.hasAddBtnNodeAttrs
  39. })
  40. this.graph.addEdge({
  41. source: 2,
  42. target: 1,
  43. labels: EDGE.defaultEdge.labels,
  44. attrs: EDGE.defaultEdge.attrs
  45. })
  46. this.graph.centerContent()
  47. this.addIconSrc = require('@/assets/add2x_disabled.png')
  48. this.lineIconSrc = require('@/assets/lined2x.png')
  49. this.$refs.lineIcon.style.cursor = 'pointer'
  50. this.$refs.addIcon.style.cursor = 'not-allowed'
  51. console.log(this.graph.getNodes())
  52. }
  53. })