| | |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped></style> |
| | | <style lang="scss" scoped></style> |
| | |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="less" scoped></style> |
| | | <style lang="scss" scoped></style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import '@antv/x6-vue-shape'; |
| | | import { Graph,Shape,Addon,FunctionExt} from '@antv/x6' |
| | | // ææ½çæå边形æè
åå½¢ |
| | | export const startDragToGraph = (graph,type,e) =>{ |
| | | const node = |
| | | type === 'Rect' |
| | | ? graph.createNode({ |
| | | width: 100, |
| | | height: 60, |
| | | attrs: { |
| | | label: { |
| | | text: 'æ£æ¹å½¢èç¹', |
| | | fill: '#000000', |
| | | fontSize: 14, |
| | | textWrap: { |
| | | width: -10, |
| | | height: -10, |
| | | ellipsis: true |
| | | } |
| | | }, |
| | | body: { |
| | | stroke: '#000000', |
| | | strokeWidth: 1, |
| | | fill: '#ffffff' |
| | | } |
| | | }, |
| | | ports: ports |
| | | }) |
| | | : type === 'Circle'?graph.createNode({ |
| | | shape: 'ellipse', |
| | | width: 100, |
| | | height: 100, |
| | | attrs: { |
| | | label: { |
| | | text: 'åå½¢èç¹', |
| | | fill: '#000000', |
| | | fontSize: 14, |
| | | textWrap: { |
| | | width: -20, |
| | | height: -10, |
| | | ellipsis: true |
| | | } |
| | | }, |
| | | body: { |
| | | stroke: '#000000', |
| | | strokeWidth: 1, |
| | | fill: '#ffffff' |
| | | } |
| | | }, |
| | | ports: ports |
| | | }): |
| | | graph.createNode({ |
| | | shape: 'polygon', |
| | | x: 40, |
| | | y: 40, |
| | | width: 120, |
| | | height: 120, |
| | | attrs: { |
| | | label: { |
| | | text: 'æ¡ä»¶èç¹', |
| | | fill: '#000000', |
| | | fontSize: 14, |
| | | textWrap: { |
| | | width: -50, |
| | | height: '70%', |
| | | ellipsis: true |
| | | } |
| | | }, |
| | | body: { |
| | | fill: '#ffffff', |
| | | stroke: '#000000', |
| | | refPoints: '0,10 10,0 20,10 10,20', |
| | | strokeWidth: 1 |
| | | } |
| | | }, |
| | | ports: ports |
| | | }) |
| | | const dnd = new Addon.Dnd({target:graph}) |
| | | dnd.start(node,e) |
| | | } |
| | | const ports = { |
| | | groups: { |
| | | // è¾å
¥é¾æ¥æ¡©ç¾¤ç»å®ä¹ |
| | | top: { |
| | | position: 'top', |
| | | attrs: { |
| | | circle: { |
| | | r: 4, |
| | | magnet: true, |
| | | stroke: '#2D8CF0', |
| | | strokeWidth: 2, |
| | | fill: '#fff', |
| | | }, |
| | | }, |
| | | }, |
| | | // è¾åºé¾æ¥æ¡©ç¾¤ç»å®ä¹ |
| | | bottom: { |
| | | position: 'bottom', |
| | | attrs: { |
| | | circle: { |
| | | r: 4, |
| | | magnet: true, |
| | | stroke: '#2D8CF0', |
| | | strokeWidth: 2, |
| | | fill: '#fff', |
| | | }, |
| | | }, |
| | | }, |
| | | left: { |
| | | position: 'left', |
| | | attrs: { |
| | | circle: { |
| | | r: 4, |
| | | magnet: true, |
| | | stroke: '#2D8CF0', |
| | | strokeWidth: 2, |
| | | fill: '#fff', |
| | | }, |
| | | }, |
| | | }, |
| | | right: { |
| | | position: 'right', |
| | | attrs: { |
| | | circle: { |
| | | r: 4, |
| | | magnet: true, |
| | | stroke: '#2D8CF0', |
| | | strokeWidth: 2, |
| | | fill: '#fff', |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | items: [ |
| | | { |
| | | id: 'port1', |
| | | group: 'top', |
| | | }, |
| | | { |
| | | id: 'port2', |
| | | group: 'bottom', |
| | | }, |
| | | { |
| | | id: 'port3', |
| | | group: 'left', |
| | | }, |
| | | { |
| | | id: 'port4', |
| | | group: 'right', |
| | | } |
| | | ], |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="drawer_container"> |
| | | <div v-if="drawerType === 'grid'"> |
| | | <div class="drawer_title">ç»å¸èæ¯è®¾ç½®</div> |
| | | <div class="drawer_wrap"> |
| | | <el-form label-position="left" label-width="85px"> |
| | | <el-form-item label="æ¯å¦æ¾ç¤ºç½æ ¼" label-width="100px"> |
| | | <el-switch v-model="showGrid" @change="changeGrid" /> |
| | | </el-form-item> |
| | | <div v-show="showGrid"> |
| | | <el-form-item label="ç½æ ¼ç±»å"> |
| | | <el-radio-group v-model="grid.type" @change="changeGridType"> |
| | | <el-radio |
| | | v-for="item in gridTypeList" |
| | | :label="item.value" |
| | | :key="item.value" |
| | | > |
| | | <span>{{ item.label }}</span> |
| | | </el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label-width="70px" label="ç½æ ¼å¤§å°"> |
| | | <el-slider |
| | | v-model="grid.size" |
| | | :min="0" |
| | | :max="30" |
| | | @change="changeGrid" |
| | | ></el-slider> |
| | | </el-form-item> |
| | | <el-form-item label="ç½æ ¼é¢è²"> |
| | | <el-color-picker v-model="grid.args.color" @change="changeGrid" /> |
| | | </el-form-item> |
| | | <el-form-item label-width="85px" label="ç½æ ¼çº¿å®½åº¦"> |
| | | <el-slider |
| | | v-model="grid.args.thickness" |
| | | :min="0" |
| | | :max="20" |
| | | @change="changeGrid" |
| | | ></el-slider> |
| | | </el-form-item> |
| | | </div> |
| | | </el-form> |
| | | </div> |
| | | </div> |
| | | <div v-if="drawerType === 'node'"> |
| | | <div class="drawer_title">ä»»å¡èç¹è®¾ç½®</div> |
| | | <div class="drawer_wrap"> |
| | | <el-form label-position="left" label-width="80px"> |
| | | <el-form-item label="ä»»å¡åç§°"> |
| | | <el-input |
| | | v-model="drawerNode.nodeText" |
| | | @change="changeNodeText" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="任塿§è¡äºº" label-width="80px"> |
| | | <el-input |
| | | v-model="drawerNode.nodeText" |
| | | @change="changeNodeText" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="èç¹èæ¯"> |
| | | <el-color-picker v-model="drawerNode.fill" @change="changeFill" /> |
| | | </el-form-item> |
| | | <el-form-item label-width="70px" label="åä½å¤§å°"> |
| | | <el-slider |
| | | v-model="drawerNode.fontSize" |
| | | :min="10" |
| | | :max="20" |
| | | @change="changefontSize" |
| | | ></el-slider> |
| | | </el-form-item> |
| | | <el-form-item label="åä½é¢è²"> |
| | | <el-color-picker |
| | | v-model="drawerNode.fontFill" |
| | | @change="changeFontFill" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label-width="70px" label="è¾¹æ¡å®½åº¦"> |
| | | <el-slider |
| | | v-model="drawerNode.strokeWidth" |
| | | :min="0" |
| | | :max="10" |
| | | @change="changeStrokeWidth" |
| | | ></el-slider> |
| | | </el-form-item> |
| | | <el-form-item label="è¾¹æ¡é¢è²"> |
| | | <el-color-picker |
| | | v-model="drawerNode.stroke" |
| | | @change="changeStroke" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="åè½"> |
| | | <el-button type="primary" icon="el-icon-upload" @click="toTopZIndex" |
| | | >置顶</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | class="margin-left-10" |
| | | icon="el-icon-delete" |
| | | @click="deleteNode" |
| | | >å é¤</el-button |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-button |
| | | type="success" |
| | | class="margin-left-10" |
| | | icon="el-icon-download" |
| | | @click="exportData" |
| | | >ä¿å</el-button |
| | | > |
| | | </div> |
| | | </div> |
| | | <div v-if="drawerType === 'edge'"> |
| | | <div class="drawer_title">线æ¡è®¾ç½®</div> |
| | | <div class="drawer_wrap"> |
| | | <el-form label-position="left" label-width="80px"> |
| | | <el-form-item label="çº¿æ¡ææ¬"> |
| | | <el-input |
| | | v-model="drawerEdge.EdgeText" |
| | | @change="changeEdgeText" |
| | | ></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="线æ¡å®½åº¦" label-width="80px"> |
| | | <el-slider |
| | | v-model="drawerEdge.edgeWidth" |
| | | :min="1" |
| | | :max="10" |
| | | @change="changeEdgeWidth" |
| | | ></el-slider> |
| | | </el-form-item> |
| | | <el-form-item label="线æ¡é¢è²"> |
| | | <el-color-picker |
| | | v-model="drawerEdge.edgeColor" |
| | | @change="changeEdgeColor" |
| | | /> |
| | | </el-form-item> |
| | | <el-form-item label="åè½"> |
| | | <el-button type="primary" icon="el-icon-upload" @click="toTopZIndex" |
| | | >置顶</el-button |
| | | > |
| | | <el-button |
| | | type="danger" |
| | | class="margin-left-10" |
| | | icon="el-icon-delete" |
| | | @click="deleteNode" |
| | | >å é¤</el-button |
| | | > |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-button |
| | | type="success" |
| | | class="margin-left-10" |
| | | icon="el-icon-download" |
| | | @click="exportData" |
| | | >ä¿å</el-button |
| | | > |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "RightDrawer", |
| | | data() { |
| | | return { |
| | | gridTypeList: [ |
| | | { |
| | | label: "åè¾¹ç½æ ¼", |
| | | value: "mesh", |
| | | }, |
| | | { |
| | | label: "ç¹ç¶ç½æ ¼", |
| | | value: "dot", |
| | | }, |
| | | ], |
| | | baseData: "", |
| | | showGrid: true, |
| | | drawerNode: { |
| | | fill: "", |
| | | nodeText: "", |
| | | fontSize: null, |
| | | fontFill: "", |
| | | strokeWidth: null, |
| | | stroke: "", |
| | | }, |
| | | drawerEdge: { |
| | | EdgeText: "", |
| | | edgeWidth: null, |
| | | edgeColor: "", |
| | | }, |
| | | }; |
| | | }, |
| | | props: { |
| | | drawerType: { |
| | | type: String, |
| | | }, |
| | | selectCell: { |
| | | type: String | Object, |
| | | }, |
| | | graph: { |
| | | type: String | Object, |
| | | }, |
| | | grid: { |
| | | type: Object, |
| | | }, |
| | | }, |
| | | created() {}, |
| | | mounted() {}, |
| | | watch: { |
| | | selectCell: { |
| | | handler(val) { |
| | | if (val) { |
| | | if (val.isNode()) { |
| | | //èç¹ |
| | | this.drawerNode.fill = val.store.data.attrs.body.fill; |
| | | this.drawerNode.nodeText = val.store.data.attrs.label.text; |
| | | this.drawerNode.fontFill = val.store.data.attrs.label.fill; |
| | | this.drawerNode.fontSize = Number( |
| | | val.store.data.attrs.label.fontSize |
| | | ); |
| | | this.drawerNode.strokeWidth = Number( |
| | | val.store.data.attrs.body.strokeWidth |
| | | ); |
| | | this.drawerNode.stroke = val.store.data.attrs.body.stroke; |
| | | } else { |
| | | //è¾¹ |
| | | this.drawerEdge.EdgeText = val.store.data.labels |
| | | ? val.store.data.labels[0].text |
| | | : ""; |
| | | this.drawerEdge.edgeWidth = Number( |
| | | val.store.data.attrs.line.strokeWidth |
| | | ); |
| | | this.drawerEdge.edgeColor = val.store.data.attrs.line.stroke; |
| | | } |
| | | } |
| | | }, |
| | | immediate: true, |
| | | deep: false, |
| | | }, |
| | | }, |
| | | methods: { |
| | | // ç½æ ¼è®¾ç½® |
| | | changeGrid() { |
| | | this.showGrid ? this.graph.showGrid() : this.graph.hideGrid(); |
| | | }, |
| | | changeGridType(e) { |
| | | this.grid.type = e; |
| | | this.changeGrid(); |
| | | }, |
| | | changeGrid() { |
| | | this.graph.drawGrid({ |
| | | ...this.grid, |
| | | }); |
| | | }, |
| | | // èç¹è®¾ç½® |
| | | changeStrokeWidth(val) { |
| | | this.selectCell.attr("body/strokeWidth", val); |
| | | }, |
| | | changefontSize(val) { |
| | | this.selectCell.attr("label/fontSize", val); |
| | | }, |
| | | changeNodeText() { |
| | | this.selectCell.attr("label/text", this.drawerNode.nodeText); |
| | | }, |
| | | changeStroke(val) { |
| | | this.drawerNode.stroke = val; |
| | | this.selectCell.attr("body/stroke", this.drawerNode.stroke); |
| | | }, |
| | | changeFontFill(val) { |
| | | this.drawerNode.fontFill = val; |
| | | this.selectCell.attr("label/fill", this.drawerNode.fontFill); |
| | | }, |
| | | changeFill(val) { |
| | | this.drawerNode.fill = val; |
| | | this.selectCell.attr("body/fill", val); |
| | | }, |
| | | // 边设置 |
| | | changeEdgeText() { |
| | | console.log(this.drawerEdge.EdgeText); |
| | | this.selectCell.setLabels([ |
| | | { attrs: { label: { text: this.drawerEdge.EdgeText } } }, |
| | | ]); |
| | | }, |
| | | changeEdgeWidth(val) { |
| | | this.drawerEdge.edgeWidth = val; |
| | | this.selectCell.attr("line/strokeWidth", this.drawerEdge.edgeWidth); |
| | | }, |
| | | changeEdgeColor(val) { |
| | | this.drawerEdge.stroke = val; |
| | | this.selectCell.attr("line/stroke", this.drawerEdge.stroke); |
| | | }, |
| | | // 置顶 |
| | | toTopZIndex() { |
| | | this.selectCell.toFront(); |
| | | }, |
| | | // å é¤ |
| | | deleteNode() { |
| | | this.$emit("deleteNode"); |
| | | }, |
| | | // å¯¼åºæ°æ® |
| | | exportData() { |
| | | this.baseData = this.graph.toJSON(); |
| | | console.log(this.baseData); |
| | | }, |
| | | // 导å
¥æ°æ® |
| | | importData() { |
| | | this.graph.fromJSON(this.baseData); |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .drawer_container { |
| | | max-width: 300px; |
| | | min-width: 300px; |
| | | .drawer_title { |
| | | border-bottom: 1px solid #e8eaec; |
| | | box-sizing: border-box; |
| | | padding: 14px 16px; |
| | | color: #333; |
| | | font-size: 16px; |
| | | } |
| | | .drawer_wrap { |
| | | box-sizing: border-box; |
| | | padding: 20px 10px 20px 20px; |
| | | } |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | @font-face {font-family: "iconfont"; |
| | | src: url('//at.alicdn.com/t/font_2431749_zpzhmewttjs.eot?t=1616140304099'); /* IE9 */ |
| | | src: url('//at.alicdn.com/t/font_2431749_zpzhmewttjs.eot?t=1616140304099#iefix') format('embedded-opentype'), /* IE6-IE8 */ |
| | | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), |
| | | url('//at.alicdn.com/t/font_2431749_zpzhmewttjs.woff?t=1616140304099') format('woff'), |
| | | url('//at.alicdn.com/t/font_2431749_zpzhmewttjs.ttf?t=1616140304099') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ |
| | | url('//at.alicdn.com/t/font_2431749_zpzhmewttjs.svg?t=1616140304099#iconfont') format('svg'); /* iOS 4.1- */ |
| | | } |
| | | |
| | | .iconfont { |
| | | font-family: "iconfont" !important; |
| | | font-size: 16px; |
| | | font-style: normal; |
| | | -webkit-font-smoothing: antialiased; |
| | | -moz-osx-font-smoothing: grayscale; |
| | | } |
| | | |
| | | .icon-straight:before { |
| | | content: "\e752"; |
| | | } |
| | | |
| | | .icon-mousepointershubiao:before { |
| | | content: "\e6df"; |
| | | } |
| | | |
| | | .icon-ai28:before { |
| | | content: "\e68e"; |
| | | } |
| | | |
| | | .icon-baocun:before { |
| | | content: "\e60b"; |
| | | } |
| | | |
| | | .icon-Down-Right:before { |
| | | content: "\e741"; |
| | | } |
| | | |
| | | .icon-tuozhuai:before { |
| | | content: "\e636"; |
| | | } |
| | | |
| | | .icon-circle:before { |
| | | content: "\e642"; |
| | | } |
| | | |
| | | .icon-quxian:before { |
| | | content: "\e637"; |
| | | } |
| | | |
| | | .icon-square:before { |
| | | content: "\e676"; |
| | | } |
| | | |
| | | .icon-shanchu:before { |
| | | content: "\e696"; |
| | | } |
| | | |
| | | .icon-jiantou:before { |
| | | content: "\e7e2"; |
| | | } |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | |
| | | .container_warp { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100vh; |
| | | display: flex; |
| | | .operating { |
| | | position: absolute; |
| | | top: 0; |
| | | z-index: 99; |
| | | background-color: #ffffff; |
| | | padding: 20px 10px; |
| | | box-shadow: 1px 1px 4px 0 #0a0a0a2e; |
| | | } |
| | | } |
| | | .btn-group { |
| | | border-right: 1px solid #efefef; |
| | | display: inline-block; |
| | | padding-left: 10px; |
| | | padding-right: 14px; |
| | | position: relative; |
| | | .btn-group_tips { |
| | | text-align: center; |
| | | top: 63px; |
| | | left: 1px; |
| | | position: absolute; |
| | | color: #fff; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | width: 120px; |
| | | height: 60px; |
| | | background: #515a6e; |
| | | border-radius: 6px; |
| | | animation: tips 4s; |
| | | transition: all 1s; |
| | | &:after { |
| | | content: ""; |
| | | width: 0; |
| | | height: 0; |
| | | position: absolute; |
| | | top: -5px; |
| | | left: 46%; |
| | | border-width: 0 5px 5px; |
| | | border-style: solid; |
| | | border-color: transparent transparent #515a6e; |
| | | } |
| | | } |
| | | &:last-of-type { |
| | | border-right: 0; |
| | | } |
| | | .btn { |
| | | display: inline-block; |
| | | margin: 2px; |
| | | width: 30px; |
| | | height: 30px; |
| | | line-height: 30px; |
| | | text-align: center; |
| | | cursor: pointer; |
| | | transition: all .4s; |
| | | border-radius: 6px; |
| | | border: 1px solid rgba(233, 233, 233, 0); |
| | | i { |
| | | font-size: 20px; |
| | | } |
| | | } |
| | | .currentArrow { |
| | | background: #2d8cf0; |
| | | color: #fff; |
| | | } |
| | | } |
| | | @keyframes tips { |
| | | 0% { |
| | | opacity: 0; |
| | | transform: scale(0); |
| | | } |
| | | 10% { |
| | | opacity: 1; |
| | | transform: scale(1); |
| | | } |
| | | 90% { |
| | | opacity: 1; |
| | | transform: scale(1); |
| | | } |
| | | 100% { |
| | | opacity: 0; |
| | | transform: scale(0); |
| | | } |
| | | } |
| | | .rotate-square { |
| | | display: inline-block; |
| | | transform: rotate(45deg); |
| | | } |
| | | .my-snapline { |
| | | color: #000; |
| | | } |
| | | .right_drawer { |
| | | height: 100%; |
| | | width: 300px; |
| | | border-left: 1px solid #eee; |
| | | background: #fff; |
| | | } |
| | |
| | | <template> |
| | | <div>è§å¾</div> |
| | | <div class="container_warp"> |
| | | <div id="containerChart"></div> |
| | | <RightDrawer |
| | | class="right_drawer" |
| | | :drawerType="type" |
| | | :selectCell="selectCell" |
| | | :graph="graph" |
| | | :grid="grid" |
| | | @deleteNode="deleteNode" |
| | | ></RightDrawer> |
| | | |
| | | <div class="operating"> |
| | | <div class="btn-group"> |
| | | <div |
| | | class="btn" |
| | | title="åå½¢èç¹" |
| | | @mousedown="startDrag('Circle', $event)" |
| | | > |
| | | <i class="iconfont icon-circle"></i> |
| | | </div> |
| | | <div |
| | | class="btn" |
| | | title="æ£æ¹å½¢èç¹" |
| | | @mousedown="startDrag('Rect', $event)" |
| | | > |
| | | <i class="iconfont icon-square"></i> |
| | | </div> |
| | | <div class="btn" title="æ¡ä»¶èç¹"> |
| | | <i |
| | | class="iconfont icon-square rotate-square" |
| | | @mousedown="startDrag('polygon', $event)" |
| | | ></i> |
| | | </div> |
| | | <div class="btn-group_tips" v-if="showTips"> |
| | | ææ½çæ<br />èµäº§ææå¾å½¢ |
| | | </div> |
| | | </div> |
| | | <div class="btn-group"> |
| | | <el-tooltip content="ç´çº¿ç®å¤´" placement="bottom"> |
| | | <div |
| | | :class="['btn', currentArrow === 1 ? 'currentArrow' : '']" |
| | | @click="changeEdgeType('normal')" |
| | | > |
| | | <i class="iconfont icon-ai28"></i> |
| | | </div> |
| | | </el-tooltip> |
| | | <el-tooltip content="æ²çº¿ç®å¤´" placement="bottom"> |
| | | <div |
| | | :class="['btn', currentArrow === 2 ? 'currentArrow' : '']" |
| | | @click="changeEdgeType('smooth')" |
| | | > |
| | | <i class="iconfont icon-Down-Right"></i> |
| | | </div> |
| | | </el-tooltip> |
| | | <el-tooltip content="ç´è§ç®å¤´" placement="bottom"> |
| | | <div |
| | | :class="['btn', currentArrow === 3 ? 'currentArrow' : '']" |
| | | @click="changeEdgeType()" |
| | | > |
| | | <i class="iconfont icon-jiantou"></i> |
| | | </div> |
| | | </el-tooltip> |
| | | </div> |
| | | <div class="btn-group"> |
| | | <el-tooltip content="å é¤" placement="bottom"> |
| | | <div class="btn" @click="deleteNode()" style="margin-top: 5px"> |
| | | <i class="iconfont icon-shanchu"></i> |
| | | </div> |
| | | </el-tooltip> |
| | | <el-tooltip content="ä¿åPNG" placement="bottom"> |
| | | <div class="btn" @click="saveToPNG()" title="ä¿å"> |
| | | <i class="iconfont icon-baocun"></i> |
| | | </div> |
| | | </el-tooltip> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import "@antv/x6-vue-shape"; |
| | | import { Graph, Shape, Addon, FunctionExt, DataUri } from "@antv/x6"; |
| | | import RightDrawer from "./RightDrawer"; |
| | | import insertCss from "insert-css"; |
| | | import { startDragToGraph } from "./Graph/methods.js"; |
| | | const data = {}; |
| | | export default { |
| | | data() { |
| | | return {}; |
| | | return { |
| | | graph: "", |
| | | value1: true, |
| | | type: "grid", |
| | | selectCell: "", |
| | | connectEdgeType: { |
| | | //è¿çº¿æ¹å¼ |
| | | connector: "normal", |
| | | router: { |
| | | name: "", |
| | | }, |
| | | }, |
| | | showTips: false, |
| | | currentArrow: 1, |
| | | grid: { |
| | | // ç½æ ¼è®¾ç½® |
| | | size: 20, // ç½æ ¼å¤§å° 10px |
| | | visible: true, // 渲æç½æ ¼èæ¯ |
| | | type: "mesh", |
| | | args: { |
| | | color: "#D0D0D0", |
| | | thickness: 1, // ç½æ ¼çº¿å®½åº¦/ç½æ ¼ç¹å¤§å° |
| | | factor: 10, |
| | | }, |
| | | }, |
| | | }; |
| | | }, |
| | | |
| | | created() {}, |
| | | |
| | | methods: {}, |
| | | components: { |
| | | RightDrawer, |
| | | }, |
| | | methods: { |
| | | initX6() { |
| | | var _that = this; |
| | | this.graph = new Graph({ |
| | | container: document.getElementById("containerChart"), |
| | | width: 1700, |
| | | height: "100%", |
| | | grid: _that.grid, |
| | | resizing: { |
| | | //è°æ´èç¹å®½é« |
| | | enabled: true, |
| | | orthogonal: false, |
| | | }, |
| | | selecting: true, //å¯é |
| | | snapline: true, |
| | | interacting: { |
| | | edgeLabelMovable: true, |
| | | }, |
| | | connecting: { |
| | | // èç¹è¿æ¥ |
| | | anchor: "center", |
| | | connectionPoint: "anchor", |
| | | allowBlank: false, |
| | | snap: true, |
| | | createEdge() { |
| | | return new Shape.Edge({ |
| | | attrs: { |
| | | line: { |
| | | stroke: "#1890ff", |
| | | strokeWidth: 1, |
| | | targetMarker: { |
| | | name: "classic", |
| | | size: 8, |
| | | }, |
| | | strokeDasharray: 0, //è线 |
| | | style: { |
| | | animation: "ant-line 30s infinite linear", |
| | | }, |
| | | }, |
| | | }, |
| | | label: { |
| | | text: "", |
| | | }, |
| | | connector: _that.connectEdgeType.connector, |
| | | router: { |
| | | name: _that.connectEdgeType.router.name || "", |
| | | }, |
| | | zIndex: 0, |
| | | }); |
| | | }, |
| | | }, |
| | | highlighting: { |
| | | magnetAvailable: { |
| | | name: "stroke", |
| | | args: { |
| | | padding: 4, |
| | | attrs: { |
| | | strokeWidth: 4, |
| | | stroke: "#6a6c8a", |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | }); |
| | | insertCss(` |
| | | @keyframes ant-line { |
| | | to { |
| | | stroke-dashoffset: -1000 |
| | | } |
| | | } |
| | | `); |
| | | this.graph.fromJSON(data); |
| | | // éåãoptions å°è¢«ä¼ éå°äºä»¶åè°ä¸ã |
| | | this.graph.history.redo(); |
| | | // æ¤éãoptions å°è¢«ä¼ éå°äºä»¶åè°ä¸ |
| | | this.graph.history.undo(); |
| | | // é¼ æ ç§»å
¥ç§»åºèç¹ |
| | | this.graph.on( |
| | | "node:mouseenter", |
| | | FunctionExt.debounce(() => { |
| | | const container = document.getElementById("containerChart"); |
| | | const ports = container.querySelectorAll(".x6-port-body"); |
| | | this.showPorts(ports, true); |
| | | }), |
| | | 500 |
| | | ); |
| | | // é¼ æ ç§»å¼èç¹ |
| | | this.graph.on("node:mouseleave", () => { |
| | | const container = document.getElementById("containerChart"); |
| | | const ports = container.querySelectorAll(".x6-port-body"); |
| | | this.showPorts(ports, false); |
| | | }); |
| | | // åå»ç©ºç½ |
| | | this.graph.on("blank:click", () => { |
| | | this.type = "grid"; |
| | | }); |
| | | // åå»èç¹æè¾¹ |
| | | this.graph.on("cell:click", ({ cell }) => { |
| | | this.type = cell.isNode() ? "node" : "edge"; |
| | | }); |
| | | // éä¸çèç¹/è¾¹åçæ¹å(å¢å )æ¶è§¦åã |
| | | this.graph.on("selection:changed", (args) => { |
| | | args.added.forEach((cell) => { |
| | | this.selectCell = cell; |
| | | if (cell.isEdge()) { |
| | | cell.isEdge() && cell.attr("line/strokeDasharray", 5); //è线èè线 |
| | | cell.addTools([ |
| | | { |
| | | name: "vertices", |
| | | args: { |
| | | padding: 4, |
| | | attrs: { |
| | | strokeWidth: 0.1, |
| | | stroke: "#2d8cf0", |
| | | fill: "#ffffff", |
| | | }, |
| | | }, |
| | | }, |
| | | ]); |
| | | } |
| | | }); |
| | | args.removed.forEach((cell) => { |
| | | cell.isEdge() && cell.attr("line/strokeDasharray", 0); //æ£å¸¸çº¿ |
| | | cell.removeTools(); |
| | | }); |
| | | }); |
| | | }, |
| | | showPorts(ports, show) { |
| | | for (let i = 0, len = ports.length; i < len; i = i + 1) { |
| | | ports[i].style.visibility = show ? "visible" : "hidden"; |
| | | } |
| | | }, |
| | | // ææ½çææ£æ¹å½¢æè
åå½¢ |
| | | startDrag(type, e) { |
| | | startDragToGraph(this.graph, type, e); |
| | | }, |
| | | // å é¤èç¹ |
| | | deleteNode() { |
| | | const cell = this.graph.getSelectedCells(); |
| | | this.graph.removeCells(cell); |
| | | this.type = "grid"; |
| | | }, |
| | | // ä¿åpng |
| | | saveToPNG() { |
| | | this.$nextTick(() => { |
| | | this.graph.toPNG( |
| | | (dataUri) => { |
| | | // ä¸è½½ |
| | | DataUri.downloadDataUri(dataUri, "èµäº§ææå¾.png"); |
| | | }, |
| | | { |
| | | backgroundColor: "white", |
| | | padding: { |
| | | top: 50, |
| | | right: 50, |
| | | bottom: 50, |
| | | left: 50, |
| | | }, |
| | | quality: 1, |
| | | copyStyles: false, |
| | | } |
| | | ); |
| | | }); |
| | | }, |
| | | // æ¹åè¾¹å½¢ç¶ |
| | | changeEdgeType(e) { |
| | | if (e === "normal") { |
| | | this.connectEdgeType = { |
| | | connector: "normal", |
| | | router: { name: "" }, |
| | | }; |
| | | this.currentArrow = 1; |
| | | } else if (e === "smooth") { |
| | | this.connectEdgeType = { |
| | | connector: "smooth", |
| | | router: { name: "" }, |
| | | }; |
| | | this.currentArrow = 2; |
| | | } else { |
| | | this.connectEdgeType = { |
| | | connector: "normal", |
| | | router: { name: "manhattan" }, |
| | | }; |
| | | this.currentArrow = 3; |
| | | } |
| | | }, |
| | | }, |
| | | mounted() { |
| | | this.initX6(); |
| | | setTimeout(() => { |
| | | this.showTips = true; |
| | | }, 1000); |
| | | setTimeout(() => { |
| | | this.showTips = false; |
| | | }, 5000); |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped></style> |
| | | <style lang="scss"> |
| | | @import "./iconfont.css"; |
| | | @import "./index.scss"; |
| | | </style> |