From e48a56c2171f023f1978b0b6aec9befd43e7a9dc Mon Sep 17 00:00:00 2001 From: xyc <jc_xiong@hotmail.com> Date: 星期一, 04 十一月 2024 08:45:22 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- web/src/views/modules/taskReliability/TimeDiagram.vue | 434 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 405 insertions(+), 29 deletions(-) diff --git a/web/src/views/modules/taskReliability/TimeDiagram.vue b/web/src/views/modules/taskReliability/TimeDiagram.vue index a5fc186..15c0973 100644 --- a/web/src/views/modules/taskReliability/TimeDiagram.vue +++ b/web/src/views/modules/taskReliability/TimeDiagram.vue @@ -1,8 +1,8 @@ <template> - <div class="fa-card-a"> - <el-row :gutter="5"> + <div class="fa-card-a" style="width: calc(100% - 20px);height: calc(100vh - 128px)"> + <div > <div class="mod-taskReliability-simulatAssess"> - <el-form :inline="true" :model="dataForm" ref="dataForm" :disabled="dataForm.disabled" label-width="80px"> + <el-form :inline="true" :model="dataForm" ref="dataForm" :disabled="dataForm.disabled" > <zt-form-item label="浜у搧鑺傜偣" prop="productId"> <zt-select v-model="dataForm.productId" :datas="productList" @change="onProductSelected"/> </zt-form-item> @@ -12,36 +12,76 @@ <zt-form-item label="浠跨湡璁板綍" prop="simulatHis"> <zt-select v-model="dataForm.id" :datas="simulatList" @change="onSimulatSelected"/> </zt-form-item> + <zt-form-item label="鏃堕棿鍒嗙墖" prop="samplPeriod"> + <el-input v-model="dataForm.samplPeriod" readonly="false" style="width: 150px;vertical-align: baseline;"> + <template slot="append">鍒嗛挓</template> + </el-input> + </zt-form-item> + <zt-form-item label="浠跨湡娆℃暟" prop="simulatFrequency"> + <el-input v-model="dataForm.simulatFrequency" readonly="false" style="width: 150px;"> + </el-input> + </zt-form-item> + <zt-form-item> + <zt-button @click="getDiagram(null)">鏌ョ湅鏃跺簭鍥�</zt-button> + <el-dropdown style="margin-left: 10px" @command="download"> + <el-button type="primary"> + 涓嬭浇xml<i class="el-icon-arrow-down el-icon--right"></i> + </el-button> + <el-dropdown-menu slot="dropdown"> + <el-dropdown-item command="1">杈撳叆xml</el-dropdown-item> + <el-dropdown-item command="2">杈撳嚭xml</el-dropdown-item> + </el-dropdown-menu> + </el-dropdown> + </zt-form-item> </el-form> - <div> - <el-col :span="4"> + <div style="display: flex"> + <div style="width: 300px"> <div style="margin-right: 5px;height: calc(88vh - 100px)" v-if="isSelect"> - <product-model-tree @on-selected="onTreeSelected" showXdy="false" - ref="ProductModelTree" :isShow="false" basic="5"/> + <product-model-tree @on-selected="onTreeSelected" + ref="ProductModelTree" :isShow="false" :productId="dataForm.productId"/> </div> - </el-col> - <el-col :span="20"> - <div style="margin-top: 20px"> - <div> - <SimulatCurve ref="SimulatCurve"></SimulatCurve> + </div> + <div style="height: calc(100vh - 233px);width: calc(100% - 300px);margin-left:10px"> + <div style="margin-top:15px;width:100%; height:100%;border: 1px solid #EAEBEE;border-left:none;border-radius: 6px; + box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);"> +<!-- <div style="width:100%;height: 150px" id="thumbnail" class="minimap-container"></div>--> + <timeDiagramThumbnail ref="timeDiagramThumbnail" @getPoint="getPoint"></timeDiagramThumbnail> + <div id="flexLayout" style="display:flex;"> + <textDiagram class="flexLayout-item_1" ref="textDiagram"></textDiagram> + <div id="timeDiagram" class="flexLayout-item_2" style="height: 300px" ref="scrollView" @mousewheel="handleScroll"></div> </div> </div> - </el-col> + </div> </div> </div> - </el-row> + </div> + <el-dialog v-dialogDrag :title="title" top="1vh" width='95%' :visible.sync="dialogVisible2" v-if="dialogVisible2"> + <model-view ref="modelView"></model-view> + </el-dialog> </div> </template> <script> import SimulatCurve from "./SimulatCurve"; import ProductModelTree from "../basicInfo/ProductModelTree"; + import {Graph, Shape, Addon, Cell} from '@antv/x6' + import ModelView from "./ModelView"; + import textDiagram from "./textDiagram"; + import timeDiagramThumbnail from "./timeDiagramThumbnail" + import qs from "qs"; + import Cookies from "js-cookie"; export default { data() { return { + bigWidth:0, + left:400, + title:'', + knob:HTMLDivElement, + dialogVisible2: false, timers: '', + shape: '', isSelect: false, isShow: false, productList: [], @@ -49,6 +89,45 @@ taskList: [], MTBF: '', MTTR: '', + diagramJson: '', + graph: null, + timeDiagramWidth:document.documentElement.clientWidth - 300, + timeDiagramHeight:document.documentElement.clientHeight - 133, + smallTimeDiagramWidth:document.documentElement.clientWidth - 600, + globalGridAttr: { + type: 'mesh', + size: 10, + color: '#e5e5e5', + thickness: 1, + colorSecond: '#d0d0d0', + thicknessSecond: 1, + factor: 4, + bgColor: '#e5e5e5', + showImage: true, + repeat: 'watermark', + position: 'center', + bgSize: JSON.stringify({width: 150, height: 150}), + opacity: 0.1, + + stroke: '#5F95FF', + strokeWidth: 1, + connector: 'normal', + label: '', + nodeStroke: '#5F95FF', + nodeStrokeWidth: 1, + nodeFill: '#ffffff', + nodeFontSize: 12, + nodeColor: '#080808', + nodeText: '', + nodeDate: '', + nodeUsers: '', + nodeDataDate: '', + nodeDataText: '', + dataId: '', + inspectName: '', + distance: 0.5, + angle: 0, + }, dataForm: { id: '', pid: '', @@ -62,18 +141,232 @@ } } }, + created() { + let scrollView = this.$refs['scrollView'] + window.addEventListener('scroll', this.handleScroll,true); + }, + destroyed() { + let scrollView = this.$refs['scrollView'] + window.removeEventListener('scroll', this.handleScroll,true); + }, mounted() { this.getProductList() + this.init() + this.$refs.textDiagram.init() + this.$refs.timeDiagramThumbnail.init() }, components: { + ModelView, ProductModelTree, SimulatCurve, + textDiagram, + timeDiagramThumbnail }, - methods: { + handleScroll(){ + this.graph.getScrollbarPosition() + let left = this.graph.getScrollbarPosition().left + let top = this.graph.getScrollbarPosition().top + this.$refs.textDiagram.setScroll(top) + this.$refs.timeDiagramThumbnail.getNodePointX(left,this.bigWidth) + }, + init() { + this.graph = new Graph({ + container: document.getElementById('timeDiagram'), + // width: document.documentElement.clientWidth - 100, + height: document.documentElement.clientHeight - 440, + // async: true, + grid: { + visible: false, + }, + virtual:true, + embedding: { + enabled: true, + findParent({node}) { + const bbox = node.getBBox() + return this.getNodes().filter((node) => { + // 鍙湁 data.parent 涓� true 鐨勮妭鐐规墠鏄埗鑺傜偣 + const data = node.getData() + if (data && data.parent) { + const targetBBox = node.getBBox() + return bbox.isIntersectWithRect(targetBBox) + } + return false + }) + } + }, + autoResize: true, + scroller: { + enabled: true, + className:'my-scroller-drag', + pageWidth:100, + pageVisible:true, + // pageBreak:true, + padding: { + top: 0, + right: 0, + bottom: 0, + left: 0, + }, + minVisibleWidth: 500, + minVisibleHeight:300, + pannable: true, + }, + createEdge() { + return new Shape.Edge({ + data: { + id: '', + status: '', + startTime:'', + endTime: '', + }, + attrs: { + line: { + stroke: '#A2B1C3', + strokeWidth: 2, + targetMarker: null, + } + }, + tools: { + name: 'vertices', + }, + zIndex: 0, + }) + }, + keyboard: true, + }) + this.knob = document.createElement('div',false) + this.knob.style.position = 'absolute' + document.getElementById('timeDiagram').appendChild(this.knob) + this.graph.positionContent('left',{ padding: { left: 0 }}) + // this.graph.centerContent() + Graph.registerNode( + 'custom-rect', + { + inherit: 'rect', + width: 86, + height: 26, + zIndex: 10, + data: { + dataId: '', + finishDate: '', + inspectName: '' + }, + attrs: { + body: { + strokeWidth: 1, + stroke: 'none', + fill: 'none', + }, + text: { + // fontFamily: '浠垮畫', + fontSize: 20, + fill: '#000', + }, + label: { + refX: 0, + refY: 0.5, + textAnchor: 'start', + textVerticalAnchor: 'middle', + textWrap: { + text: '鏂囧瓧妯℃澘', + width: 120, // 瀹藉害鍑忓皯 10px + ellipsis: false, // 鏂囨湰瓒呭嚭鏄剧ず鑼冨洿鏃讹紝鑷姩娣诲姞鐪佺暐鍙� + breakWord: true, // 鏄惁鎴柇鍗曡瘝 + } + }, + }, + ports: {...this.ports}, + }, + true, + ) +// zoom + this.graph.bindKey(['ctrl+1', 'meta+1'], () => { + const zoom = this.graph.zoom() + if (zoom < 1.5) { + this.graph.zoom(0.1) + } + }) + + this.graph.bindKey(['ctrl+2', 'meta+2'], () => { + const zoom = this.graph.zoom() + if (zoom > 0.5) { + this.graph.zoom(-0.1) + } + }) + + this.graph.on('blank:click', ({cell}) => { + this.type = 'grid' + }) + this.graph.on('cell:click', ({cell}) => { + this.type = cell.isNode() ? 'node' : 'edge' + this.shape = cell.shape + this.id = cell.id + }) + // 鍗曞嚮node鑺傜偣 + this.graph.on('node:click', ({node}) => { + // this.reset() + if (node.getData().dataId) { + this.dialogVisible2 = true + let param = { + id: node.getData().dataId, + modelName: node.attr('label/textWrap/modelName'), + } + this.title=node.attr('label/textWrap/modelName') + "妯″瀷璁捐" + this.$nextTick(() => { + this.$refs.modelView.init(param) + }) + } + }) + + this.graph.on('node:customevent', ({name, view, e}) => { + if (name === 'node:delete') { + e.stopPropagation() + view.cell.remove() + } + }) + + // 榧犳爣绉诲叆edge鑺傜偣 + this.graph.on('edge:mouseenter', ({edge,e}) => { + const style = this.knob.style + // e.stopPropagation() + // console.log('edge:mouseenter') + if (e && edge.data) { + if (edge.getData().status==='F') { + //console.log(edge.getData(),"eee edge.getData()") + let startTimes = edge.getData().startTimes + let endTimes = edge.getData().endTimes + //console.log(e,'eee') + const p = this.graph.clientToGraph(e.clientX, e.clientY) + setTimeout(()=>{ + style.display = 'block' + style.left = `${p.x}px` + style.top = `${p.y}px` + style.width = 200+ 'px' + style.height = 80 + 'px' + style.textAlign = 'center' + style.background = '#000' + style.color = '#fff' + style.lineHeight = (40 + 'px') + style.zIndex = 100 + this.knob.innerText = `寮�濮嬫椂闂达細${startTimes}\n缁撴潫鏃堕棿锛�${endTimes}` + },0) + // console.log(p,'p p p') + // console.log(style,this.knob,'style style') + } + } + }) +// 榧犳爣绉诲嚭edge鑺傜偣 + this.graph.on('edge:mouseleave', ({edge}) => { + // console.log('edge:mouseleave') + const style = this.knob.style + style.display = 'none' + }) + }, async getProductList() { let res = await this.$http.get('/basicInfo/XhProductModel/getTaskProductList') this.productList = res.data + this.onProductSelected(this.productList[0]) }, async getTaskList() { let params = { @@ -85,24 +378,13 @@ }, async getSimulatList() { let params = { - productId: this.dataForm.productId, taskModelId: this.dataForm.taskModelId } let res = await this.$http.get('/taskReliability/SimulatAssess/getSimulatList', {params: params}) console.log(res.data) this.simulatList = res.data }, - async onTreeSelected(data) { - this.dataForm.productId = data.id - console.log(this.dataForm.productId) - let params = { - productId: this.dataForm.productId, - taskId: this.dataForm.taskModelId, - fzId: '1722218139013042135' - } - let res = await this.$http.get('/taskReliability/SimulatAssess/getStatus', {params: params}) - console.log(res.data) - }, + // 鑾峰彇淇℃伅 onProductSelected(data) { this.isSelect = true @@ -110,6 +392,10 @@ this.dataForm.productId = data.id this.getTaskList() this.dataForm.taskModelId = '' + this.$nextTick(() => { + this.$refs.ProductModelTree.getProductList() + }) + // this.init() }, onTaskSelected(data) { console.log(data, ' onProductSelected(data)') @@ -117,14 +403,104 @@ this.getSimulatList() this.dataForm.id = '' }, - onSimulatSelected(data) { + async onSimulatSelected(data) { this.dataForm.id = data.id this.dataForm.samplPeriod = data.samplPeriod - this.$refs.SimulatCurve.initEcharts(this.dataForm); + let param = { + id: this.dataForm.id, + taskModelId: this.dataForm.taskModelId + } + let result = await this.$http.get('/taskReliability/SimulatAssess/getSimulatParams', {params: param}) + this.dataForm.samplPeriod = result.data.samplPeriod + this.dataForm.simulatFrequency = result.data.simulatFrequency + }, + async onTreeSelected(data) { + await this.getDiagram(data.id) + }, + async getDiagram(productId) { + this.graph.unfreeze() + let params = { + productId: productId ? productId : this.dataForm.productId, + taskId: this.dataForm.taskModelId, + fzId: this.dataForm.id, + smallWidth: 1200, + minPointNum: 5 + } + let res = await this.$http.get('/taskReliability/SimulatAssess/getStatus', {params: params}) + if (res.data !== null) { + this.diagramJson = JSON.parse(res.data.diagramJson) + let textDiagramJson = JSON.parse(res.data.textDiagramJson) + let smallDiagramJson = JSON.parse(res.data.smallDiagramJson) + this.graph.fromJSON(this.diagramJson) + this.graph.positionContent('left',{ padding: { left: 0 }}) + this.bigWidth = this.graph.getContentBBox().width + // this.graph.resize(this.graph.getContentBBox().width,this.graph.getContentBBox().height) + this.graph.freeze() + this.$refs.textDiagram.getTextDiagram(textDiagramJson) + this.$refs.timeDiagramThumbnail.getThumbnail(smallDiagramJson) + } else { + this.graph.fromJSON(this.emptyJson) + this.graph.positionContent('left',{ padding: { left: 0 }}) + // this.graph.centerContent() + //this.graph.zoomToFit() + this.graph.freeze() + } + console.log(res.data) + }, + getPoint(x,smallWidth){ + let pointX = Number((x * (this.bigWidth / smallWidth )).toFixed(0)) + this.graph.setScrollbarPosition(pointX, null) + }, + async download(selsect) { + if(this.dataForm.id){ + let param = qs.stringify({ + 'token': Cookies.get('token'), + type: 'sxt', + xml:selsect, + id: this.dataForm.id + }) + let apiURL = `/taskReliability/SimulatAssess/downloadXml` + window.location.href = `${window.SITE_CONFIG['apiURL']}${apiURL}?${param}` + }else{ + this.$alert('杩樻湭閫夋嫨浠跨湡璁板綍') + } }, } } </script> <style> + #timeDiagram { + display: flex; + /*border: 1px solid #dfe3e8;*/ + /*width: 60% !important;*/ + } + #timeDiagram .x6-cell.x6-node { + cursor: inherit; + } + + #flexLayout .x6-graph-scroller.x6-graph-scroller-pannable { + width: 92% !important; + } + .x6-widget-stencil { + position: relative; + height: 100%; + } + + .x6-widget-stencil-content { + position: relative; + height: 100%; + } + .my-scroller-drag { + overflow: auto; /* 闇�瑕佹粴鍔ㄦ椂淇濇寔杩欎釜灞炴�� */ + scrollbar-width: none; /* 瀵逛簬Firefox */ + } + + .my-scroller-drag::-webkit-scrollbar { + display: none; /* 瀵逛簬Chrome, Safari鍜孫pera */ + } + .zt.light .el-tab-pane .mod-taskReliability-simulatAssess .el-form{ + margin-top: 5px; + margin-bottom: 0; +} </style> -- Gitblit v1.9.1