index.vue 21 KB

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