frameContainer.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <template>
  2. <!-- 沙盘图区域 -->
  3. <div class="frame-container-wrap">
  4. <!-- 工具栏 -->
  5. <FrameToolBar v-if="$route.path==='/editframe'&&graph"
  6. :is-select-edge="isSelectEdge"
  7. :is-select-node="isSelectNode"
  8. :canUndo="canUndo"
  9. :canRedo="canRedo"
  10. :graph="graph"
  11. :current-cell="currentCell||baseNode"
  12. ></FrameToolBar>
  13. <div class="frame-container" id="frameContainer"></div>
  14. <!-- 缩略图 -->
  15. <div class="minimap" id="frameMinimap"></div>
  16. <!-- 右键菜单 -->
  17. <div id="context-menu-wrapper" @mouseleave="hideContextMenu">
  18. <el-dropdown-menu size="medium">
  19. <el-dropdown-item v-for="menu in contextMenu" :key="menu.key" @click.native="handleContext(menu.key)">
  20. <i :class="menu.icon" v-if="menu.icon"/>
  21. {{menu.label}}
  22. </el-dropdown-item>
  23. </el-dropdown-menu>
  24. </div>
  25. </div>
  26. </template>
  27. <script>
  28. import { ElDropdownMenu } from 'element-ui';
  29. import { myGraph } from '../common/graph';
  30. import { baseNode } from '../common/config';
  31. import FrameToolBar from './frameToolBar.vue';
  32. export default {
  33. components:{ElDropdownMenu,FrameToolBar},
  34. data() {
  35. this.baseNode = baseNode
  36. return {
  37. graph:null,
  38. contextMenu:[{
  39. label: '编辑',
  40. key: 'edit',
  41. icon: 'el-icon-edit'
  42. },
  43. {
  44. label: '删除',
  45. key: 'del',
  46. icon: 'el-icon-delete'
  47. }],//右键菜单
  48. isSelectEdge:false,
  49. isSelectNode:false,
  50. currentCell:null,
  51. canRedo:false,
  52. canUndo:false
  53. };
  54. },
  55. watch:{
  56. cleanSelect(newVal){
  57. if(newVal){
  58. this.currentCell = null
  59. }
  60. }
  61. },
  62. methods: {
  63. init(){
  64. //如果需要在内部调用vue实例,则初始化时就将this传入
  65. this.graph = new myGraph('frameContainer',this);
  66. //mock
  67. this.graph.addNode({
  68. ...baseNode,
  69. ...{
  70. data:{id:653,userId:218},
  71. label:'text'
  72. }})
  73. this.graph.addNode({
  74. ...baseNode,
  75. ...{
  76. x:200,
  77. y:200,
  78. data:{id:652,userId:218},
  79. label:'text2'
  80. }})
  81. this.graph.addNode({
  82. ...baseNode,
  83. ...{
  84. x:400,
  85. y:200,
  86. data:{id:370,userId:204},
  87. label:'别人的框架测试'
  88. }})
  89. //如果有内容
  90. this.graph.scrollToContent({ animation: { duration: 600 }})
  91. //如果是非编辑页,加载完成画布内容后冻结画布
  92. !window.location.pathname.startsWith('/editframe')&&this.graph.freeze()
  93. //如果是编辑页,加载完成后清楚历史数据
  94. window.location.pathname.startsWith('/editframe')&&this.graph.cleanHistory()
  95. },
  96. editNode(node){
  97. //获取视口范围
  98. const position = this.graph.getContentArea()
  99. const nodes = this.graph.getNodes()
  100. const currentNode = nodes.find(item=>item.id===node.nodeId)
  101. if(currentNode){
  102. currentNode.data.id=node.nodeLink
  103. currentNode.label=node.nodeName
  104. }else{
  105. //在视口范围内添加节点
  106. this.graph.addNode({
  107. ...baseNode,
  108. ...{
  109. x:position.x+position.width/2,
  110. y:position.y+position.height/2,
  111. width:120,
  112. height:50,
  113. data:{
  114. id:node.nodeLink.id,//存储节点对应的myETA分类id
  115. userId:node.nodeLink.userId
  116. },
  117. label:node.nodeName||''
  118. }})
  119. }
  120. },
  121. handleContext(key){
  122. const select_cell = this.graph.getSelectedCells()
  123. if(!select_cell.length) return
  124. if(key==='edit'){
  125. const {id} = select_cell[0]
  126. const node = this.graph.getNodes().find(item=>item.id===id)
  127. this.$emit('editNode',{
  128. nodeId:node.id,
  129. nodeName:node.label,
  130. nodeLink:{id:node.data.id,userId:node.data.userId}
  131. })
  132. }
  133. if(key==='del'){
  134. this.graph.removeCells(select_cell)
  135. this.hideContextMenu()
  136. }
  137. //清除选区
  138. this.graph.cleanSelection()
  139. },
  140. deleteNode(){},
  141. hideContextMenu(){
  142. const dom = $('#context-menu-wrapper')[0];
  143. dom.style.left = '-9999px';
  144. dom.style.top = '-9999px';
  145. },
  146. },
  147. mounted(){
  148. this.init()
  149. }
  150. };
  151. </script>
  152. <style lang="scss">
  153. .frame-container-wrap {
  154. width:100%;
  155. height:100%;
  156. display: flex;
  157. overflow: hidden;
  158. position: relative;
  159. padding-top: 24px;
  160. .minimap {
  161. position: absolute;
  162. right: 6px;
  163. bottom: 6px;
  164. box-sizing: border-box;
  165. .x6-widget-minimap-viewport {
  166. border-color: red;
  167. .x6-widget-minimap-viewport-zoom {
  168. border-color: red;
  169. }
  170. }
  171. .x6-widget-minimap {
  172. width: auto !important;
  173. height: auto !important;
  174. }
  175. }
  176. #context-menu-wrapper{
  177. position: fixed;
  178. z-index: 99;
  179. top: -9999px;
  180. left: -9999px;
  181. background: #fff;
  182. padding: 10px 0;
  183. box-shadow: 0 1px 4px #999;
  184. }
  185. #frameContainer{
  186. flex: 1;
  187. }
  188. .x6-graph-scroller {
  189. flex: 1;
  190. }
  191. .x6-port-body {
  192. display: none;
  193. }
  194. }
  195. </style>
  196. <style scoped lang="scss">
  197. </style>