修改图形化方法和功能

This commit is contained in:
limengnan 2026-01-21 18:18:52 +08:00
parent fb75114eaf
commit 223f815b15
6 changed files with 467 additions and 34 deletions

View File

@ -0,0 +1,369 @@
<script lang="ts">
export default {
name: "变动设置-弹窗",
};
</script>
<script setup lang="ts">
import { onMounted, ref, nextTick } from "vue";
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
import { topologyDevicesLsit } from '@/api/business/project';
const emit = defineEmits([ 'closeChangeDialogsettings']);
const formula = ref('')
function getName(code:any) {
let tempInfo = {
name: '',
key: '',
type: ''
}
switch (code) {
case 'width':
return tempInfo = {
name: "宽度cm",
key: 'width',
type: 'device'
};
break;
case 'outer_diameter':
return tempInfo = {
name: "外径cm",
key: 'outer_diameter',
type: 'device'
};
break;
case 'height':
return tempInfo = {
name: "高度cm",
key: 'height',
type: 'device'
};
break;
case 'length':
return tempInfo = {
name: "长度cm",
key: 'length',
type: 'device'
};
break;
case 'diameter':
return tempInfo = {
name: "外径cm",
key: 'diameter',
type: 'device'
};
break;
case 'volume':
return tempInfo = {
name: "体积单位L",
key: 'volume',
type: 'device'
};
break;
case 'flow_rate':
return tempInfo = {
name: "流量单位m3/h",
key: 'flow_rate',
type: 'device'
};
break;
case 'pulse_velocity':
return tempInfo = {
name: "脉冲速度单位Hz",
key: 'pulse_velocity',
type: 'device'
};
break;
case 'u_concentration':
return tempInfo = {
name: "铀浓度g/L",
key: 'u_concentration',
type: 'material'
};
break;
case 'uo2_density':
return tempInfo = {
name: "氧化铀密度g/cm3",
key: 'uo2_density',
type: 'material'
};
break;
case 'u_enrichment':
return tempInfo = {
name: "铀富集度(%",
key: 'u_enrichment',
type: 'material'
};
break;
case 'pu_concentration':
return tempInfo = {
name: "钚浓度g/L",
key: 'pu_concentration',
type: 'material'
};
break;
case 'puo2_density':
return tempInfo = {
name: "氧化钚密度g/cm3",
key: 'puo2_density',
type: 'material'
};
break;
case 'pu_isotope':
return tempInfo = {
name: "钚同位素比例PU-240占比%",
key: 'pu_isotope',
type: 'material'
};
break;
case 'hno3_acidity':
return tempInfo = {
name: "硝酸酸度mol/L",
key: 'hno3_acidity',
type: 'material'
};
break;
case 'h2c2o4_concentration':
return tempInfo = {
name: "草酸浓度mol/L",
key: 'h2c2o4_concentration',
type: 'material'
};
break;
case 'organic_ratio':
return tempInfo = {
name: "有机相比例%",
key: 'organic_ratio',
type: 'material'
};
break;
case 'moisture_content':
return tempInfo = {
name: "含水率%",
key: 'moisture_content',
type: 'material'
};
break;
default:
return tempInfo = {
name: "",
key: '',
type: ''
};
}
return tempInfo
}
const props = defineProps({
projectInfo: {
required: false,
type: Object,
default: {}
},
})
const isAcitve = ref(-1);
const attributeList:any = ref([]); //
const deviceList:any = ref([]);
function gettableData() {
topologyDevicesLsit({
id: props.projectInfo.projectId
}).then((res:any) => {
if (res.code == 0) {
deviceList.value = res.data;
}
})
}
function handleClick(item:any, index:any){
attributeList.value = [];
if(item.deviceSize != "" && item.deviceSize != null){
let deviceSize = JSON.parse(item.deviceSize);
item = { ...deviceSize,...item}
}
for(let key in item){
if(getName(key).name != '' && item[key] != '' && item[key] != null){
attributeList.value.push({
name: '('+getName(key).name +')',
key: getName(key).key,
type: getName(key).type,
parentName : getName(key).type == 'device' ? '('+item.deviceName +')' : '('+item.materialName +')',
parentId : getName(key).type == 'device' ? item.deviceId : item.materialId
})
}
}
isAcitve.value = index;
// formulaInfo.value.correlation = JSON.parse(JSON.stringify(item.deviceName))
}
function closeChangeDialogsettings(){
emit('closeChangeDialogsettings',{})
}
const formulaData:any = ref([])
function selectedClick(item:any, index:any){
formulaData.value.push(item)
let tempData:any = []
formulaData.value.forEach((element:any) => {
if(element.parentName != null){
tempData.push(element.parentName)
}else{
tempData.push(element)
}
});
formula.value = tempData.join('')
console.log(formulaData.value)
}
onMounted(() => {
gettableData();
});
;
function selectedSymbolClick(name:any){
formulaData.value.push(name)
let tempData:any = []
formulaData.value.forEach((element:any) => {
if(element.parentName != null){
tempData.push(element.parentName)
}else{
tempData.push(element)
}
});
formula.value = tempData.join('')
}
function delClick(index:any){
formulaData.value.pop()
let tempData:any = []
formulaData.value.forEach((element:any) => {
if(element.parentName != null){
tempData.push(element.parentName)
}else{
tempData.push(element)
}
});
formula.value = tempData.join('')
}
function confirmClick(){
let deviceMaterialData:any = []
formulaData.value.forEach((element:any) => {
if(element.type != null){
deviceMaterialData.push(element)
}
});
emit('closeChangeDialogsettings',{
formula: formula.value,
formulaData: formulaData.value,
deviceMaterialData: deviceMaterialData
})
}
</script>
<template>
<div class="changeDialogsettings-box">
<div class="choiceMateria-left">
<div class="choiceMateria-left-title">设备属性列表</div>
<div style="height: calc(100% - 70px);overflow: auto;margin-top: 10px;">
<div v-for="(item, index) in deviceList" :key="index" class="choiceMateria-left-item" :class="{'choiceMateria-item-active': index == isAcitve}"
@click="handleClick(item, index)">
{{ item.deviceName }}({{ item.materialName }})
</div>
</div>
</div>
<div class="choiceMateria-left">
<div class="choiceMateria-left-title">属性列表</div>
<div style="height: calc(100% - 70px);overflow: auto;margin-top: 10px;">
<div v-for="(item, index) in attributeList" :key="index" class="choiceMateria-left-item"
@click="selectedClick(item, index)">
{{ item.name }}
</div>
</div>
</div>
<div>
<div class="calculator-box">
<div @click="selectedSymbolClick(7)">7</div>
<div @click="selectedSymbolClick(8)">8</div>
<div @click="selectedSymbolClick(9)">9</div>
<div @click="selectedSymbolClick('/')">/</div>
</div>
<div class="calculator-box">
<div @click="selectedSymbolClick(4)">4</div>
<div @click="selectedSymbolClick(5)">5</div>
<div @click="selectedSymbolClick(6)">6</div>
<div @click="selectedSymbolClick('*')">*</div>
</div>
<div class="calculator-box">
<div @click="selectedSymbolClick(1)">1</div>
<div @click="selectedSymbolClick(2)">2</div>
<div @click="selectedSymbolClick(3)">3</div>
<div @click="selectedSymbolClick(3)">-</div>
</div>
<div class="calculator-box">
<div style="width: 220px;" @click="selectedSymbolClick(0)">0</div>
<div @click="selectedSymbolClick('.')">.</div>
<div @click="selectedSymbolClick('+')">+</div>
</div>
<div class="formula-viewbox">
{{ formula }}
</div>
<el-button type="primary" @click="delClick"> </el-button>
<el-button type="primary" @click="confirmClick"> </el-button>
<!--
-->
</div>
</div>
</template>
<style scoped>
.changeDialogsettings-box{
display: flex;
}
.choiceMateria-item-active{
background-color: #f5f8ff;
color: #266fff;
}
.calculator-box{
display: flex;
align-items: center;
}
.calculator-box div{
width: 100px;
height: 80px;
line-height: 80px;
text-align: center;
border: 1px solid #ccc;
border-radius: 5px;
margin: 10px;
cursor: pointer;
font-size: 30px;
}
.calculator-box div:hover{
background-color: #f5f8ff;
}
.formula-viewbox{
width: 460px;
height: 80px;
line-height: 40px;
text-align: left;
border: 1px solid #ccc;
border-radius: 5px;
padding: 0 10px;
margin: 10px;
font-size: 14x;
}
</style>

View File

@ -9,7 +9,7 @@ import { onMounted, ref, nextTick } from "vue";
import { ElForm, ElMessage, ElMessageBox } from "element-plus"; import { ElForm, ElMessage, ElMessageBox } from "element-plus";
import { searchDevicesPage } from "@/api/business/database/device"; import { searchDevicesPage } from "@/api/business/database/device";
import { topologyDevicesLsit } from '@/api/business/project'; import { topologyDevicesLsit } from '@/api/business/project';
import ChangeDialogsettings from './changeDialogsettings.vue';
const emit = defineEmits([ 'closeChangesettingsModel']); const emit = defineEmits([ 'closeChangesettingsModel']);
const props = defineProps({ const props = defineProps({
@ -202,8 +202,25 @@ function confirmTableClick(){ // 确认变动公式设置
tableData.value[tableIndex.value].formula = formulaInfo.value.formula tableData.value[tableIndex.value].formula = formulaInfo.value.formula
tableData.value[tableIndex.value].correlation = formulaInfo.value.correlation tableData.value[tableIndex.value].correlation = formulaInfo.value.correlation
tableData.value[tableIndex.value].delay = formulaInfo.value.delay tableData.value[tableIndex.value].delay = formulaInfo.value.delay
tableData.value[tableIndex.value].formulaData = formulaInfo.value.formulaData
tableData.value[tableIndex.value].deviceMaterialData = formulaInfo.value.deviceMaterialData
isDialogFormula.value = false isDialogFormula.value = false
} }
const isChangeDialogsettings:any = ref(false) //
function openChangeDialogsettings(){ //
isChangeDialogsettings.value = true
}
function dialogChangeDialogsettings(){ //
isChangeDialogsettings.value = false
}
function closeChangeDialogsettings(e:any){ //
formulaInfo.value.formula = e.formula
formulaInfo.value.formulaData = e.formulaData
formulaInfo.value.deviceMaterialData = e.deviceMaterialData
isChangeDialogsettings.value = false
}
</script> </script>
<template> <template>
@ -277,7 +294,12 @@ function confirmTableClick(){ // 确认变动公式设置
<div>变动公式</div> <div>变动公式</div>
</div> </div>
<el-form-item label="值=" style="width: 100%;" label-width="80px"> <el-form-item label="值=" style="width: 100%;" label-width="80px">
<el-input v-model="formulaInfo.formula" style="width: 100%"></el-input> <div class="valuebox-input">
{{ formulaInfo.formula }}
</div>
<el-button type="primary" @click="openChangeDialogsettings">设置</el-button>
<!-- <el-input v-model="formulaInfo.formula" style="width: 100%" disabled="true" ></el-input> -->
</el-form-item> </el-form-item>
<div style="display: flex;align-items: center;padding: 20px 0;"> <div style="display: flex;align-items: center;padding: 20px 0;">
@ -302,6 +324,14 @@ function confirmTableClick(){ // 确认变动公式设置
</div> </div>
</el-dialog> </el-dialog>
<el-dialog v-model="isChangeDialogsettings" :close-on-click-modal="false" :modal="false" draggable
:before-close="dialogChangeDialogsettings" title="变动公式值设置" append-to-body width="1280px" class="materialmodel-dialog-box">
<ChangeDialogsettings v-if="isChangeDialogsettings" :projectInfo="projectInfo"
@closeChangeDialogsettings="closeChangeDialogsettings" />
</el-dialog>
</div> </div>
</template> </template>
@ -364,4 +394,16 @@ function confirmTableClick(){ // 确认变动公式设置
.materialmodel-dialog-box.el-dialog .el-dialog__body{ .materialmodel-dialog-box.el-dialog .el-dialog__body{
padding: 0 !important; padding: 0 !important;
} }
.valuebox-input{
width:calc(100% - 70px) ;
height: 40px;
line-height: 40px;
margin-right: 10px;
background: #f5f7fa;
/* border: 1px solid rgba(240, 240, 240, 1); */
background-color: #ffffff;
box-shadow: 0 0 0 1px var(--el-disabled-border-color) inset;
border-radius: 4px;
cursor: pointer;
}
</style> </style>

View File

@ -46,6 +46,9 @@ function getName(code:any) {
case 'width': case 'width':
return name = "宽度cm"; return name = "宽度cm";
break; break;
case 'outer_diameter':
return name = "外径cm";
break;
case 'height': case 'height':
return name = "高度cm"; return name = "高度cm";
break; break;
@ -119,7 +122,7 @@ const option = ref<any>({
feature: { feature: {
saveAsImage: { saveAsImage: {
title: '导出图片', // hover title: '导出图片', // hover
name: '导出图片', // name: '图片', //
pixelRatio: 2 // pixelRatio: 2 //
} }
} }

View File

@ -28,11 +28,16 @@ const route = useRoute();
const router = useRouter() const router = useRouter()
const emit = defineEmits([ 'closeAntvx6']); const emit = defineEmits([ 'closeAntvx6']);
const props = defineProps({ const props = defineProps({
projectInfo: { projectId: {
required: false, required: false,
type: Object, type: String,
default: {} default: ''
}, },
scenarioId: {
required: false,
type: String,
default: ''
}
}) })
const deviceTypetype:any = ref('') // const deviceTypetype:any = ref('') //
const isAdddevice = ref(false) // const isAdddevice = ref(false) //
@ -173,6 +178,9 @@ function getName(code:any) {
case 'width': case 'width':
return name = "宽度cm"; return name = "宽度cm";
break; break;
case 'outer_diameter':
return name = "外径cm";
break;
case 'height': case 'height':
return name = "高度cm"; return name = "高度cm";
break; break;
@ -291,7 +299,8 @@ function groupByDeviceId(data:any) { // 按设备id分组
} }
onMounted(() => { onMounted(() => {
scenarioId.value = route.query.scenarioId
scenarioId.value = props.scenarioId
// #region // #region
graph = new Graph({ graph = new Graph({
container: document.getElementById('graph-container') as HTMLElement, container: document.getElementById('graph-container') as HTMLElement,
@ -582,7 +591,7 @@ onMounted(() => {
projectsById({projectId:route.query.projectId}).then((res:any) => { projectsById({projectId:props.projectId}).then((res:any) => {
if(res.topology != null && res.topology != ''){ if(res.topology != null && res.topology != ''){
projectInfo.value = res projectInfo.value = res
if (!graph || !projectInfo.value || !projectInfo.value.topology) return; if (!graph || !projectInfo.value || !projectInfo.value.topology) return;
@ -676,14 +685,14 @@ function isDisplayClick(){
</script> </script>
<template> <template>
<div class="app-layout" @click="isMenuShow = false"> <div class="antvx6-layout" @click="isMenuShow = false">
<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>
@ -735,14 +744,14 @@ function isDisplayClick(){
box-sizing: border-box; box-sizing: border-box;
} }
.app-layout { .antvx6-layout{
position: fixed; /* position: relative;
z-index: 10; z-index: 10;
display: flex; display: flex;
flex-direction: column; flex-direction: column; */
width: 100vw; width:100%;
height: 100vh; height: calc(100vh - 150px);
font-family: 'Segoe UI', sans-serif; /* font-family: 'Segoe UI', sans-serif; */
} }
.toolbar { .toolbar {
@ -851,13 +860,13 @@ function isDisplayClick(){
} }
/* Graph Container Styles */ /* Graph Container Styles */
.graph-container { #graph-container {
flex: 1; flex: 1;
position: relative; position: relative;
background-color: #fafafa; background-color: #fafafa;
overflow: hidden; overflow: hidden;
width: 100%; width: 100% !important;
height: 100%; height: calc(100% - 60px) !important;
} }
/* Drag and drop visual feedback */ /* Drag and drop visual feedback */
@ -927,6 +936,7 @@ function isDisplayClick(){
font-size: 16px; font-size: 16px;
color: #333333; color: #333333;
margin-right: 10px; margin-right: 10px;
margin-left: 10px;
} }
.antvx6-header .operation-icon-box { .antvx6-header .operation-icon-box {

View File

@ -156,7 +156,7 @@ onMounted(() => {
</div> </div>
<div style="text-align: center;"> <div style="text-align: center;">
<el-button v-if="stepsActive == 0" type="primary" @click="confirmClick(infoForm)">下一步</el-button> <el-button v-if="stepsActive == 0" type="primary" @click="confirmClick(infoForm)">下一步</el-button>
<el-button v-else type="primary" @click="submitClick">下一步</el-button> <el-button v-else type="primary" @click="submitClick">确定</el-button>
</div> </div>
</el-dialog> </el-dialog>

View File

@ -18,6 +18,8 @@ import { eventsBatchSave } from '@/api/business/event';
import { topologyDevicesLsit } from '@/api/business/project'; import { topologyDevicesLsit } from '@/api/business/project';
import TableModels from '@/components/antvx6/tableModel.vue'; import TableModels from '@/components/antvx6/tableModel.vue';
import EchartsModels from '@/components/antvx6/echartsModel.vue'; import EchartsModels from '@/components/antvx6/echartsModel.vue';
import Viewx6 from '@/components/antvx6/viewx6.vue';
const webUrl = import.meta.env.VITE_APP_BASE_HTTP; // const webUrl = import.meta.env.VITE_APP_BASE_HTTP; //
const algorithmTypeData: any = ref([]); // const algorithmTypeData: any = ref([]); //
const stepsActive = ref(0); // const stepsActive = ref(0); //
@ -241,7 +243,8 @@ function confirmationAnalysis(row: any) {
}); });
gettableData(); gettableData();
setTimeout(() => { setTimeout(() => {
window.open(webUrl + '/#/viewanalysis?projectId='+ row.projectId +'&scenarioId='+ row.scenarioId, '_blank'); resultClick(row)
// window.open(webUrl + '/#/viewanalysis?projectId='+ row.projectId +'&scenarioId='+ row.scenarioId, '_blank');
}, 1000); }, 1000);
}else{ }else{
@ -299,6 +302,7 @@ function submitConditionClick(){
} }
function resultClick(row:any){ function resultClick(row:any){
title.value = props.projectInfo.name + ' - ' + props.projectInfo.createdAt + ' - ' + row.name
isAcitve.value = 0 isAcitve.value = 0
scenarioId.value = row.scenarioId, scenarioId.value = row.scenarioId,
getMenuData() getMenuData()
@ -332,9 +336,9 @@ function handleClick(item:any, index:any){
function handleResultClose(){ // function handleResultClose(){ //
isShowResult.value = false; isShowResult.value = false;
} }
const isEchartsModel = ref<boolean>(false) // echarts const isEchartsModel = ref<any>(0) // echarts
function changeShowResult(isShow:boolean){ // function changeShowResult(isShow:any){ //
isEchartsModel.value = isShow isEchartsModel.value = isShow
let tempId = deviceId.value let tempId = deviceId.value
deviceId.value = '' deviceId.value = ''
@ -458,7 +462,14 @@ function changeShowResult(isShow:boolean){ // 切换显示结果模型
<el-dialog v-model="isShowResult" :close-on-click-modal="false" <el-dialog v-model="isShowResult" :close-on-click-modal="false"
:modal="false" draggable :before-close="handleResultClose" :title="title" :modal="false" draggable :before-close="handleResultClose" :title="title"
append-to-body width="calc(100% - 100px)" class="resultmodel-dialog-box"> append-to-body width="calc(100% - 100px)" class="resultmodel-dialog-box">
<div style="display: flex;"> <div style="display: flex; margin-bottom: 0px; border-bottom: 1px solid #e5e5e5;padding-bottom: 5px;padding-top: 10px;">
<div @click="changeShowResult(0)" class="adddevice_navigation_left" :class="{'adddevice_navigation_activeleft':isEchartsModel == 0}">图形化</div>
<div @click="changeShowResult(1)" class="adddevice_navigation_right" :class="{'adddevice_navigation_activeright':isEchartsModel == 1}">列表</div>
<div @click="changeShowResult(2)" class="adddevice_navigation_right" :class="{'adddevice_navigation_activeright':isEchartsModel == 1}">图形</div>
</div>
<Viewx6 v-if="isShowResult && isEchartsModel == 0 " :projectId="projectInfo.projectId" :scenarioId="scenarioId"/>
<div style="display: flex;" v-if="isEchartsModel == 1 || isEchartsModel == 2">
<div class="choiceMateria-left"> <div class="choiceMateria-left">
<div class="choiceMateria-left-title">设备列表</div> <div class="choiceMateria-left-title">设备列表</div>
<div style="height: calc(100% - 70px);overflow: auto;margin-top: 10px;"> <div style="height: calc(100% - 70px);overflow: auto;margin-top: 10px;">
@ -469,16 +480,10 @@ function changeShowResult(isShow:boolean){ // 切换显示结果模型
</div> </div>
</div> </div>
</div> </div>
<div style="padding-left: 45px;padding-top: 40px; width: calc(100% - 290px); height: calc(100vh - 100px);"> <div style="padding-left: 45px;padding-top: 20px; width: calc(100% - 290px); height: calc(100vh - 150px);">
<div style="display: flex; margin-bottom: 20px; border-bottom: 1px solid #e5e5e5;padding-bottom: 5px;"> <TableModels v-if="isShowResult && isEchartsModel == 1 && deviceId !=''" :deviceId="deviceId" :scenarioId="scenarioId"/>
<div @click="changeShowResult(false)" class="adddevice_navigation_left" :class="{'adddevice_navigation_activeleft':!isEchartsModel}">列表</div> <EchartsModels v-if="isShowResult && isEchartsModel == 2 && deviceId !=''" :deviceId="deviceId" :scenarioId="scenarioId"/>
<div @click="changeShowResult(true)" class="adddevice_navigation_right" :class="{'adddevice_navigation_activeright':isEchartsModel}">图形</div>
</div> </div>
<TableModels v-if="isShowResult && isEchartsModel == false && deviceId !=''" :deviceId="deviceId" :scenarioId="scenarioId"/>
<EchartsModels v-if="isShowResult && isEchartsModel == true && deviceId !=''" :deviceId="deviceId" :scenarioId="scenarioId"/>
</div>
</div> </div>
</el-dialog> </el-dialog>
@ -740,4 +745,8 @@ function changeShowResult(isShow:boolean){ // 切换显示结果模型
.resultmodel-dialog-box.el-dialog .el-dialog__body{ .resultmodel-dialog-box.el-dialog .el-dialog__body{
padding: 0 !important; padding: 0 !important;
} }
.resultmodel-dialog-box.el-dialog{
transform: translate(0) !important;
}
</style> </style>