123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667 |
- <template>
- <div>
- <div class="bigBox">
- <div ref="container" class="container" v-loading="loading"></div>
- </div>
- <!-- 功能模态框 -->
- <AbilityModal v-if="abModal" :fun="fun" :funOne="funOne" :listMap="listMap" :abModal="abModal"
- :modelId="modelId" :iedType="iedType" :nodeid="nodeid" @abilityBack="abilityBack">
- </AbilityModal>
- <LineDouble v-if="ldModal" :ldModal="ldModal" :modelId="modelId" :startTarget="startTarget"
- :endTarget="endTarget" :numCase="numCase" :startText="startText" :endText="endText" :lineType="lineType"
- @lineBack="lineBack">
- </LineDouble>
- <GroupModelAdd v-if="groupType" :groupType="groupType" :modelId="modelId" @groupBack="groupBack"></GroupModelAdd>
- </div>
- </template>
- <script>
- import { ref, onMounted, watch, onBeforeUnmount } from 'vue';
- import LogicFlow from "@logicflow/core";
- import { PolylineEdge, PolylineEdgeModel } from "@logicflow/core";
- import cid from '@/api/cid/cid'
- import { ElMessage } from 'element-plus';
- import { useRouter, useRoute } from 'vue-router';
- import AbilityModal from "../drawModal/AbilityModal.vue"
- import LineDouble from '../drawModal/LineDouble.vue';
- import GroupModelAdd from '../drawModal/GroupModelAdd.vue';
- import {
- DndPanel,
- SelectionSelect,
- Group,
- Menu,
- MiniMap,
- regeister,
- Snapshot,
- lfJson2Xml,
- lfXml2Json,
- RectResize,
- NodeResize,
- GroupNode,
- groupModel,
- } from "@logicflow/extension";
- import "@logicflow/core/dist/style/index.css";
- import "@logicflow/extension/lib/style/index.css";
- export default {
- props: {
- lineMenuColor: {
- type: String,
- required: true
- },
- fatX: {
- type: Number,
- required: true
- },
- fatY: {
- type: Number,
- required: true
- },
- nowLook: {
- type: null || Number,
- required: true
- },
- needObj: {
- type: Object,
- required: true
- },
- needId: {
- type: Number || String,
- required: true
- },
- needName: {
- type: String,
- required: true
- },
- coolObj: {
- type: Object,
- required: true
- },
- // 用于判断是sv还是goose
- svOrGoose: {
- type: Number,
- required: true,
- },
- searchModule: {
- type: Function,
- required: true
- },//父组件insideModule的方法
- cleanAll: {
- type: Function,
- required: true
- },//父组件insideModule的方法
- },
- setup(props, { emit }) {
- let router = useRouter()
- let route = useRoute()
- const container = ref();
- const lf = ref();
- let lineColor = ref('#255CE7')
- let copyColor = ref('')
- let delId = ref('')
- let nodeId = ref('')
- let copyId = ref('')
- let setX = ref(0)
- let setY = ref(0)
- let needMap = ref([])
- let coolId = ref('')
- let coolName = ref('')
- let copyObj = ref({})//整个模型属性
- let modelId = ref("")//模型id
- let abModal = ref(false)//功能模态框
- let iedType = ref("")//iedtype
- let ldModal = ref(false)//linemodel.vue开关
- let startTarget = ref({})//开始节点
- let endTarget = ref({})//结束节点
- let numCase = ref(1)//判断sv还是goose
- let startText = ref("")//开始节点名称
- let endText = ref("")//结束节点名称
- let lineType = ref("")//连接线
- let loading = ref(false)
- let nodeid = ref("")//节点的id
- let fun = ref()//储存父节点传来的函数
- let funOne = ref()//储存父节点传来的函数
- let groupType = ref(false)//GroupModelAdd.vue组件显示与否
- watch(() => props.lineMenuColor, (newVal) => {
- copyColor.value = newVal
- })
- watch(() => props.fatX, (newVal) => {
- if (newVal == 0 || newVal == '') {
- setX.value = 0
- } else {
- setX.value = newVal
- }
- })
- watch(() => props.fatY, (newVal) => {
- if (newVal == 0 || newVal == '') {
- setY.value = 0
- } else {
- setY.value = newVal
- }
- })
- // watch(() => props.needObj, (newVal) => {
- // coolObj.value = newVal
- // })
- watch(() => props.needId, (newVal) => {
- coolId.value = newVal
- })
- watch(() => props.needName, (newVal) => {
- coolName.value = newVal
- })
- watch(() => props.coolObj, (newVal) => {
- if (route.query.modelid != '' && route.query.modelid != null && route.query.modelid != undefined) {
- console.log('路由跳转watch');
- return
- } else {
- console.log('普通watch');
- loading.value = true//打开加载动画
- copyObj.value = newVal
- modelId.value = copyObj.value.id//模型id
- setTimeout(() => {
- cid.getModelInfo({ id: copyObj.value.id, pageno: 1, pagesize: 20 }).then(res => {
- if (res.data[0].relation_json == null || res.data[0].relation_json == '') return;
- const origiondata = JSON.parse(res.data[0].relation_json)
- lf.value.render(origiondata);//渲染模型图
- loading.value = false//关闭加载动画
- for (let index = 0; index < origiondata.edges.length; index++) {
- const element = origiondata.edges[index];
- if (element.properties != null && element.properties["issv"] === 'SV') {
- let lineStyle = lf.value.getEdgeModelById(element.id)//.getEdgeStyle();
- // console.log(lineStyle)
- lineStyle.setProperties({ svEdge: { stroke: 'orange' } })
- }
- }
- })
- }, 2000);
- }
- }, {
- deep: true
- })
- watch(() => props.svOrGoose, (newVal) => {
- numCase.value = newVal
- })
- function blue() {
- lf.value.setTheme({
- baseEdge: {
- stroke: '#255CE7',
- strokeWidth: 2,
- },
- });//设置连接线为蓝色
- }
- function orange() {
- lf.value.setTheme({
- svEdge: {
- stroke: 'orange',
- strokeWidth: 2,
- },
- });//设置连接线为橙色
- }
- function delLine() {
- if (delId.value) {
- lf.value.deleteEdge(delId.value)//删除选择的连接线
- }
- if (nodeId.value) {
- lf.value.deleteNode(nodeId.value)//删除节点
- }
- }
- function saveLine() {
- // lf.value.getSnapshot()//保存为图片
- console.log(JSON.stringify(lf.value.getGraphData()))
- const xml = lfJson2Xml(lf.value.getGraphData());
- const data = JSON.stringify(lf.value.getGraphData())
- if (modelId.value != undefined && modelId.value != null && modelId.value != '') {
- cid.saveMap(
- {
- id: modelId.value - 0,
- relation_json: data,
- }
- ).then(res => {
- if (res.code == 0) {
- ElMessage({
- type: "success",
- message: "保存成功!",
- duration: 2000,
- })
- } else {
- ElMessage({
- message: res.msg,
- type: "error"
- })
- }
- })
- } else {
- cid.saveMap(
- {
- id: copyObj.value.id - 0,
- relation_json: data,
- }
- ).then(res => {
- if (res.code == 0) {
- ElMessage({
- type: "success",
- message: "保存成功!",
- duration: 2000,
- })
- } else {
- ElMessage({
- message: res.msg,
- type: "error"
- })
- }
- })
- }
- }
- function cleanMap() {
- lf.value.clearData()
- }
- function textColor() {
- if (lineColor.value == "#255CE7") {
- lf.value.setTheme({
- svEdge: {
- stroke: "orange",
- strokeWidth: 2,
- },
- });
- lineColor.value = 'orange'
- } else {
- lf.value.setTheme({
- baseEdge: {
- stroke: "#255CE7",
- strokeWidth: 2,
- },
- });
- lineColor.value = '#255CE7'
- }
- }
- function momal() {
- lf.value.graphModel.moveNode2Coordinate(copyId.value, setX.value - 0, setY.value - 0, true);
- }
- function lastRender() {
- loading.value = true
- modelId.value = route.query.modelid
- cid.getModelInfo({ id: modelId.value - 0, pageno: 1, pagesize: 20 }).then(res => {
- if (res.data[0].relation_json == null || res.data[0].relation_json == '') return;
- const origiondata = JSON.parse(res.data[0].relation_json)
- lf.value.render(origiondata);
- loading.value = false
- for (let index = 0; index < origiondata.edges.length; index++) {
- const element = origiondata.edges[index];
- if (element.properties != null && element.properties["issv"] === 'SV') {
- let lineStyle = lf.value.getEdgeModelById(element.id)
- lineStyle.setProperties({ svEdge: { stroke: 'orange' } })
- }
- }
- }, { immediate: true })
- }
- function listMap() {
- fun.value = props.searchModule
- funOne.value = props.cleanAll
- coolId.value = props.needId
- coolName.value = props.needName//模型名称
- copyObj.value = props.coolObj//需要的模型信息对象
- numCase.value = props.svOrGoose//判断sv或者goose类型
- copyColor.value = props.lineMenuColor//颜色
- setTimeout(() => {
- console.log('定时器执行');
- cid.getModelInfo({ id: copyObj.value.id ? copyObj.value.id : route.query.modelid - 0, pageno: 1, pagesize: 20 }).then(res => {
- emit("drawCor", res.data)
- const filteredArray = res.data[0].ied_type.filter(param => param !== null)
- let groups = {
- type: "my-group",
- label: "分组",
- id: "952",
- resizable: true,//手动调整大小
- foldable: true,//展开收起
- children: [],
- width: 5,
- height: 5,
- isShowAnchor: true,//锚点
- }
- needMap.value = filteredArray.map(item => {
- return {
- type: 'rect',
- text: item.name,
- label: item.name,
- icon: '',
- id: item.id,
- properties: {
- ied_type: item.code,
- id: item.id
- },
- }
- })
- needMap.value.push(groups)
- lf.value = new LogicFlow({
- // 通过选项指定了渲染的容器和需要显示网格
- container: container.value,//需要显示画布的容器ref
- // grid: {
- // size: 10,
- // visible: false,
- // type: "mesh",
- // config: {
- // color: "#ababab",
- // thickness: 1,
- // },
- // },//网格,
- grid: true,
- plugins: [DndPanel, SelectionSelect, Group,GroupNode, Menu, MiniMap, Snapshot, RectResize, NodeResize],//全局加载的组件
- keyboard: {
- enabled: true
- },
- snapline: true,//辅助线
- edgeTextDraggable: true,//连接线文本可以拖拽
- })
- class SvEdge extends PolylineEdge { }
- // 节点Model
- class SvEdgeModel extends PolylineEdgeModel {
- getEdgeStyle() {
- const stl = super.getEdgeStyle()
- stl.stroke = 'orange'
- return stl
- }
- }
- class GooseEdge extends PolylineEdge { }
- // 节点Model
- class GooseEdgeModel extends PolylineEdgeModel {
- getEdgeStyle() {
- const stl = super.getEdgeStyle()
- stl.stroke = '#255CE7'
- return stl
- }
- }
- class MyGroup extends GroupNode.view {
- }
- class MyGroupModel extends GroupNode.model {
- initNodeData(data) {
- data.text= ""//{"value":"未命名组","x":10,"y":5,"editable":true}
- data.id=new Date().getTime();
- super.initNodeData(data);
- //this.isRestrict = true;
- this.resizable = true;
- this.foldable = true;
- this.width = 200;
- this.height = 150;
- this.foldedWidth = 100;
- this.foldedHeight = 100;
- this.isShowAnchor = true;
-
- }
- getNodeStyle() {
- const stl = super.getNodeStyle()
- stl.strokeDasharray= '4 4'
- return stl
- }
- getAnchorStyle(anchorInfo) {
- const style = super.getAnchorStyle(anchorInfo);
- style.stroke = "rgb(24, 125, 255)";
- style.r = 5;
- style.hover.r = 8;
- style.hover.fill = "rgb(24, 125, 255)";
- style.hover.stroke = "rgb(24, 125, 255)";
- return style;
- }
- getTextStyle() {
- const style = super.getTextStyle();
- style.fontSize = 12;
- style.color="#666"
- return style;
- }
- }
- lf.value.register({
- type: "svEdge",
- view: SvEdge,
- model: SvEdgeModel,
- })
- lf.value.register({
- type: "baseEdge",
- view: GooseEdge,
- model: GooseEdgeModel,
- })
- lf.value.register({
- type: "my-group",
- model: MyGroupModel,
- view: MyGroup,
- });
- lf.value.setTheme({//设置画布
- rect: {
- fill: "#FFFFFF",
- stroke: "#255CE7",
- strokeWidth: 2,
- },//放置的元素
- snapline: {
- stroke: 'black', // 对齐线颜色
- strokeWidth: 1, // 对齐线宽度
- },
- edgeText: {
- textWidth: 100,
- overflowMode: "default",
- fontSize: 18,
- background: {
- fill: "#FFFFFF",
- },
- },//连接线w文字样式
- outline: {
- fill: "transparent",
- stroke: "#949494",
- strokeDasharray: "3,3",
- hover: {
- stroke: "#949494",
- },
- },
- anchor: {
- stroke: "#000000",
- fill: "#FFFFFF",
- r: 4,
- hover: {
- fill: "#949494",
- fillOpacity: 0.5,
- stroke: "#949494",
- r: 10,
- },
- },//锚点样式
- baseEdge: {
- stroke: "#255CE7",
- strokeWidth: 2,
- },//连接线颜色
- svEdge: {
- stroke: "orange",
- strokeWidth: 1,
- },//连接线颜色
- nodeText: {
- color: "#255CE7",
- overflowMode: "autoWrap",
- lineHeight: 1.2,
- fontSize: 12,
- },//节点内文字样式
- });
- lf.value.on("edge:click", function (data, e, position) {
- delId.value = data.data.id
- // if (copyColor.value == '#255CE7') {
- // lf.value.graphModel.updateText(data.data.id, "GOOSE");
- // } else if (copyColor.value == 'orange') {
- // lf.value.graphModel.updateText(data.data.id, "SV");
- // }
- })
- lf.value.on("edge:add", function (data, e, position) {
- if (copyColor.value == '#255CE7') {
- blue()
- lf.value.changeEdgeType(data.data.id, "baseEdge")
- lf.value.setProperties(data.data.id, { 'issv': 'GOOSE' })
- }
- if (copyColor.value == 'orange') {
- orange()
- lf.value.changeEdgeType(data.data.id, "svEdge")
- lf.value.setProperties(data.data.id, { 'issv': 'SV' })
- }
- })
- lf.value.on('node:click', function (data, e, position) {//传送坐标轴参数到父组件
- copyId.value = data.data.id
- nodeId.value = data.data.id
- setX.value = data.data.x
- setY.value = data.data.y
- emit("backxy", setX.value, setY.value)
- })
- // lf.value.on('anchor:drop', function (data, e, position) {//添加线上文字
- // if (numCase.value == 0) {
- // lf.value.graphModel.updateText(data.edgeModel.id, "SV");
- // } else if (numCase.value == 1) {
- // lf.value.graphModel.updateText(data.edgeModel.id, "GOOSE");
- // }
- // })
- lf.value.on('node:dbclick', function (data, e, position) {//双击打开弹窗
- console.log(data, 'datas');
- iedType.value = data.data.properties.ied_type
- nodeid.value = data.data.properties.id
- abModal.value = true
- })
- lf.value.on('edge:dbclick', function (data, e, position) {//双击连接线
- lineType.value = data.data.properties.issv
- let start = lf.value.getNodeModelById(data.data.sourceNodeId)//获取连线开始节点
- let end = lf.value.getNodeModelById(data.data.targetNodeId)//获取连线结尾节点
- startText.value = start.text.value//开始文本
- endText.value = end.text.value//结束文本
- startTarget.value = start.properties
- endTarget.value = end.properties
- console.log(copyColor.value, 'copy');
- console.log(data, 'data');
- // if (copyColor.value == '#255CE7') {
- // lf.value.graphModel.updateText(data.data.id, "GOOSE");
- // } else if (copyColor.value == 'orange') {
- // lf.value.graphModel.updateText(data.data.id, "SV");
- // }
- ldModal.value = true
- })
- lf.value.on('node:mousemove', function (data, e) {//传递坐标轴参数到父组件
- setX.value = data.data.x
- setY.value = data.data.y
- console.log(data.data, 'move');
- emit("backxy", setX.value, setY.value)
- })
- // console.log(lf.value.graphModel,'sss');
- lf.value.on('edge:click', function (data, e, position) {//解决点击连接线问题
- console.log(data, 'data2');
- if (copyColor.value == '#255CE7') {
- blue()
- lf.value.changeEdgeType(data.data.id, "baseEdge")
- lf.value.setProperties(data.data.id, { 'issv': 'GOOSE' })
- }
- if (copyColor.value == 'orange') {
- orange()
- lf.value.changeEdgeType(data.data.id, "svEdge")
- lf.value.setProperties(data.data.id, { 'issv': 'SV' })
- }
- })
- //当将节点托入画布后触发事件
- lf.value.on('node:dnd-add',function (nodedata){
- console.log(nodedata,'node');
- if(nodedata.data.type=='my-group'){
- let nodeid=nodedata.data.id
- // 添加的是分组节点,需要打开一个窗口让用户设置该节点的ied_type并保存到properties中
- let ied_type="user set iedtype"
- lf.value.getNodeModelById(nodeid).setProperties({
- ied_type: ied_type,
- id:-99 //分组的装置类型id固定为0
- });
- groupType.value = true
- }
- })
- // lf.value.register(logicFlows)
- lf.value.extension.dndPanel.setPatternItems(needMap.value);
- lf.value.render();
- console.log('执行了渲染');
- if (route.query.modelid != '' && route.query.modelid != null && route.query.modelid != undefined) {
- lastRender()
- }
- setTimeout(() => {
- loading.value = false
- }, 1000)
- })
- }, 1000);
- }
- onMounted(() => {
- listMap()
- })
- function abilityBack(data) {
- abModal.value = data
- }
- function lineBack(data) {
- ldModal.value = data
- }
- // GroupModelAdd.vue返回状态
- function groupBack(data){
- groupType.value = data
- }
- onBeforeUnmount(() => {
- // lf.value.remove()
- // coolObj.value = {}
- router.push("/home/setting")
- })
- return {
- container,
- lf,
- textColor,
- lineColor,
- blue,
- orange,
- delLine,
- saveLine,
- cleanMap,
- nodeId,
- copyColor,
- copyId,
- setX,
- setY,
- momal,
- needMap,
- coolId,
- coolName,
- copyObj,//模型整个数据
- modelId,//模型id
- abModal,//功能模态框
- iedType,//模型属性
- abilityBack,//abilitymodal.vue返回模态框开关状态
- ldModal,//lineDouble.vue模态框开关
- startTarget,//开始节点
- endTarget,//结束节点
- lineBack,//LineDouble.vue返回模态框开关状态
- numCase,//判断是sv还是goose,0为sv,1为goose
- startText,//开始节点名称
- endText,//结束节点名称
- lineType,//连接线
- lastRender,//路由跳转的渲染
- loading,
- nodeid,//节点的id
- fun,//储存父节点传来的函数
- listMap,//组件初始化
- funOne,//储存父节点传来的函数
- groupType,//GroupModelAdd.vue组件显示与否
- groupBack,// GroupModelAdd.vue返回状态
- }
- },
- components: {
- AbilityModal,//功能模态框
- LineDouble,//连接线模态框
- GroupModelAdd,//分组专属模态框
- }
- }
- </script>
- <style scoped>
- .container {
- width: 100%;
- height: calc(100vh - 18rem);
- /* overflow: auto; */
- }
- :deep(.lf-element-text) {
- color: black;
- }
- /* :deep(.lf-dndpanel){
- w
- } */
- /* :deep(.lf-basic-shape) {
- width: 150px;
- height: 150px;
- } */
- </style>
|