¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <vue-flowchart-editor ref="flowChart" class="vue-flowchart-editor"> |
| | | <div class="vfe-chart"> |
| | | <!-- é¡¶é¨èå --> |
| | | <div v-if="type !== 'detail'" class="vfe-chart-header"> |
| | | <editor-toolbar @handler-save="handlerSave" @reset-tree="handleResetTree" :chart-data="chartData"/> |
| | | </div> |
| | | <div class="vfe-chart-container"> |
| | | <!-- å·¦ä¾§é¡¹ç®æ --> |
| | | <div v-if="disabledBtn" class="vfe-chart-sidebar"> |
| | | <editor-item-panel :node-items="chartDataNodeItems"/> |
| | | </div> |
| | | <!-- 主å¾è¡¨ --> |
| | | <div class="vfe-chart-main"> |
| | | <flow |
| | | :data="chartData" |
| | | :onAfterChange="onAfterChange" |
| | | :onAfterItemSelected="onAfterItemSelected" |
| | | /> |
| | | <!-- æç¤ºæ¡ --> |
| | | <div class="tooltip"> |
| | | <template v-for="item in tooltipData"> |
| | | <p>{{ item.name }}: {{ item.value }}</p> |
| | | </template> |
| | | </div> |
| | | </div> |
| | | |
| | | <div v-if="type !== 'detail'" class="vfe-chart-panel"> |
| | | <div class="vfe-chart-panel-detail"> |
| | | <editor-detail-panel |
| | | ref="EditorDetailPanel" |
| | | :currentSelectedLine="currentSelectedLine" |
| | | :existEdges="existEdges" |
| | | :existNodes="existNodes" |
| | | :rowData="rowData" |
| | | :type="type" |
| | | /> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- å³é®èå --> |
| | | <editor-context-menu v-if="type !== 'detail'"/> |
| | | <!-- èªå®ä¹è¾¹é
ç½® --> |
| | | <register-edge |
| | | :config="customEdgeConfig" |
| | | extend="flow-polyline" |
| | | name="custom-polyline" |
| | | /> |
| | | <!-- èªå®ä¹å½ä»¤ç»ä»¶ --> |
| | | <custom-command :download="downloadImage"/> |
| | | </vue-flowchart-editor> |
| | | </template> |
| | | |
| | | <script> |
| | | import VueFlowchartEditor, {Flow, RegisterEdge} from "vue-flowchart-editor"; |
| | | import EditorToolbar from "./components/Toolbar"; |
| | | import EditorItemPanel from "./components/ItemPanel"; |
| | | import EditorDetailPanel from "./components/DetailPanel"; |
| | | import EditorMinimap from "./components/EditorMinimap"; |
| | | import EditorContextMenu from "./components/ContextMenu"; |
| | | import CustomCommand from "./components/CustomCommand"; |
| | | |
| | | export default { |
| | | name: "FlowchartEditor", |
| | | |
| | | components: { |
| | | VueFlowchartEditor, |
| | | Flow, |
| | | EditorToolbar, |
| | | EditorItemPanel, |
| | | EditorDetailPanel, |
| | | EditorMinimap, |
| | | EditorContextMenu, |
| | | CustomCommand, |
| | | RegisterEdge, |
| | | }, |
| | | |
| | | props: ["chartData", "chartDataNodeItems", "saveData", "rowData", "type"], |
| | | |
| | | data() { |
| | | return { |
| | | // å½åå¾è¡¨çæ°æ® |
| | | flowChartData: {}, |
| | | // èªå®ä¹è¾¹çé
ç½® |
| | | customEdgeConfig: { |
| | | getActivedStyle(/*item*/) { |
| | | return { |
| | | lineWidth: 3, // æ´»è·ç¶æä¸çè¾¹æ ·å¼ |
| | | }; |
| | | }, |
| | | getSelectedStyle(/*item*/) { |
| | | return { |
| | | lineWidth: 3, // éä¸ç¶æä¸çè¾¹æ ·å¼ |
| | | }; |
| | | }, |
| | | }, |
| | | // å·¥å
·æç¤ºæ¾ç¤ºå¼å
³ |
| | | tooltipShow: true, |
| | | // å·¥å
·æç¤ºæ°æ® |
| | | tooltipData: [], |
| | | // å·²åå¨çèç¹åè¾¹ |
| | | existNodes: this.chartData.nodes || [], |
| | | existEdges: this.chartData.edges || [], |
| | | // å½åéä¸çè¾¹ |
| | | currentSelectedLine: {} |
| | | }; |
| | | }, |
| | | computed: { |
| | | disabledBtn() { |
| | | return this.$store.state.flow.methodBtn; |
| | | } |
| | | }, |
| | | |
| | | mounted() { |
| | | // ç»ä»¶æè½½å®æåï¼èªå¨ç¼©æ¾ç»å¸ï¼ä»
卿·»å 模å¼ä¸ï¼ |
| | | if (this.type === "add") { |
| | | this.$nextTick(() => { |
| | | this.$refs.flowChart.propsAPI.executeCommand("autoZoom"); |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | | update(){ |
| | | this.$refs.flowChart.propsAPI.read(this.flowChartData); |
| | | }, |
| | | // å¤çå¾è¡¨æ°æ®æ´æ¹çäºä»¶ |
| | | onAfterChange(e) { |
| | | console.log(e) |
| | | try { |
| | | if('edit' === this.$store.state.flow.type){ |
| | | this.$refs.flowChart.propsAPI.remove(e.item); |
| | | if(e.action === 'remove'){ |
| | | this.$message.error('ç¼è¾ç¶æä¸ä¸è½åæ¢éä¸é¡¹ï¼'); |
| | | } |
| | | return; |
| | | } |
| | | // å¦ææ·»å äºèç¹ä¸èç¹æ²¡æè¢«æ´æ¹è¿ |
| | | if (e.action === "add" && e.model.type === "node") { |
| | | if (!e.model.change) { |
| | | this.$refs.flowChart.propsAPI.remove(e.item); // ç§»é¤åæçèç¹ |
| | | e.model.id = e.model.label; // ä½¿ç¨æ ç¾ä½ä¸ºèç¹ç ID |
| | | e.model.change = true; |
| | | this.$refs.flowChart.propsAPI.add("node", e.model); // æ·»å æ°çèç¹ |
| | | } |
| | | } |
| | | } catch (err) { |
| | | console.log(err) |
| | | // å¤çèç¹ ID å²çªé误 |
| | | if ( |
| | | err.message === |
| | | `id:${e.model.label} has already been set, please set new one` |
| | | ) { |
| | | this.$message.error("ä¸è½æ·»å å·²åå¨çèç¹ï¼"); |
| | | } |
| | | } |
| | | // ä¿åå½åçèç¹åè¾¹æ°æ® |
| | | const {nodes, edges} = this.$refs.flowChart.propsAPI.save(); |
| | | this.existNodes = nodes || []; |
| | | this.existEdges = edges || []; |
| | | }, |
| | | // å¤çéä¸çº¿ååçäºä»¶ åå¡«å½åçº¿ä¿¡æ¯ |
| | | onAfterItemSelected({item}) { |
| | | if (item.target) { |
| | | // æ¥æ¾å½åéä¸çè¾¹ |
| | | const currentEdge = this.existEdges.filter(itm => itm.id === item.id)[0] || {}; |
| | | if (!Array.isArray(currentEdge.events)) { |
| | | currentEdge.events = [] |
| | | } |
| | | this.currentSelectedLine = currentEdge; |
| | | } |
| | | }, |
| | | |
| | | // ä¸è½½å¾ç |
| | | _downloadImage(data, filename = "flowchart.png") { |
| | | const a = document.createElement("a"); |
| | | a.href = data; |
| | | a.download = filename; |
| | | document.body.appendChild(a); |
| | | a.click(); |
| | | }, |
| | | |
| | | // è°ç¨ä¸è½½å¾çæ¹æ³ |
| | | downloadImage() { |
| | | const page = this.$refs["flowChart"].propsAPI.editor.getCurrentPage(); |
| | | this._downloadImage(page.saveImage().toDataURL("image/png")); |
| | | }, |
| | | // è·åæ°çè¡æ°æ®ï¼ä»è¯¦ç»é¢æ¿ä¸ï¼ |
| | | getNewRowData() { |
| | | return this.$refs.EditorDetailPanel.getNewRowDate(); |
| | | }, |
| | | // è·åå½åå¾è¡¨çæ°æ® |
| | | getFlowData() { |
| | | return this.$refs.flowChart.propsAPI.save(); |
| | | }, |
| | | // è·åè¾¹äºä»¶å表ï¼ä»è¯¦ç»é¢æ¿ä¸ï¼ |
| | | getEdgesEvents() { |
| | | return this.$refs.EditorDetailPanel.edgeEventList; |
| | | }, |
| | | |
| | | // è°ç¨ç¶ç»ä»¶éç½® |
| | | handleResetTree(){ |
| | | this.$emit('reset-tree'); |
| | | }, |
| | | handlerSave(){ |
| | | this.$emit('handler-save') |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .vue-flowchart-editor { |
| | | display: flex; |
| | | flex: 1; |
| | | flex-direction: column; |
| | | width: 100%; |
| | | height: 100%; |
| | | background: #fff; |
| | | } |
| | | |
| | | .vfe-chart { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | .vfe-chart-header { |
| | | border: 1px solid #e6e9ed; |
| | | padding: 8px; |
| | | } |
| | | |
| | | .vfe-chart-container { |
| | | flex: 1; |
| | | display: flex; |
| | | height: 550px; |
| | | overflow: hidden; |
| | | |
| | | .vfe-chart-main { |
| | | position: relative; |
| | | flex: 1; |
| | | height: 80vh; // fix scroll show |
| | | width: 65%; |
| | | |
| | | .tooltip { |
| | | position: absolute; |
| | | display: none; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100px; |
| | | height: auto; |
| | | padding: 15px; |
| | | border-radius: 10px; |
| | | z-index: 999; |
| | | opacity: 0.8; |
| | | color: #ffffff; |
| | | font-size: 12px; |
| | | background-color: #000; |
| | | |
| | | p { |
| | | margin: 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .vfe-chart-sidebar { |
| | | margin-top: 10px; |
| | | position: relative; |
| | | display: flex; |
| | | justify-content: center; |
| | | width: 210px; |
| | | background-color: #fafafa; |
| | | border-right: 1px solid #e6e9ed; |
| | | } |
| | | |
| | | .vfe-chart-panel { |
| | | position: relative; |
| | | width: 260px; |
| | | background-color: #fafafa; |
| | | border-left: 1px solid #e6e9ed; |
| | | overflow-y: scroll; |
| | | |
| | | .vfe-chart-panel-detail { |
| | | box-sizing: border-box; |
| | | padding: 10px; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |