提交前端
This commit is contained in:
parent
45f5a28775
commit
f38acfc857
@ -9,6 +9,13 @@ export function searchProjectsLsit(queryParams:any){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function projectsById(queryParams:any){
|
||||||
|
return request({
|
||||||
|
url: '/projects/'+ queryParams.projectId ,
|
||||||
|
method: 'get'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -57,3 +57,12 @@ export function getActiveAlgorithms(){
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取所有项目列表
|
||||||
|
export function getByScenario(queryParams:any){
|
||||||
|
return request({
|
||||||
|
url: '/scenario-results/by-scenario' ,
|
||||||
|
method: 'get',
|
||||||
|
params: queryParams
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
import { useRoute,useRouter } from 'vue-router';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Clipboard,
|
Clipboard,
|
||||||
Graph,
|
Graph,
|
||||||
@ -10,34 +12,24 @@ import {
|
|||||||
Selection,
|
Selection,
|
||||||
Shape,
|
Shape,
|
||||||
Snapline,
|
Snapline,
|
||||||
Stencil,
|
|
||||||
Transform
|
Transform
|
||||||
} from '@antv/x6'
|
} from '@antv/x6'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import insertCss from 'insert-css'
|
import { updateProjects,projectsById} from "@/api/business/project";
|
||||||
import { updateProjects} from "@/api/business/project";
|
|
||||||
|
import { getByScenario } from "@/api/business/scenario";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import Createscenario from '@/views/component/scenario/createscenario.vue'
|
import Createscenario from '@/views/component/scenario/createscenario.vue'
|
||||||
import ScenarioModel from '@/views/component/scenario/index.vue'
|
import ScenarioModel from '@/views/component/scenario/index.vue'
|
||||||
import img1 from '@/assets/x6/1.png'
|
|
||||||
import img2 from '@/assets/x6/2.png'
|
|
||||||
import img3 from '@/assets/x6/3.png'
|
|
||||||
import img4 from '@/assets/x6/4.png'
|
|
||||||
import img5 from '@/assets/x6/5.png'
|
|
||||||
import img6 from '@/assets/x6/6.png'
|
|
||||||
import img7 from '@/assets/x6/7.png'
|
|
||||||
|
|
||||||
import line1 from '@/assets/x6/line1.png'
|
|
||||||
import line2 from '@/assets/x6/line2.png'
|
|
||||||
import line3 from '@/assets/x6/line3.png'
|
|
||||||
import line4 from '@/assets/x6/line4.png'
|
|
||||||
import line5 from '@/assets/x6/line5.png'
|
|
||||||
import line6 from '@/assets/x6/line6.png'
|
|
||||||
import AdddeviceModel from './adddevice.vue';
|
import AdddeviceModel from './adddevice.vue';
|
||||||
import EditdeviceModel from './editdevice.vue';
|
import EditdeviceModel from './editdevice.vue';
|
||||||
import MaterialModels from './materialmodel.vue';
|
import MaterialModels from './materialmodel.vue';
|
||||||
import ChangesettingsModels from './changesettings.vue';
|
import ChangesettingsModels from './changesettings.vue';
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter()
|
||||||
const emit = defineEmits([ 'closeAntvx6']);
|
const emit = defineEmits([ 'closeAntvx6']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
projectInfo: {
|
projectInfo: {
|
||||||
@ -50,52 +42,26 @@ const deviceTypetype:any = ref('') // 设备类型
|
|||||||
const isAdddevice = ref(false) // 是否添加设备
|
const isAdddevice = ref(false) // 是否添加设备
|
||||||
const isEditdevice = ref(false) // 是否编辑设备
|
const isEditdevice = ref(false) // 是否编辑设备
|
||||||
const isMaterialModel = ref(false) // 是否物料信息
|
const isMaterialModel = ref(false) // 是否物料信息
|
||||||
const projectInfo:any = ref(props.projectInfo) // 项目信息
|
const projectInfo:any = ref({}) // 项目信息
|
||||||
const isScenario = ref(false) //是否展示历史模拟场景
|
const isScenario = ref(false) //是否展示历史模拟场景
|
||||||
const isDisplay = ref(true) // 是否显示
|
const isDisplay = ref(true) // 是否显示
|
||||||
const isExpansionandcontraction = ref(false) // 是否显示展开收起按钮
|
const isExpansionandcontraction = ref(false) // 是否显示展开收起按钮
|
||||||
// 为了协助代码演示
|
// 为了协助代码演示
|
||||||
let graph: Graph
|
let graph: Graph
|
||||||
let currentArrowStyle = 'single' // 默认单箭头
|
const scenarioId:any = ref('') // 场景id
|
||||||
let currentLineStyle = 'solid' // 默认实线
|
function getScenarioResults(){
|
||||||
|
getByScenario({
|
||||||
// 设置箭头样式
|
scenarioId: scenarioId.value,
|
||||||
// function setArrowStyle(style: 'single' | 'double' | 'none', lineStyle: 'solid' | 'dashed' = 'solid') {
|
pageNum:1,
|
||||||
// currentArrowStyle = style
|
pageSize:999
|
||||||
// currentLineStyle = lineStyle
|
}).then((res:any) => {
|
||||||
// // 重新配置连接线
|
console.log(res.data.records)
|
||||||
// graph.options.connecting.createEdge = () => {
|
|
||||||
// const edge = new Shape.Edge({
|
|
||||||
// attrs: {
|
|
||||||
// line: {
|
|
||||||
// stroke: '#A2B1C3',
|
|
||||||
// strokeWidth: 2,
|
|
||||||
// strokeDasharray: lineStyle === 'dashed' ? 5 : 0,
|
|
||||||
// targetMarker: style === 'none' ? null : {
|
|
||||||
// name: 'block',
|
|
||||||
// width: 12,
|
|
||||||
// height: 8,
|
|
||||||
// },
|
|
||||||
// sourceMarker: style === 'double' ? {
|
|
||||||
// name: 'block',
|
|
||||||
// width: 12,
|
|
||||||
// height: 8,
|
|
||||||
// } : null,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// zIndex: 0,
|
|
||||||
// })
|
|
||||||
// return edge
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
res.data.records
|
||||||
|
})
|
||||||
|
}
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
preWork()
|
scenarioId.value = route.query.scenarioId
|
||||||
if(projectInfo.value.topology != null && projectInfo.value.topology != ''){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #region 初始化画布
|
// #region 初始化画布
|
||||||
graph = new Graph({
|
graph = new Graph({
|
||||||
container: document.getElementById('graph-container') as HTMLElement,
|
container: document.getElementById('graph-container') as HTMLElement,
|
||||||
@ -155,13 +121,8 @@ onMounted(() => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
interacting: function (cellView) {
|
interacting: function (cellView) {
|
||||||
// 获取当前节点的模型
|
|
||||||
const cell = cellView.cell
|
|
||||||
// 判断节点是否为 'rect' 形状
|
|
||||||
if (cell.shape === 'rect') {
|
|
||||||
// 如果是 'rect' 形状,则禁止节点移动
|
// 如果是 'rect' 形状,则禁止节点移动
|
||||||
return { nodeMovable: false }
|
return { nodeMovable: false }
|
||||||
}
|
|
||||||
// 其他形状的节点允许所有交互
|
// 其他形状的节点允许所有交互
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -169,314 +130,6 @@ onMounted(() => {
|
|||||||
// nodeMovable: false, // 禁止所有节点移动
|
// nodeMovable: false, // 禁止所有节点移动
|
||||||
// },
|
// },
|
||||||
})
|
})
|
||||||
// #endregion
|
|
||||||
|
|
||||||
// #region 使用插件
|
|
||||||
graph
|
|
||||||
.use(
|
|
||||||
new Transform({
|
|
||||||
resizing: false, // 通过拖拽边缘调整节点大小
|
|
||||||
rotating: false, // 允许旋转节点
|
|
||||||
// scaling 不是 Transform 插件的有效配置项,已移除
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.use(
|
|
||||||
new Selection({
|
|
||||||
rubberband: true,
|
|
||||||
showNodeSelectionBox: true,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.use(new Snapline())
|
|
||||||
.use(new Keyboard())
|
|
||||||
.use(new Clipboard())
|
|
||||||
.use(new History())
|
|
||||||
// #endregion
|
|
||||||
|
|
||||||
// #region 初始化 stencil
|
|
||||||
const stencil = new Stencil({
|
|
||||||
title: '',
|
|
||||||
target: graph,
|
|
||||||
stencilGraphWidth: 300,
|
|
||||||
stencilGraphHeight: 180,
|
|
||||||
stencilGraphOptions: { panning: false },
|
|
||||||
collapsable: false,
|
|
||||||
groups: [
|
|
||||||
// {
|
|
||||||
// title: '基础流程图',
|
|
||||||
// name: 'group1',
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
collapsable: false,
|
|
||||||
title: '设备',
|
|
||||||
name: 'group2',
|
|
||||||
graphHeight: 550,
|
|
||||||
layoutOptions: {
|
|
||||||
rowHeight: 120,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
collapsable: false,
|
|
||||||
title: '管线',
|
|
||||||
name: 'group3',
|
|
||||||
graphHeight: 400,
|
|
||||||
layoutOptions: {
|
|
||||||
rowHeight: 120,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
layoutOptions: {
|
|
||||||
columns: 2,
|
|
||||||
columnWidth: 140,
|
|
||||||
rowHeight: 100,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
graph.on('node:contextmenu', ({ e, node }) => {
|
|
||||||
selectedNode.value = node
|
|
||||||
e.preventDefault()
|
|
||||||
// 显示自定义上下文菜单,包含箭头样式选项
|
|
||||||
const pos = node.position?.() || { x: 0, y: 0 }
|
|
||||||
showContextMenu(pos.x, pos.y)
|
|
||||||
})
|
|
||||||
function showContextMenu(x: number, y: number) {
|
|
||||||
left.value = x + 260
|
|
||||||
top.value = y - 50
|
|
||||||
|
|
||||||
isMenuShow.value = true
|
|
||||||
// 创建并显示上下文菜单
|
|
||||||
// 包含箭头样式选项
|
|
||||||
}
|
|
||||||
// 监听Stencil内部的Dnd事件
|
|
||||||
stencil.on('dnd:start', (args:any) => {
|
|
||||||
console.log('Stencil节点开始拖拽', args)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
stencil.on('dnd:drag', (args:any) => {
|
|
||||||
console.log('Stencil节点拖拽中', args)
|
|
||||||
})
|
|
||||||
|
|
||||||
stencil.on('dnd:end', (args:any) => {
|
|
||||||
console.log('Stencil节点结束拖拽', args)
|
|
||||||
})
|
|
||||||
document
|
|
||||||
.getElementById('stencil')
|
|
||||||
?.appendChild(stencil.container as HTMLElement)
|
|
||||||
|
|
||||||
// 监听Graph中节点创建事件
|
|
||||||
graph.on('node:added', (args:any) => {
|
|
||||||
console.log('节点已添加到画布', args)
|
|
||||||
const { node } = args
|
|
||||||
|
|
||||||
// 检查是否是管线节点
|
|
||||||
if (node.data && node.data.lineStyle) {
|
|
||||||
// 应用管线样式到连接线
|
|
||||||
const lineStyle = node.data.lineStyle
|
|
||||||
graph.options.connecting.createEdge = () => {
|
|
||||||
return new Shape.Edge({
|
|
||||||
attrs: {
|
|
||||||
line: {
|
|
||||||
stroke: '#A2B1C3',
|
|
||||||
strokeWidth: 2,
|
|
||||||
strokeDasharray: lineStyle.strokeDasharray,
|
|
||||||
targetMarker: lineStyle.targetMarker,
|
|
||||||
sourceMarker: lineStyle.sourceMarker
|
|
||||||
}
|
|
||||||
},
|
|
||||||
zIndex: 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// 移除管线节点,因为它只是一个样式选择器
|
|
||||||
setTimeout(() => {
|
|
||||||
graph.removeNode(node)
|
|
||||||
}, 100)
|
|
||||||
} else {
|
|
||||||
if(node.store && node.store.data && node.store.data.shape === 'rect'){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
nodeId.value = node.id
|
|
||||||
if(node.store.data.attrs.text.text == '扁平槽'){
|
|
||||||
deviceTypetype.value = 'FlatTank'
|
|
||||||
}else if(node.store.data.attrs.text.text == '圆柱槽'){
|
|
||||||
deviceTypetype.value = 'CylindricalTank'
|
|
||||||
}else if(node.store.data.attrs.text.text == '环形槽'){
|
|
||||||
deviceTypetype.value = 'AnnularTank'
|
|
||||||
}else if(node.store.data.attrs.text.text == '管束槽'){
|
|
||||||
deviceTypetype.value = 'TubeBundleTank'
|
|
||||||
}else if(node.store.data.attrs.text.text == '萃取柱'){
|
|
||||||
deviceTypetype.value = 'ExtractionColumn'
|
|
||||||
}else if(node.store.data.attrs.text.text == '流化床'){
|
|
||||||
deviceTypetype.value = 'FluidizedBed'
|
|
||||||
}else if(node.store.data.attrs.text.text == '锥底环形槽'){
|
|
||||||
deviceTypetype.value = 'ACFTank'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 设置固定大小
|
|
||||||
node.size(160, 160)
|
|
||||||
// 去掉背景节点
|
|
||||||
node.attr('body/fill', 'none')
|
|
||||||
// 图片居中
|
|
||||||
node.attr('image/refX', 0)
|
|
||||||
node.attr('image/refY', 0)
|
|
||||||
node.attr('image/width', 160) // 修改宽度
|
|
||||||
node.attr('image/height', 160) // 修改高度
|
|
||||||
// 删除节点上的文字
|
|
||||||
node.attr('text/text', '')
|
|
||||||
node.attr('label/text', '')
|
|
||||||
|
|
||||||
|
|
||||||
isAdddevice.value = true
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
// #endregion
|
|
||||||
|
|
||||||
// #region 快捷键与事件
|
|
||||||
graph.bindKey(['meta+c', 'ctrl+c'], () => {
|
|
||||||
const cells = graph.getSelectedCells()
|
|
||||||
if (cells.length) {
|
|
||||||
graph.copy(cells)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
graph.bindKey(['meta+x', 'ctrl+x'], () => {
|
|
||||||
const cells = graph.getSelectedCells()
|
|
||||||
if (cells.length) {
|
|
||||||
graph.cut(cells)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
graph.bindKey(['meta+v', 'ctrl+v'], () => {
|
|
||||||
if (!graph.isClipboardEmpty()) {
|
|
||||||
const cells = graph.paste({ offset: 32 })
|
|
||||||
graph.cleanSelection()
|
|
||||||
graph.select(cells)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
// undo redo
|
|
||||||
graph.bindKey(['meta+z', 'ctrl+z'], () => {
|
|
||||||
if (graph.canUndo()) {
|
|
||||||
graph.undo()
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
|
|
||||||
if (graph.canRedo()) {
|
|
||||||
graph.redo()
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
// select all
|
|
||||||
graph.bindKey(['meta+a', 'ctrl+a'], () => {
|
|
||||||
const nodes = graph.getNodes()
|
|
||||||
if (nodes) {
|
|
||||||
graph.select(nodes)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// delete
|
|
||||||
graph.bindKey('backspace', () => {
|
|
||||||
const cells = graph.getSelectedCells()
|
|
||||||
if (cells.length) {
|
|
||||||
graph.removeCells(cells)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// zoom
|
|
||||||
graph.bindKey(['ctrl+1', 'meta+1'], () => {
|
|
||||||
const zoom = graph.zoom()
|
|
||||||
if (zoom < 1.5) {
|
|
||||||
graph.zoom(0.1)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
graph.bindKey(['ctrl+2', 'meta+2'], () => {
|
|
||||||
const zoom = graph.zoom()
|
|
||||||
if (zoom > 0.5) {
|
|
||||||
graph.zoom(-0.1)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let startPoint:any = null // 矩形起点
|
|
||||||
|
|
||||||
// 监听鼠标按下事件:记录起点
|
|
||||||
graph.on('blank:mousedown', (e) => {
|
|
||||||
startPoint = { x: e.x, y: e.y }
|
|
||||||
})
|
|
||||||
|
|
||||||
// 监听鼠标松开事件:绘制矩形
|
|
||||||
graph.on('blank:mouseup', (e) => {
|
|
||||||
console.log('鼠标松开事件', e)
|
|
||||||
if (!startPoint) return
|
|
||||||
|
|
||||||
|
|
||||||
const endPoint = { x: e.x, y: e.y }
|
|
||||||
if(Math.abs(endPoint.x - startPoint.x) <20 && Math.abs(endPoint.y - startPoint.y) <20){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const width = Math.abs(endPoint.x - startPoint.x)
|
|
||||||
const height = Math.abs(endPoint.y - startPoint.y)
|
|
||||||
const x = Math.min(startPoint.x, endPoint.x)
|
|
||||||
const y = Math.min(startPoint.y, endPoint.y)
|
|
||||||
|
|
||||||
// 添加矩形节点(设置 zIndex 为 -1 确保在最底层)
|
|
||||||
graph.addNode({
|
|
||||||
shape: 'rect',
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
zIndex: -1, // 关键:置于底层
|
|
||||||
// interactive: false, // 禁用所有交互
|
|
||||||
// selectable: false, // 明确禁止选中
|
|
||||||
draggable: false, // 明确禁止移动
|
|
||||||
interacting: {
|
|
||||||
nodeMovable: false, // 禁止所有节点移动
|
|
||||||
},
|
|
||||||
attrs: {
|
|
||||||
body: {
|
|
||||||
fill: 'transparent',
|
|
||||||
stroke: '#999',
|
|
||||||
strokeWidth: 1,
|
|
||||||
strokeDasharray: '5 5', // 设置虚线样式
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
startPoint = null // 重置起点
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
// 控制连接桩显示/隐藏
|
|
||||||
const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
|
|
||||||
for (let i = 0, len = ports.length; i < len; i += 1) {
|
|
||||||
ports[i].style.visibility = show ? 'visible' : 'hidden'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
graph.on('node:mouseenter', () => {
|
|
||||||
const container = document.getElementById('graph-container') as HTMLElement
|
|
||||||
const ports = container.querySelectorAll(
|
|
||||||
'.x6-port-body',
|
|
||||||
) as NodeListOf<SVGElement>
|
|
||||||
showPorts(ports, true)
|
|
||||||
})
|
|
||||||
graph.on('node:mouseleave', () => {
|
|
||||||
const container = document.getElementById('graph-container') as HTMLElement
|
|
||||||
const ports = container.querySelectorAll(
|
|
||||||
'.x6-port-body',
|
|
||||||
) as NodeListOf<SVGElement>
|
|
||||||
showPorts(ports, false)
|
|
||||||
})
|
|
||||||
// #endregion
|
|
||||||
|
|
||||||
// #region 初始化图形
|
|
||||||
const ports = {
|
const ports = {
|
||||||
groups: {
|
groups: {
|
||||||
top: {
|
top: {
|
||||||
@ -598,235 +251,144 @@ graph.on('blank:mouseup', (e) => {
|
|||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
|
projectsById({projectId:route.query.projectId}).then((res:any) => {
|
||||||
const imageShapes = [
|
if(res.topology != null && res.topology != ''){
|
||||||
{
|
projectInfo.value = res
|
||||||
label: '圆柱槽',
|
|
||||||
image: img1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '扁平槽',
|
|
||||||
image:img2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '环形槽',
|
|
||||||
image:img3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '管束槽',
|
|
||||||
image:img4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '萃取柱',
|
|
||||||
image:img5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '流化床',
|
|
||||||
image:img6,
|
|
||||||
},{
|
|
||||||
label: '锥底环形槽',
|
|
||||||
image:img7,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
const imageNodes = imageShapes.map((item) =>
|
|
||||||
graph.createNode({
|
|
||||||
shape: 'custom-image',
|
|
||||||
label: item.label,
|
|
||||||
attrs: {
|
|
||||||
image: {
|
|
||||||
'xlink:href': item.image,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
stencil.load(imageNodes, 'group2')
|
|
||||||
|
|
||||||
// 创建管线节点
|
|
||||||
const lineShapes = [
|
|
||||||
{
|
|
||||||
label: '实线',
|
|
||||||
image: line1,
|
|
||||||
targetMarker: null,
|
|
||||||
sourceMarker: null,
|
|
||||||
strokeDasharray: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '单箭头实线',
|
|
||||||
image: line2,
|
|
||||||
targetMarker: {
|
|
||||||
name: 'block',
|
|
||||||
width: 12,
|
|
||||||
height: 8
|
|
||||||
},
|
|
||||||
sourceMarker: null,
|
|
||||||
strokeDasharray: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '双箭头实线',
|
|
||||||
image: line3,
|
|
||||||
targetMarker: {
|
|
||||||
name: 'block',
|
|
||||||
width: 12,
|
|
||||||
height: 8
|
|
||||||
},
|
|
||||||
sourceMarker: {
|
|
||||||
name: 'block',
|
|
||||||
width: 12,
|
|
||||||
height: 8
|
|
||||||
},
|
|
||||||
strokeDasharray: 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '虚线',
|
|
||||||
image: line4,
|
|
||||||
targetMarker: null,
|
|
||||||
sourceMarker: null,
|
|
||||||
strokeDasharray: 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '单箭头虚线',
|
|
||||||
image: line5,
|
|
||||||
targetMarker: {
|
|
||||||
name: 'block',
|
|
||||||
width: 12,
|
|
||||||
height: 8
|
|
||||||
},
|
|
||||||
sourceMarker: null,
|
|
||||||
strokeDasharray: 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '双箭头虚线',
|
|
||||||
image: line6,
|
|
||||||
targetMarker: {
|
|
||||||
name: 'block',
|
|
||||||
width: 12,
|
|
||||||
height: 8
|
|
||||||
},
|
|
||||||
sourceMarker: {
|
|
||||||
name: 'block',
|
|
||||||
width: 12,
|
|
||||||
height: 8
|
|
||||||
},
|
|
||||||
strokeDasharray: 5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const lineNodes = lineShapes.map((item) => {
|
|
||||||
// 创建一个节点来显示管线样式
|
|
||||||
const node = graph.createNode({
|
|
||||||
shape: 'custom-image',
|
|
||||||
label: item.label,
|
|
||||||
width: 130,
|
|
||||||
height: 100,
|
|
||||||
attrs: {
|
|
||||||
image: {
|
|
||||||
'xlink:href': item.image,
|
|
||||||
width: 31,
|
|
||||||
height: 31,
|
|
||||||
refX: 50,
|
|
||||||
refY: 20
|
|
||||||
},
|
|
||||||
body: {
|
|
||||||
stroke: 'transparent',
|
|
||||||
fill: '#f8f8f8'
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
text: item.label,
|
|
||||||
refX: 60,
|
|
||||||
refY: 65,
|
|
||||||
textAnchor: 'middle',
|
|
||||||
fontSize: 12,
|
|
||||||
fill: '#666'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
lineStyle: {
|
|
||||||
strokeDasharray: item.strokeDasharray,
|
|
||||||
targetMarker: item.targetMarker,
|
|
||||||
sourceMarker: item.sourceMarker
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return node
|
|
||||||
})
|
|
||||||
|
|
||||||
stencil.load(lineNodes, 'group3')
|
|
||||||
if (!graph || !projectInfo.value || !projectInfo.value.topology) return;
|
if (!graph || !projectInfo.value || !projectInfo.value.topology) return;
|
||||||
graph.clearCells();
|
graph.clearCells();
|
||||||
const topology:any = JSON.parse(projectInfo.value.topology)
|
const topology:any = JSON.parse(projectInfo.value.topology)
|
||||||
if(!topology.designData)return
|
if(!topology.designData)return
|
||||||
|
// 确保每个单元格都有 shape 属性
|
||||||
|
// const validCells = Array.isArray(topology.designData) ? topology.designData.filter(cell => cell.shape) : []
|
||||||
|
// 如果有有效单元格,则加载到图中
|
||||||
graph.fromJSON(topology.designData);
|
graph.fromJSON(topology.designData);
|
||||||
|
getScenarioResults()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region 使用插件
|
||||||
|
// graph
|
||||||
|
// .use(
|
||||||
|
// new Transform({
|
||||||
|
// resizing: false, // 通过拖拽边缘调整节点大小
|
||||||
|
// rotating: false, // 允许旋转节点
|
||||||
|
// // scaling 不是 Transform 插件的有效配置项,已移除
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
// .use(
|
||||||
|
// new Selection({
|
||||||
|
// rubberband: true,
|
||||||
|
// showNodeSelectionBox: true,
|
||||||
|
// }),
|
||||||
|
// )
|
||||||
|
// .use(new Snapline())
|
||||||
|
// .use(new Keyboard())
|
||||||
|
// .use(new Clipboard())
|
||||||
|
// .use(new History())
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
|
||||||
|
graph.on('node:contextmenu', ({ e, node }) => {
|
||||||
|
selectedNode.value = node
|
||||||
|
e.preventDefault()
|
||||||
|
// 显示自定义上下文菜单,包含箭头样式选项
|
||||||
|
const pos = node.position?.() || { x: 0, y: 0 }
|
||||||
|
showContextMenu(pos.x, pos.y)
|
||||||
|
})
|
||||||
|
function showContextMenu(x: number, y: number) {
|
||||||
|
left.value = x + 260
|
||||||
|
top.value = y - 50
|
||||||
|
|
||||||
|
isMenuShow.value = true
|
||||||
|
// 创建并显示上下文菜单
|
||||||
|
// 包含箭头样式选项
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 监听Graph中节点创建事件
|
||||||
|
// graph.on('node:added', (args:any) => {
|
||||||
|
// console.log('节点已添加到画布', args)
|
||||||
|
// const { node } = args
|
||||||
|
|
||||||
|
// // 检查是否是管线节点
|
||||||
|
// if (node.data && node.data.lineStyle) {
|
||||||
|
// // 应用管线样式到连接线
|
||||||
|
// const lineStyle = node.data.lineStyle
|
||||||
|
// graph.options.connecting.createEdge = () => {
|
||||||
|
// return new Shape.Edge({
|
||||||
|
// attrs: {
|
||||||
|
// line: {
|
||||||
|
// stroke: '#A2B1C3',
|
||||||
|
// strokeWidth: 2,
|
||||||
|
// strokeDasharray: lineStyle.strokeDasharray,
|
||||||
|
// targetMarker: lineStyle.targetMarker,
|
||||||
|
// sourceMarker: lineStyle.sourceMarker
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// zIndex: 0
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// // 移除管线节点,因为它只是一个样式选择器
|
||||||
|
// setTimeout(() => {
|
||||||
|
// graph.removeNode(node)
|
||||||
|
// }, 100)
|
||||||
|
// } else {
|
||||||
|
// if(node.store && node.store.data && node.store.data.shape === 'rect'){
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// nodeId.value = node.id
|
||||||
|
// if(node.store.data.attrs.text.text == '扁平槽'){
|
||||||
|
// deviceTypetype.value = 'FlatTank'
|
||||||
|
// }else if(node.store.data.attrs.text.text == '圆柱槽'){
|
||||||
|
// deviceTypetype.value = 'CylindricalTank'
|
||||||
|
// }else if(node.store.data.attrs.text.text == '环形槽'){
|
||||||
|
// deviceTypetype.value = 'AnnularTank'
|
||||||
|
// }else if(node.store.data.attrs.text.text == '管束槽'){
|
||||||
|
// deviceTypetype.value = 'TubeBundleTank'
|
||||||
|
// }else if(node.store.data.attrs.text.text == '萃取柱'){
|
||||||
|
// deviceTypetype.value = 'ExtractionColumn'
|
||||||
|
// }else if(node.store.data.attrs.text.text == '流化床'){
|
||||||
|
// deviceTypetype.value = 'FluidizedBed'
|
||||||
|
// }else if(node.store.data.attrs.text.text == '锥底环形槽'){
|
||||||
|
// deviceTypetype.value = 'ACFTank'
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// // 设置固定大小
|
||||||
|
// node.size(160, 160)
|
||||||
|
// // 去掉背景节点
|
||||||
|
// node.attr('body/fill', 'none')
|
||||||
|
// // 图片居中
|
||||||
|
// node.attr('image/refX', 0)
|
||||||
|
// node.attr('image/refY', 0)
|
||||||
|
// node.attr('image/width', 160) // 修改宽度
|
||||||
|
// node.attr('image/height', 160) // 修改高度
|
||||||
|
// // 删除节点上的文字
|
||||||
|
// node.attr('text/text', '')
|
||||||
|
// node.attr('label/text', '')
|
||||||
|
|
||||||
|
|
||||||
|
// isAdddevice.value = true
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
// })
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
})
|
})
|
||||||
|
|
||||||
function preWork() {
|
|
||||||
// 这里协助演示的代码,在实际项目中根据实际情况进行调整
|
|
||||||
const container = document.getElementById('container') as HTMLElement
|
|
||||||
const stencilContainer = document.createElement('div')
|
|
||||||
stencilContainer.id = 'stencil'
|
|
||||||
const graphContainer = document.createElement('div')
|
|
||||||
graphContainer.id = 'graph-container'
|
|
||||||
container.appendChild(stencilContainer)
|
|
||||||
container.appendChild(graphContainer)
|
|
||||||
|
|
||||||
insertCss(`
|
|
||||||
#container {
|
|
||||||
display: flex;
|
|
||||||
border: 1px solid #dfe3e8;
|
|
||||||
width: 100vw;
|
|
||||||
height: calc(100vh - 60px);
|
|
||||||
}
|
|
||||||
#stencil {
|
|
||||||
width: 300px;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
|
||||||
border-right: 1px solid #dfe3e8;
|
|
||||||
}
|
|
||||||
.x6-widget-stencil-content{
|
|
||||||
top:0px !important;
|
|
||||||
}
|
|
||||||
.x6-widget-stencil-title{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#graph-container {
|
|
||||||
width: calc(100% - 180px);
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.x6-widget-stencil {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.x6-widget-stencil-title {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.x6-widget-stencil-group-title {
|
|
||||||
background-color: #fff !important;
|
|
||||||
}
|
|
||||||
.x6-widget-transform {
|
|
||||||
margin: -1px 0 0 -1px;
|
|
||||||
padding: 0px;
|
|
||||||
border: 1px solid #239edd;
|
|
||||||
}
|
|
||||||
.x6-widget-transform > div {
|
|
||||||
border: 1px solid #239edd;
|
|
||||||
}
|
|
||||||
.x6-widget-transform > div:hover {
|
|
||||||
background-color: #3dafe4;
|
|
||||||
}
|
|
||||||
.x6-widget-transform-active-handle {
|
|
||||||
background-color: #3dafe4;
|
|
||||||
}
|
|
||||||
.x6-widget-transform-resize {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
.x6-widget-selection-inner {
|
|
||||||
border: 1px solid #239edd;
|
|
||||||
}
|
|
||||||
.x6-widget-selection-box {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
const left = ref(0)
|
const left = ref(0)
|
||||||
const top = ref(0)
|
const top = ref(0)
|
||||||
const isMenuShow = ref(false)
|
const isMenuShow = ref(false)
|
||||||
@ -855,7 +417,7 @@ function copyNode() { // 复制节点
|
|||||||
|
|
||||||
|
|
||||||
function closeAntvx6() {
|
function closeAntvx6() {
|
||||||
emit('closeAntvx6')
|
router.push('/business/project/index')
|
||||||
}
|
}
|
||||||
|
|
||||||
function revokeClick(){
|
function revokeClick(){
|
||||||
@ -1126,42 +688,20 @@ function saveDesign() { // 保存设计
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="app-layout" @click="isMenuShow = false">
|
<div class="app-layout" @click="isMenuShow = false">
|
||||||
<!-- <div class="toolbar">
|
|
||||||
<div class="style-group">
|
|
||||||
<h4>实线</h4>
|
|
||||||
<button @click="setArrowStyle('single', 'solid')">单箭头</button>
|
|
||||||
<button @click="setArrowStyle('double', 'solid')">双箭头</button>
|
|
||||||
<button @click="setArrowStyle('none', 'solid')">无箭头</button>
|
|
||||||
</div>
|
|
||||||
<div class="style-group">
|
|
||||||
<h4>虚线</h4>
|
|
||||||
<button @click="setArrowStyle('single', 'dashed')">单箭头虚线</button>
|
|
||||||
<button @click="setArrowStyle('double', 'dashed')">双箭头虚线</button>
|
|
||||||
<button @click="setArrowStyle('none', 'dashed')">无箭头虚线</button>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
<div class="antvx6-header">
|
<div class="antvx6-header">
|
||||||
<div class="header-left-box">
|
<div class="header-left-box">
|
||||||
<div class="return-icon-box" @click="closeAntvx6" title="返回工作台">
|
<div class="return-icon-box" @click="closeAntvx6" title="返回工作台">
|
||||||
<img src="@/assets/x6/return.png" alt="图标" style="cursor: pointer;">
|
<img src="@/assets/x6/return.png" alt="图标" style="cursor: pointer;">
|
||||||
</div>
|
</div>
|
||||||
<div class="project-name">{{ projectInfo.name }}</div>
|
<div class="project-name">{{ projectInfo.name }}</div>
|
||||||
<div class="return-icon-box" @click="analysisAdd" title="新增模拟分析">
|
<!-- <div class="return-icon-box" @click="analysisAdd" title="新增模拟分析">
|
||||||
<img src="@/assets/x6/add.png" alt="图标" style="cursor: pointer;">
|
<img src="@/assets/x6/add.png" alt="图标" style="cursor: pointer;">
|
||||||
</div>
|
</div>
|
||||||
<div class="return-icon-box" @click="simulationClick" title="历史模拟分析">
|
<div class="return-icon-box" @click="simulationClick" title="历史模拟分析">
|
||||||
<img src="@/assets/x6/history.png" alt="图标" style="cursor: pointer;">
|
<img src="@/assets/x6/history.png" alt="图标" style="cursor: pointer;">
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="header-content-box">
|
<div class="header-content-box">
|
||||||
<div class="operation-icon-box" @click="revokeClick">
|
|
||||||
<img src="@/assets/x6/revoke.png">
|
|
||||||
<div class="operation-icon-text">撤销</div>
|
|
||||||
</div>
|
|
||||||
<div class="operation-icon-box" @click="removeClick">
|
|
||||||
<img src="@/assets/x6/redo.png">
|
|
||||||
<div class="operation-icon-text">重做</div>
|
|
||||||
</div>
|
|
||||||
<div class="operation-icon-box" @click="bigClick">
|
<div class="operation-icon-box" @click="bigClick">
|
||||||
<img src="@/assets/x6/magnify.png">
|
<img src="@/assets/x6/magnify.png">
|
||||||
<div class="operation-icon-text">放大</div>
|
<div class="operation-icon-text">放大</div>
|
||||||
@ -1175,14 +715,10 @@ function saveDesign() { // 保存设计
|
|||||||
<img v-else src="@/assets/x6/hide.png">
|
<img v-else src="@/assets/x6/hide.png">
|
||||||
<div class="operation-icon-text">显示</div>
|
<div class="operation-icon-text">显示</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="operation-icon-box" @click="saveDesign">
|
|
||||||
<img src="@/assets/x6/save.png">
|
|
||||||
<div class="operation-icon-text">保存</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="header-left-box"></div>
|
<div class="header-left-box"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="container" style="position: relative;">
|
<div id="graph-container" style="width: 100%; height: calc(100% - 60px);">
|
||||||
<div class="context-menu" v-if="isMenuShow" :style="{left: left +'px', top: top+'px'}">
|
<div class="context-menu" v-if="isMenuShow" :style="{left: left +'px', top: top+'px'}">
|
||||||
<img src="@/assets/x6/info.png" alt="图标" title="设备信息" style="cursor: pointer;" @click="EditdeviceClick">
|
<img src="@/assets/x6/info.png" alt="图标" title="设备信息" style="cursor: pointer;" @click="EditdeviceClick">
|
||||||
<img src="@/assets/x6/material.png" alt="图标" title="物料信息" style="cursor: pointer;" @click="MaterialModelClick">
|
<img src="@/assets/x6/material.png" alt="图标" title="物料信息" style="cursor: pointer;" @click="MaterialModelClick">
|
||||||
@ -1206,35 +742,6 @@ function saveDesign() { // 保存设计
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Createscenario v-if="dialogVisible" :projectInfo="projectInfo" @closeCreatescenario ="closeCreatescenario"/>
|
|
||||||
<el-dialog v-model="isScenario" :close-on-click-modal="false"
|
|
||||||
:modal="false" draggable :before-close="handleClose" title="历史模拟分析"
|
|
||||||
append-to-body width="1142px">
|
|
||||||
<ScenarioModel v-if="isScenario" :projectInfo="projectInfo" ref="Scenario" />
|
|
||||||
</el-dialog>
|
|
||||||
<el-dialog v-model="isAdddevice" :close-on-click-modal="false"
|
|
||||||
:modal="false" draggable :before-close="dialogAdddevice" title="添加设备"
|
|
||||||
append-to-body width="1050px">
|
|
||||||
<AdddeviceModel v-if="isAdddevice == true" :deviceId="nodeId" :projectInfo="projectInfo"
|
|
||||||
:deviceTypetype="deviceTypetype" ref="Adddevice" @closeAdddevice="closeAdddevice"/>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog v-model="isEditdevice" :close-on-click-modal="false" :modal="false" draggable :before-close="dialogEditdevice" title="物料信息" append-to-body width="1050px">
|
|
||||||
<EditdeviceModel v-if="isEditdevice == true" :deviceId="nodeId" :deviceInfo="deviceInfo"
|
|
||||||
:deviceTypetype="deviceTypetype" ref="Editdevice" @closeEditdevice="closeEditdevice"/>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog v-model="isMaterialModel" :close-on-click-modal="false" :modal="false" draggable :before-close="dialogMaterialModel" title="物料信息" append-to-body width="1014px">
|
|
||||||
<MaterialModels v-if="isMaterialModel == true" :materialId="nodeId" :projectInfo="projectInfo"
|
|
||||||
:materialInfo="materialInfo" :deviceInfo="deviceInfo" :deviceTypetype="deviceTypetype" ref="MaterialModel" @closeMaterialModel="closeMaterialModel"/>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
|
|
||||||
<el-dialog v-model="isChangesettings" :close-on-click-modal="false" :modal="false" draggable :before-close="dialogChangesettings" title="变动设置" append-to-body width="1014px">
|
|
||||||
<ChangesettingsModels v-if="isChangesettings == true" :materialId="nodeId" :projectInfo="projectInfo" :changesettingsData="changesettingsData"
|
|
||||||
:materialInfo="materialInfo" :deviceInfo="deviceInfo" ref="ChangesettingsModel" @closeChangesettingsModel="closeChangesettingsModel"/>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -1391,9 +898,6 @@ function saveDesign() { // 保存设计
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style>
|
<style>
|
||||||
.x6-widget-stencil-content {
|
|
||||||
top: 0px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.antvx6-header {
|
.antvx6-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@ -26,7 +26,12 @@ export const constantRoutes: RouteRecordRaw[] = [
|
|||||||
component: () => import('@/views/error-page/404.vue'),
|
component: () => import('@/views/error-page/404.vue'),
|
||||||
meta: { hidden: true }
|
meta: { hidden: true }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: '图形化分析',
|
||||||
|
path: '/viewanalysis',
|
||||||
|
component: () => import('@/components/antvx6/viewx6.vue'),
|
||||||
|
meta: { hidden: true }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user