index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. <template>
  2. <VueFlow ref="vueFlowRef" :nodes="nodes" :edges="edges" :class="{ dark }"
  3. class="basic-flow"
  4. :default-viewport="{ zoom: 1.5 }" :min-zoom="0.2" :max-zoom="2.5" @drop="onDrop1"
  5. @contextmenu.prevent="onContextMenu" @node-contextmenu="logEvent('contextmenu', $event)"
  6. @dragover="onDragOver" @dragleave="onDragLeave" @edge-click="onEdgeClick" @node-double-click="onNodeDoubleClick"
  7. @node-click="onNodeClick" @edge-double-click="onEdgeDoubleClick">
  8. <template #node-default="props">
  9. <eltree :node="props" />
  10. </template>
  11. <template #edge-default="props">
  12. <custom-edge :sourceX="props.sourceX"
  13. :sourceY="props.sourceY"
  14. :targetX="props.targetX"
  15. :targetY="props.targetY"
  16. :label="props.data.label" />
  17. </template>
  18. <Background pattern-color="#aaa" :gap="16" />
  19. <!-- <MiniMap /> @input="handleUpdate"-->
  20. <Panel :position="'right'" style="display: none;">
  21. <div class="field">
  22. <div>
  23. <label for="label">Label:</label>
  24. <input id="label" v-model.lazy="labelname" /></div>
  25. <button @click="handleUpdate" class="lableaniu">确定</button>
  26. </div>
  27. <!-- <div> -->
  28. <!-- <button class="remove" @click="removeNode(event)">N</button>
  29. <button class="remove" @click="removeEdge(event)">E</button>
  30. <button class="remove" @click="removeall(event)">all</button>
  31. </div> -->
  32. <!-- <button @click="onSelection()" class="lableaniu">获取</button> -->
  33. </Panel>
  34. <Controls position="top-left">
  35. <ControlButton title="重置" @click="resetTransform">
  36. <Icon name="reset" />
  37. </ControlButton>
  38. <ControlButton title="背景切换" @click="toggleDarkMode">
  39. <Icon v-if="dark" name="sun" />
  40. <Icon v-else name="moon" />
  41. </ControlButton>
  42. <ControlButton title="保存" @click="logToObject1">
  43. <!-- <Icon name="log" /> -->
  44. <el-icon :color="iconcolor"><UploadFilled /></el-icon>
  45. </ControlButton>
  46. <ControlButton title="删除节点" @click="removeNode()">
  47. <el-icon :color="iconcolor"><DocumentDelete /></el-icon>
  48. </ControlButton>
  49. <ControlButton title="删除线" @click="removeEdge()">
  50. <el-icon :color="iconcolor"><Crop /></el-icon>
  51. </ControlButton>
  52. <ControlButton title="清空全部" @click="removeall()">
  53. <el-icon :color="iconcolor"><DeleteFilled /></el-icon>
  54. </ControlButton>
  55. </Controls>
  56. <el-dialog v-model="changeNameshow" align-center :modal="false" :close-on-click-modal="false"
  57. :append-to-body="true" draggable :fullscreen="false" :modal-append-to-body="false" modal-class="summary-dlg"
  58. width="400" class="dialog_class bgcolor colortext tianjia sel">
  59. <template #header="{ titleId, titleClass }">
  60. <div class="my-header ">
  61. <h4 :id="titleId" :class="titleClass">修改名称</h4>
  62. </div>
  63. </template>
  64. <div style="margin-top: 20px;padding: 20px;">
  65. <el-form :model="changeName" label-width="100px" class="demo-ruleForm">
  66. <el-form-item label="新名称:" prop="name">
  67. <el-input v-model="changeName.name" placeholder="请输入名称"></el-input>
  68. </el-form-item>
  69. </el-form>
  70. </div>
  71. <template #footer>
  72. <div class="dialog-footer">
  73. <el-button @click="changeNameshow = false">取 消</el-button>
  74. <el-button type="primary" @click="handleUpdate">确 定</el-button>
  75. </div>
  76. </template>
  77. </el-dialog>
  78. <!-- 双击线段 -->
  79. <el-dialog v-model="dataflowshow" align-center :modal="false" :close-on-click-modal="false"
  80. :append-to-body="true" draggable :fullscreen="false" :modal-append-to-body="false" modal-class="summary-dlg"
  81. width="500" class="dialog_style bgcolor colortext tianjia sel">
  82. <template #header="{ titleId, titleClass }">
  83. <div class="my-header ">
  84. <h4 :id="titleId" :class="titleClass">数据流</h4>
  85. </div>
  86. </template>
  87. <div style="margin-top: 5px;padding: 10px 35px;">
  88. <el-card>
  89. <el-checkbox v-model="checkAll"
  90. :indeterminate="isIndeterminate"
  91. @change="handlecheckAllchange">全选</el-checkbox>
  92. <div class="eldesign classtable">
  93. <el-table :data="shujuliutable" border>
  94. <el-table-column
  95. type="index"
  96. label=""
  97. :header-cell-style="{ display: 'none' }"
  98. ></el-table-column>
  99. <el-table-column prop="flag" width="55">
  100. <template #default="{ row }">
  101. <el-checkbox
  102. :false-label="0"
  103. :true-label="1"
  104. v-model="row.flag"
  105. @change="handlecheckFlagchange"></el-checkbox>
  106. </template>
  107. </el-table-column>
  108. <el-table-column prop="data" label="" ></el-table-column>
  109. </el-table>
  110. </div>
  111. </el-card>
  112. </div>
  113. <template #footer>
  114. <div class="dialog-footer">
  115. <el-button @click="dataflowshow = false">取 消</el-button>
  116. <el-button type="primary" @click="confirmselection();dataflowshow = false ">确 定</el-button>
  117. </div>
  118. </template>
  119. </el-dialog>
  120. </VueFlow>
  121. <div class="dnd-flow">
  122. <!-- <div id="contextMenu" @click="deleteItemConfirm">删除</div> -->
  123. </div>
  124. </template>
  125. <script setup>
  126. import { ref, markRaw,inject } from 'vue'
  127. import { VueFlow,Panel, useVueFlow, MarkerType} from '@vue-flow/core'
  128. import { ElMessage, ElButton, ElDialog, ElSelect } from 'element-plus'
  129. import {
  130. DocumentDelete,
  131. Delete,
  132. UploadFilled,
  133. Histogram,
  134. DeleteFilled,
  135. Crop,
  136. } from '@element-plus/icons-vue'
  137. import { useRoute } from 'vue-router';
  138. import { request, uploadFile } from "@/utils/request";
  139. import { Background } from '@vue-flow/background'
  140. import { ControlButton, Controls } from '@vue-flow/controls'
  141. import { initialEdges, initialNodes } from './modeljs.js'
  142. import { MiniMap } from '@vue-flow/minimap'
  143. import "./main.css";//重置样式
  144. import DropzoneBackground from './DropzoneBackground.vue'
  145. import eltree from './eltree.vue'
  146. import CustomEdge from './CustomEdge.vue';
  147. import useDragAndDrop from './useDnD';
  148. import f11 from '@/assets/img/f11.png'
  149. import r2 from '@/assets/img/r2.png'
  150. import html2canvas from 'html2canvas';
  151. import Icon from './Icon.vue'
  152. import { formatTime } from '@/js/lindex.js';
  153. import emitter from "@/utils/emitter";
  154. // import func from 'vue-temp/vue-editor-bridge.js';
  155. const dark = ref(false)
  156. let datatree=ref();
  157. const route = useRoute();
  158. const { onInit, onNodeDragStop, onNodeContextMenu, onConnect, addEdges, setViewport, toObject,addNode } = useVueFlow()
  159. let vueFlowRef = ref();
  160. let emit = defineEmits(['optimizerfalse']);
  161. let mergedObj=ref();
  162. let labelname=ref();
  163. let iconcolor=ref('#000')
  164. const props = defineProps({
  165. optimizer: {
  166. type: Boolean,
  167. },
  168. jboptimizer: {
  169. type: Boolean,
  170. },
  171. Xfoil: {
  172. type: Boolean,
  173. },
  174. // color1: {
  175. // type: String,
  176. // },
  177. })
  178. let newobj=ref({
  179. name:'',
  180. description:'',
  181. })
  182. let nodesitem=ref([]);
  183. let linenum=ref(1);
  184. let bgcolor=ref();
  185. let linecolor=ref('#b1b1b7')
  186. let pid=ref('');
  187. let newroter=ref();
  188. let vueflowimg=ref('');
  189. const shopShow = ref(false);
  190. let noid = ref([]);
  191. let Edgeid = ref();
  192. let seledge=ref(null);
  193. let djshow=ref(false);
  194. let node = ref();
  195. let contextMenu = ref({
  196. position: { x: 0, y: 0 },
  197. target: 'kong',
  198. })
  199. let Nested=ref([]);
  200. let Nested2=ref([]);
  201. let nnum=ref(0);
  202. const { onDragOver, onDrop, onDragLeave, isDragOver } = useDragAndDrop();
  203. const edges = ref([]);
  204. const nodes = ref([]);
  205. const changeNameshow = ref(false);
  206. const changeName = ref({
  207. name: '',
  208. })
  209. onNodeContextMenu((e) => {
  210. noid.value = e.node;
  211. changeName.value.name = e.node.data.label;
  212. changeNameshow.value = true;
  213. })
  214. onConnect((connection) => {
  215. console.log(connection);
  216. connection.type = 'smoothstep';// smoothstep straight
  217. connection.markerEnd = MarkerType.ArrowClosed;
  218. connection.color=linecolor.value;
  219. // connection.label = '这是一条注释';
  220. connection.style = { strokeWidth:linenum.value ,stroke:linecolor.value};
  221. addEdges(connection)
  222. seledge.value=null;
  223. })
  224. //修改名称
  225. const handleUpdate = () => {
  226. if (noid.value && noid.value.data) {
  227. noid.value.data.label = changeName.value.name; // 更新名称
  228. console.log(noid.value.data.label); // 打印更新后的值
  229. } else {
  230. console.error("noid.value 或 noid.value.data 未定义"); // 错误日志
  231. }
  232. changeNameshow.value = false; // 更新后关闭对话框
  233. // noid.value.data.label = labelname;
  234. };
  235. emitter.on('child2Data', data => {
  236. datatree.value = data;
  237. console.log(datatree.value);
  238. })
  239. onUnmounted(() => {
  240. emitter.off('child2Data');
  241. });
  242. function onNodeClick(e) {
  243. noid.value = e.node;
  244. changeName.value.name=e.node.data.label;
  245. console.log("shuju:",e.node.data);
  246. console.log("noid.value:",noid.value);
  247. console.log("changeName.value:",changeName.value.name);
  248. djshow.value = !djshow.value;
  249. // if(djshow.value){
  250. // console.log('选中');
  251. // }else{
  252. // console.log('取消选中');
  253. // }
  254. }
  255. //模块化
  256. const bgcolorfunc= (color)=>{
  257. bgcolor.value=color;
  258. if(noid.value.style!=undefined){
  259. console.log(noid.value.style);
  260. noid.value.style.backgroundColor=color;
  261. }
  262. }
  263. function onSelection(){
  264. let positionX=[];
  265. let positiony=[];
  266. for(let i=0;i<Nested.value.length;i++){
  267. // Nested2.value.push(Nested.value[i]);
  268. positionX.push(Nested.value[i].position.x)
  269. positiony.push(Nested.value[i].position.y)
  270. }
  271. let xmin=Math.min(...positionX);
  272. let ymax=Math.max(...positiony);
  273. console.log(positionX);
  274. // console.log( positionX)
  275. // console.log(44444)
  276. // console.log( positiony)
  277. nnum.value++;
  278. // let x=Math.floor(Math.random() * 91) + 10;
  279. // let y=Math.floor(Math.random() * 91) + 10;
  280. let name='模块'+nnum.value
  281. let item= {
  282. id:nnum.value.toString(),
  283. data: { label:name },
  284. position: { x:xmin , y:ymax},
  285. style: { backgroundColor: bgcolor.value, width: '200px',height: '200px' },
  286. //children: [],
  287. }
  288. if(Nested.value.length!=0){
  289. Nested2.value=[];
  290. for(let i=0;i<Nested.value.length;i++){
  291. Nested2.value.push(Nested.value[i]);
  292. }
  293. console.log(Nested2.value);
  294. nodesitem.value= Nested2.value.map(node => {
  295. if(node.parentNode==undefined){
  296. node.isParent=false;
  297. node.parentNode=item.id;
  298. console.log( node.parentNode)
  299. node.position.x= node.position.x /2;
  300. node.position.y= node.position.y/2;
  301. node.expandParent=true;
  302. //positionxy=node.position;
  303. // node.extent='parent';
  304. // return node;
  305. }
  306. return node;
  307. })
  308. }
  309. nodes.value.push(item)
  310. for(let i=0;i<nodesitem.value.length;i++){
  311. console.log(nodesitem.value[i]);
  312. nodes.value.push(nodesitem.value[i])
  313. }
  314. console.log( nodes.value);
  315. }
  316. function onNodeDoubleClick(e) {
  317. noid.value = e.node;
  318. console.log( e.node.data.name);
  319. if (e.node.data.name == '优化器') {
  320. emit('optimizerfalse','优化器');
  321. }else if(e.node.data.name=="进化优化器"){
  322. emit('optimizerfalse','进化优化器');
  323. }else if(e.node.data.name=="代理优化器"){
  324. emit('optimizerfalse','代理优化器');
  325. }else if(e.node.data.name=="Xfoil"){
  326. emit('optimizerfalse','Xfoil');
  327. }else if(e.node.data.name=="梯度优化器"){
  328. emit('optimizerfalse','梯度优化器');
  329. }else if(e.node.data.name=="CST"){
  330. emit('optimizerfalse','CST');
  331. }else if(e.node.data.name=="ADflow"){
  332. emit('optimizerfalse','ADflow');
  333. }else if(e.node.data.name=="CST"){
  334. emit('optimizerfalse','CST');
  335. }else if(e.node.data.name=="FFD"){
  336. emit('optimizerfalse','FFD');
  337. }else if(e.node.data.name=="TACS"){
  338. emit('optimizerfalse','TACS');
  339. }else if(e.node.data.name=="参数化"){
  340. emit('optimizerfalse','参数化');
  341. }else if(e.node.data.name=="气动分析"){
  342. emit('optimizerfalse','气动分析');
  343. }else if(onPythonlist.value.some(item => e.node.data.name.includes(item))){
  344. emit('optimizerfalse','Python');
  345. }else if(e.node.data.name=="CATIA"){
  346. emit('optimizerfalse','CATIA');
  347. }else if(e.node.data.name=="FSI"){
  348. emit('optimizerfalse','FUM to FEM');
  349. }else if(e.node.data.name=="Flight"){
  350. emit('optimizerfalse','Flight');
  351. }
  352. }
  353. let onPythonlist=ref(['Python','Branin','Rosenbrock','Rastrigin','G9','Forrester']);
  354. let previousEdge = null; // 用于保存上一个选中的边缘
  355. // 监听线
  356. function onEdgeClick(e) {
  357. // 如果已经有选中的边缘
  358. if (seledge.value) {
  359. // 恢复上一个选中边缘的样式
  360. if (previousEdge) {
  361. previousEdge.style = {
  362. ...previousEdge.style,
  363. stroke: previousEdge.originalColor, // 恢复原始颜色
  364. strokeWidth: 1, // 恢复原始宽度
  365. };
  366. }
  367. }
  368. // 保存当前点击的边缘为选中边缘
  369. Edgeid.value = e.edge.id;
  370. seledge.value = e.edge;
  371. // 暂时更改当前选中边缘的样式
  372. seledge.value.originalColor = seledge.value.style.stroke; // 保存当前边缘的原始颜色
  373. seledge.value.style = {
  374. ...seledge.value.style,
  375. stroke: '#2267B1', // 设置选中边缘的颜色
  376. strokeWidth: 2, // 设置选中边缘的宽度
  377. };
  378. // 保存当前选中的边缘作为上一个选中边缘
  379. previousEdge = seledge.value;
  380. }
  381. let dataflowshow=ref(false);
  382. let shujuliutable = ref([
  383. {data: '升力系数Cl',flag:1},
  384. {data: '阻力系数Cd',flag:1},
  385. {data: '压阻力系数Cdp',flag:1},
  386. {data: '上表面转换点位置xtr-upper',flag:1},
  387. {data: '下表面转换点位置xtr-lower',flag:1},
  388. ])
  389. let checkAll = ref(false);
  390. let isIndeterminate = ref(false);
  391. const handlecheckAllchange = (val) => {
  392. shujuliutable.value.forEach((item) => {
  393. item.flag = val;
  394. });
  395. isIndeterminate.value = false;
  396. };
  397. const handlecheckFlagchange = () => {
  398. let checkedCount = shujuliutable.value.filter((item) => item.flag).length;
  399. checkAll.value = checkedCount === shujuliutable.value.length;
  400. isIndeterminate.value = checkedCount > 0 && checkedCount < shujuliutable.value.length;
  401. };
  402. const confirmselection=()=>{
  403. let checkedData = shujuliutable.value.filter((item) => item.flag).map((item) => item.data);
  404. console.log('xuanzhongshuju:',checkedData);
  405. console.log('seledge:',seledge.value);
  406. seledge.value.label=checkedData.join('\n');
  407. dataflowshow.value = false;
  408. }
  409. function onEdgeDoubleClick(e) {
  410. handlecheckFlagchange();
  411. console.log('Edge Double Click', e)
  412. seledge.value = e.edge;
  413. dataflowshow.value = true
  414. }
  415. function logEvent(name, event) {
  416. console.log(2222)
  417. }
  418. // 右键更改名字
  419. // const onContextMenu = (e) => {
  420. // e.preventDefault(); // 阻止浏览器默认的右键菜单
  421. // const node = e.target.closest(".vue-flow__node");
  422. // console.log("nodes:",nodes);
  423. // console.log("node:",node);
  424. // if (node) {
  425. // // 获取当前右键点击的节点
  426. // const nodeId = node.getAttribute("data-id");
  427. // const clickedNode = nodes.value.find((n) => n.id === nodeId);
  428. // console.log("clickedNode:",clickedNode);
  429. // if (clickedNode) {
  430. // noid.value = clickedNode;
  431. // changeName.value.name = clickedNode.label; // 将当前节点的label放入弹窗中
  432. // changeNameshow.value = true; // 显示弹窗
  433. // }
  434. // }
  435. // };
  436. onInit((vueFlowInstance) => {
  437. vueFlowInstance.fitView()
  438. })
  439. onNodeDragStop(({ event, nodes, node }) => {
  440. console.log(nodes)
  441. Nested.value=nodes;
  442. console.log('Node Drag Stop', { event, nodes, node })
  443. })
  444. onConnect((connection) => {
  445. addEdges(connection)
  446. })
  447. function updatePos() {
  448. nodes.value = nodes.value.map((node) => {
  449. return {
  450. ...node,
  451. position: {
  452. x: Math.random() * 400,
  453. y: Math.random() * 400,
  454. },
  455. }
  456. })
  457. }
  458. function removeEdge(id) {
  459. id = Edgeid.value;
  460. vueFlowRef.value.removeEdges(id);
  461. console.log('msg:',datatree.value);
  462. }
  463. // 触摸
  464. const onDrop1=(event)=>{
  465. onDrop(event);
  466. emitter.emit('doSomethingEvent');
  467. }
  468. function removeNode(id) {
  469. id = noid.value.id;
  470. if(datatree.value==undefined){
  471. if(nodes.value.length>0){
  472. for (let i = 0; i <nodes.value.length; i++) {
  473. if(id==nodes.value[i].id){
  474. console.log(44444)
  475. console.log( nodes.value[i]);
  476. nodes.value.splice(i, 1)
  477. }
  478. }
  479. console.log( nodes.value);
  480. }
  481. }else{
  482. if(nodes.value.length>0){
  483. for (let i = 0; i <nodes.value.length; i++) {
  484. if(id==nodes.value[i].id){
  485. console.log( nodes.value[i]);
  486. nodes.value.splice(i, 1)
  487. }
  488. }
  489. }
  490. for (let i = 0; i <datatree.value[0].children.length; i++) {
  491. if(id.includes(datatree.value[0].children[i].Text)){
  492. for (let j = 0; j <datatree.value[0].children[i].children.length; j++) {
  493. if(id==datatree.value[0].children[i].children[j].id){
  494. //datatree.value[0].children.splice(datatree.value[0].children[i].children[j], 1);
  495. datatree.value[0].children[i].children.splice(j, 1)
  496. vueFlowRef.value.removeNodes(id);
  497. }
  498. }
  499. }
  500. }
  501. }
  502. }
  503. function removeall(){
  504. nodes.value=[];
  505. edges.value=[];
  506. Nested2.value=[];
  507. Nested.value=[];
  508. for (let i = 0; i <datatree.value[0].children.length; i++) {
  509. for (let j = 0; j <datatree.value[0].children[i].children.length; j++) {
  510. datatree.value[0].children[i].children=[];
  511. }
  512. }
  513. }
  514. async function logToObject1() {
  515. let obj = { nodes: toObject().nodes,edges:toObject().edges };
  516. mergedObj.value=JSON.stringify(obj);
  517. try {
  518. const container = vueFlowRef.value.$el;
  519. const canvas = await html2canvas(container, { scale: 3 });
  520. const img = canvas.toDataURL('image/jpeg', 1.0);
  521. // 创建一个图片元素并设置src属性为转换后的图片数据
  522. vueflowimg.value=img
  523. if(vueflowimg.value!=''){
  524. console.log("进入了")
  525. addflow();
  526. }
  527. // 添加到DOM中或者做其他操作
  528. } catch (error) {
  529. console.error('转换出错:', error);
  530. }
  531. }
  532. //添加接口
  533. const addflow = () => {
  534. const savedObj = JSON.parse(sessionStorage.getItem("objlist"));
  535. const stypeValue = savedObj ? savedObj.stype : '';
  536. console.log(stypeValue);
  537. const params = {
  538. transCode: 'MDO0002',
  539. pid: pid.value,
  540. name: newobj.value.name,
  541. remark:newobj.value.description,
  542. image:vueflowimg.value,
  543. isshare:'1',
  544. flow:mergedObj.value ,
  545. stype:stypeValue,
  546. }
  547. console.log(params);
  548. request(params)
  549. .then((res) => {
  550. console.log(res);
  551. ElMessage({
  552. message: res.returnMsg,
  553. type: 'success',
  554. })
  555. })
  556. .catch((err) => {
  557. ElMessage.error(err.returnMsg)
  558. })
  559. }
  560. /**
  561. * Resets the current viewport transformation (zoom & pan)
  562. */
  563. function resetTransform() {
  564. setViewport({ x: 0, y: 0, zoom: 1 })
  565. }
  566. function toggleDarkMode() {
  567. dark.value = !dark.value;
  568. if(dark.value){
  569. iconcolor.value='#fff'
  570. }else{
  571. iconcolor.value='#000'
  572. }
  573. }
  574. onMounted(() => {
  575. setTimeout(function() {
  576. getroter();
  577. }, 1500);
  578. // childfun();
  579. });
  580. // 获取链接
  581. const getroter=()=>{
  582. //datatree.value[0].children=[];
  583. let objlist=JSON.parse(sessionStorage.getItem("objlist"));
  584. if(objlist.flow!=''){
  585. let nodesflow=JSON.parse(objlist.flow)
  586. nodes.value=nodesflow.nodes;
  587. edges.value=nodesflow.edges;
  588. }
  589. newobj.value.name=objlist.name;
  590. newobj.value.description=objlist.remark;
  591. pid.value=objlist.pid;
  592. // let item={
  593. // id:'1-0',
  594. // label: objlist.name,
  595. // img:r2,
  596. // }
  597. // console.log( datatree.value[0].children);
  598. // datatree.value[0].children.push(item);
  599. }
  600. //改变线的粗
  601. const linestrokeWidth=(num)=>{
  602. if(seledge.value){
  603. seledge.value.style.strokeWidth = num;
  604. }
  605. linenum.value=num;
  606. // console.log(seledge.value);
  607. // let edgearr= toObject().edges;
  608. // for (let i = 0; i <= edgearr.length-1; i++) {
  609. // edgearr[i].style.strokeWidth = num;
  610. // }
  611. console.log(num)
  612. //addEdges(edgearr);
  613. }
  614. //改变线的颜色
  615. const changeAllEdgesColor = (color1) => {
  616. console.log('yanse:', color1);
  617. linecolor.value = color1;
  618. // 找到当前选中的边缘
  619. if (seledge.value) {
  620. // 更新该边缘的颜色,不修改宽度
  621. const updatedEdge = {
  622. ...seledge.value,
  623. style: {
  624. ...seledge.value.style,
  625. stroke: linecolor.value, // 只修改颜色
  626. strokeWidth: 1, // 保持选中样式的宽度(如果想要恢复原始宽度,设置为 1)
  627. }
  628. };
  629. // 更新 edges 数组
  630. const updatedEdges = edges.value.map(edge =>
  631. edge.id === seledge.value.id ? updatedEdge : edge
  632. );
  633. edges.value = updatedEdges; // 持久化修改后的边缘
  634. }
  635. };
  636. watch(() => seledge.value, (newItems, oldItems) => {
  637. if(seledge.value!=null){
  638. // seledge.value.style.stroke = linecolor.value;
  639. }
  640. });
  641. defineExpose({changeAllEdgesColor,linestrokeWidth,getroter,onSelection,bgcolorfunc});
  642. </script>
  643. <style>
  644. /* .vue-flow__edge.selected .vue-flow__edge-path, .vue-flow__edge:focus .vue-flow__edge-path, .vue-flow__edge:focus-visible .vue-flow__edge-path {
  645. stroke: #555 !important;
  646. } */
  647. .vue-flow__edge:focus .vue-flow__edge-path, .vue-flow__edge:focus-visible .vue-flow__edge-path {
  648. stroke: #555 !important;
  649. }
  650. .vue-flow__edge {
  651. text-align: left;
  652. /* 设置edges的左对齐 */
  653. }
  654. .edge-label {
  655. position: absolute;
  656. background-color: rgba(0, 0, 0, 0.6);
  657. color: white;
  658. padding: 5px;
  659. border-radius: 4px;
  660. font-size: 14px;
  661. white-space: pre-line; /* 保证文本支持换行 */
  662. }
  663. .edge-label-line {
  664. margin-bottom: 4px; /* 控制每行的间距 */
  665. }
  666. #contextMenu {
  667. display: none;
  668. position: absolute;
  669. background-color: #fff;
  670. border-radius: 5px;
  671. padding: 10px;
  672. text-align: center;
  673. color: black;
  674. font-size: 14px;
  675. font-weight: 400;
  676. cursor: pointer;
  677. z-index: 99999;
  678. }
  679. .vue-flow__node-default.selectable:hover,
  680. .vue-flow__node-input.selectable:hover,
  681. .vue-flow__node-output.selectable:hover {
  682. box-shadow: none;
  683. }
  684. panel {
  685. cursor: pointer;
  686. position: absolute;
  687. z-index: 100000;
  688. }
  689. .remove {
  690. background: #fff;
  691. color: #666;
  692. margin: 0 10px;
  693. font-size: 12px;
  694. }
  695. .vue-flow__node-default, .vue-flow__node-input, .vue-flow__node-output{
  696. /* width: auto !important; */
  697. border: none;
  698. background-color: rgba(0,0,0,0);
  699. }
  700. .node-content {
  701. cursor: move; /* 更改鼠标光标表示可拖动 */
  702. }
  703. .vue-flow__node {
  704. cursor: move;
  705. }
  706. /* 禁用文本选中效果 */
  707. .left_main * {
  708. -webkit-user-select: none; /* Safari */
  709. -moz-user-select: none; /* Firefox */
  710. -ms-user-select: none; /* IE10+/Edge */
  711. user-select: none; /* Standard syntax */
  712. }
  713. .lableaniu{
  714. font-size: 12px;
  715. background-color: #ddd;
  716. padding: 4px 16px;
  717. /* margin-top: -17px; */
  718. margin-left: 5px;
  719. margin-top: 0px;
  720. border-radius: 1px;
  721. }
  722. .vue-flow__controls-button svg{
  723. max-width: 16px;
  724. max-height: 16px;
  725. }
  726. .field{
  727. display: flex;
  728. }
  729. .node-label, .edge-label,.custom-node span {
  730. text-transform: none; /* 确保文本不转换为大写 */
  731. font-family: 'Inter-Regular';
  732. }
  733. </style>