|
@@ -1,45 +1,32 @@
|
|
|
<template>
|
|
|
-
|
|
|
- <VueFlow
|
|
|
- ref="vueFlowRef"
|
|
|
- :nodes="nodes"
|
|
|
- :edges="edges"
|
|
|
- :edgeTypes="edgeTypes.smoothstep"
|
|
|
- :class="{ dark }"
|
|
|
- class="basic-flow"
|
|
|
- :default-viewport="{ zoom: 1.5 }"
|
|
|
- :min-zoom="0.2"
|
|
|
- :max-zoom="4"
|
|
|
- @drop="onDrop"
|
|
|
- @contextmenu.prevent="onContextMenu"
|
|
|
- @node-contextmenu="logEvent('contextmenu', $event)"
|
|
|
- @keydown.delete="onDeleteKey"
|
|
|
- @dragover="onDragOver"
|
|
|
- @dragleave="onDragLeave"
|
|
|
- @edge-click="onEdgeClick"
|
|
|
- @node-click="onNodeClick">
|
|
|
- <template #node-default="props">
|
|
|
+ <VueFlow ref="vueFlowRef" :nodes="nodes" :edges="edges" :class="{ dark }"
|
|
|
+ class="basic-flow"
|
|
|
+ :default-viewport="{ zoom: 1.5 }" :min-zoom="0.2" :max-zoom="4" @drop="onDrop"
|
|
|
+ @contextmenu.prevent="onContextMenu" @node-contextmenu="logEvent('contextmenu', $event)"
|
|
|
+ @dragover="onDragOver" @dragleave="onDragLeave" @edge-click="onEdgeClick" @node-click="onNodeClick">
|
|
|
+ <template #node-default="props">
|
|
|
<!-- <template #node-process="props"> // @contextmenu.prevent="onContextMenu" -->
|
|
|
- <eltree :node="props" />
|
|
|
- </template>
|
|
|
-
|
|
|
- <Background pattern-color="#aaa" :gap="16" />
|
|
|
+ <eltree :node="props" />
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <Background pattern-color="#aaa" :gap="16" />
|
|
|
|
|
|
<!-- <MiniMap /> -->
|
|
|
<Panel>
|
|
|
- <div>
|
|
|
- <button class="remove" @click="removeNode(event)">删除节点</button>
|
|
|
- <button class="remove" @click="removeEdge(event)">删除线</button>
|
|
|
- </div>
|
|
|
+ <div>
|
|
|
+ <button class="remove" @click="removeNode(event)">删除节点</button>
|
|
|
+ <button class="remove" @click="removeEdge(event)">删除线</button>
|
|
|
+ <!-- <button class="remove" @click="getnodes()">获取所有数据</button> -->
|
|
|
+ </div>
|
|
|
</Panel>
|
|
|
<Controls position="top-left">
|
|
|
<ControlButton title="Reset Transform" @click="resetTransform">
|
|
|
<Icon name="reset" />
|
|
|
</ControlButton>
|
|
|
|
|
|
- <ControlButton title="Shuffle Node Positions" @click="updatePos">
|
|
|
+ <!-- <ControlButton title="Shuffle Node Positions" @click="updatePos">
|
|
|
<Icon name="update" />
|
|
|
- </ControlButton>
|
|
|
+ </ControlButton> -->
|
|
|
|
|
|
<ControlButton title="Toggle Dark Mode" @click="toggleDarkMode">
|
|
|
<Icon v-if="dark" name="sun" />
|
|
@@ -50,132 +37,105 @@
|
|
|
<Icon name="log" />
|
|
|
</ControlButton>
|
|
|
</Controls>
|
|
|
-
|
|
|
+
|
|
|
</VueFlow>
|
|
|
- <div class="dnd-flow" >
|
|
|
-
|
|
|
- <div id="contextMenu" @click="deleteItemConfirm">删除</div>
|
|
|
-
|
|
|
-
|
|
|
- </div>
|
|
|
+ <div class="dnd-flow">
|
|
|
+
|
|
|
+ <div id="contextMenu" @click="deleteItemConfirm">删除</div>
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
</template>
|
|
|
<script setup>
|
|
|
-import { ref,markRaw } from 'vue'
|
|
|
-import { VueFlow, useVueFlow,MarkerType } from '@vue-flow/core'
|
|
|
+import { ref, markRaw } from 'vue'
|
|
|
+import { VueFlow, useVueFlow, MarkerType } from '@vue-flow/core'
|
|
|
+import { useRoute } from 'vue-router';
|
|
|
import { Background } from '@vue-flow/background'
|
|
|
import { ControlButton, Controls } from '@vue-flow/controls'
|
|
|
+import { initialEdges, initialNodes } from './modeljs.js'
|
|
|
import { MiniMap } from '@vue-flow/minimap'
|
|
|
import "./main.css";//重置样式
|
|
|
- import DropzoneBackground from './DropzoneBackground.vue'
|
|
|
- import eltree from './eltree.vue'
|
|
|
- import useDragAndDrop from './useDnD'
|
|
|
- import f11 from '@/assets/img/f11.png'
|
|
|
- import { initialEdges, initialNodes } from './initial-elements.js'
|
|
|
+import DropzoneBackground from './DropzoneBackground.vue'
|
|
|
+import eltree from './eltree.vue'
|
|
|
+import useDragAndDrop from './useDnD'
|
|
|
+import f11 from '@/assets/img/f11.png'
|
|
|
import Icon from './Icon.vue'
|
|
|
-
|
|
|
-/**
|
|
|
- * `useVueFlow` provides:
|
|
|
- * 1. a set of methods to interact with the VueFlow instance (like `fitView`, `setViewport`, `addEdges`, etc)
|
|
|
- * 2. a set of event-hooks to listen to VueFlow events (like `onInit`, `onNodeDragStop`, `onConnect`, etc)
|
|
|
- * 3. the internal state of the VueFlow instance (like `nodes`, `edges`, `viewport`, etc)
|
|
|
- */
|
|
|
-// our dark mode toggle flag
|
|
|
const dark = ref(false)
|
|
|
-const { onInit, onNodeDragStop,onNodeContextMenu, onConnect, addEdges, setViewport, toObject } = useVueFlow()
|
|
|
- let vueFlowRef=ref();
|
|
|
- const edgeTypes = {
|
|
|
- smoothstep: markRaw(eltree),
|
|
|
-}
|
|
|
- let emit = defineEmits(['optimizerfalse']);
|
|
|
- const props = defineProps({
|
|
|
-
|
|
|
- optimizer: {
|
|
|
+const route = useRoute();
|
|
|
+const { onInit, onNodeDragStop, onNodeContextMenu, onConnect, addEdges, setViewport, toObject } = useVueFlow()
|
|
|
+let vueFlowRef = ref();
|
|
|
+let emit = defineEmits(['optimizerfalse']);
|
|
|
+const props = defineProps({
|
|
|
+
|
|
|
+ optimizer: {
|
|
|
type: Boolean,
|
|
|
},
|
|
|
- })
|
|
|
- const shopShow=ref(false);
|
|
|
- let noid=ref([]);
|
|
|
- let Edgeid=ref();
|
|
|
- let node=ref();
|
|
|
- let contextMenu=ref( {
|
|
|
- position: { x: 0, y: 0 },
|
|
|
- target: 'kong',
|
|
|
- })
|
|
|
- const { onDragOver, onDrop, onDragLeave, isDragOver} = useDragAndDrop();
|
|
|
- const edges = ref([]);
|
|
|
- const nodes = ref([]);
|
|
|
- // function onConnect(params){
|
|
|
- // // 更改连线类型
|
|
|
- // console.log(params)
|
|
|
- // // params.type = 'custom';
|
|
|
- // // ...其他连线逻辑
|
|
|
- // }
|
|
|
- onConnect((connection) => {
|
|
|
- console.log(connection);
|
|
|
- connection.type = 'smoothstep';
|
|
|
- connection.markerEnd = MarkerType.ArrowClosed;
|
|
|
+})
|
|
|
|
|
|
-
|
|
|
+const shopShow = ref(false);
|
|
|
+let noid = ref([]);
|
|
|
+let Edgeid = ref();
|
|
|
+let node = ref();
|
|
|
+let contextMenu = ref({
|
|
|
+ position: { x: 0, y: 0 },
|
|
|
+ target: 'kong',
|
|
|
+})
|
|
|
+const { onDragOver, onDrop, onDragLeave, isDragOver } = useDragAndDrop();
|
|
|
+const edges = ref([]);
|
|
|
+const nodes = ref([]);
|
|
|
+onConnect((connection) => {
|
|
|
+ console.log(connection);
|
|
|
+ connection.type = 'smoothstep';// smoothstep straight
|
|
|
+ connection.markerEnd = MarkerType.ArrowClosed;
|
|
|
addEdges(connection)
|
|
|
})
|
|
|
- function onNodeClick(e){
|
|
|
- noid.value=e.node;
|
|
|
- if(e.node.data.label=='优化器'){
|
|
|
- console.log(e.node);
|
|
|
- emit('optimizerfalse', true);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- // 监听线
|
|
|
- function onEdgeClick(e){
|
|
|
- console.log(e.edge.id);
|
|
|
- Edgeid.value=e.edge.id;
|
|
|
- //console.log(999000)
|
|
|
+function onNodeClick(e) {
|
|
|
+ noid.value = e.node;
|
|
|
+ if (e.node.data.label == '优化器') {
|
|
|
+ console.log(e.node);
|
|
|
+ emit('optimizerfalse', true);
|
|
|
}
|
|
|
- function logEvent(name,event){
|
|
|
-console.log(2222)
|
|
|
- }
|
|
|
- function onContextMenu(event){
|
|
|
- console.log(1111)
|
|
|
- console.log(event);
|
|
|
- if(noid.value!==null){
|
|
|
- if (noid.value.id) {
|
|
|
- console.log(noid.value.position.y);
|
|
|
- console.log(noid.value.position.x);
|
|
|
- document.getElementById('contextMenu').style.top = noid.value.position.y+100 + 'px';
|
|
|
- document.getElementById('contextMenu').style.left = noid.value.position.x +270+ 'px';
|
|
|
- document.getElementById('contextMenu').style.display = 'block';
|
|
|
- event.preventDefault();
|
|
|
+
|
|
|
+}
|
|
|
+// 监听线
|
|
|
+function onEdgeClick(e) {
|
|
|
+ Edgeid.value = e.edge.id;
|
|
|
+}
|
|
|
+function logEvent(name, event) {
|
|
|
+ console.log(2222)
|
|
|
+}
|
|
|
+function onContextMenu(event) {
|
|
|
+ if (noid.value !== null) {
|
|
|
+ if (noid.value.id) {
|
|
|
+ console.log(noid.value.position.y);
|
|
|
+ console.log(noid.value.position.x);
|
|
|
+ document.getElementById('contextMenu').style.top = noid.value.position.y + 100 + 'px';
|
|
|
+ document.getElementById('contextMenu').style.left = noid.value.position.x + 270 + 'px';
|
|
|
+ document.getElementById('contextMenu').style.display = 'block';
|
|
|
+ event.preventDefault();
|
|
|
//shopShow.value=true;
|
|
|
- // document.getElementById('contextMenu').style.display = 'none';
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- //点击左键右键内容消失
|
|
|
- document.addEventListener('click', function(e) {
|
|
|
- if (e.button === 0) { // 0 是左键
|
|
|
- document.getElementById('contextMenu').style.display = 'none';
|
|
|
- // shopShow.value=false;
|
|
|
+ // document.getElementById('contextMenu').style.display = 'none';
|
|
|
}
|
|
|
- });
|
|
|
- function onDeleteKey(event,node) {
|
|
|
- // 禁用Backspace删除节点
|
|
|
- console.log(event)
|
|
|
- event.preventDefault();
|
|
|
-
|
|
|
- }
|
|
|
- //删除
|
|
|
- const deleteItemConfirm=()=>{
|
|
|
- if(noid.value.id){
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+//点击左键右键内容消失
|
|
|
+document.addEventListener('click', function (e) {
|
|
|
+ if (e.button === 0) { // 0 是左键
|
|
|
+ document.getElementById('contextMenu').style.display = 'none';
|
|
|
+ // shopShow.value=false;
|
|
|
+ }
|
|
|
+});
|
|
|
+//删除
|
|
|
+const deleteItemConfirm = () => {
|
|
|
+ if (noid.value.id) {
|
|
|
vueFlowRef.value.removeNodes(noid.value.id);
|
|
|
- noid.value=null;
|
|
|
+ noid.value = null;
|
|
|
document.getElementById('contextMenu').style.display = 'none';
|
|
|
- }
|
|
|
-
|
|
|
}
|
|
|
+
|
|
|
+}
|
|
|
onInit((vueFlowInstance) => {
|
|
|
- // instance is the same as the return of `useVueFlow`
|
|
|
vueFlowInstance.fitView()
|
|
|
})
|
|
|
|
|
@@ -188,7 +148,6 @@ onConnect((connection) => {
|
|
|
console.log(1111);
|
|
|
console.log(edges.value);
|
|
|
})
|
|
|
-
|
|
|
function updatePos() {
|
|
|
nodes.value = nodes.value.map((node) => {
|
|
|
return {
|
|
@@ -201,11 +160,11 @@ function updatePos() {
|
|
|
})
|
|
|
}
|
|
|
function removeEdge(id) {
|
|
|
-id= Edgeid.value;
|
|
|
-vueFlowRef.value.removeEdges(id);
|
|
|
+ id = Edgeid.value;
|
|
|
+ vueFlowRef.value.removeEdges(id);
|
|
|
}
|
|
|
function removeNode(id) {
|
|
|
- id= noid.value.id
|
|
|
+ id = noid.value.id
|
|
|
vueFlowRef.value.removeNodes(noid.value.id);
|
|
|
}
|
|
|
function logToObject() {
|
|
@@ -222,19 +181,32 @@ function resetTransform() {
|
|
|
function toggleDarkMode() {
|
|
|
dark.value = !dark.value
|
|
|
}
|
|
|
-// 点击右键显示
|
|
|
-// function contextmenuclick(e){
|
|
|
-// console.log(e)
|
|
|
-// }
|
|
|
+onMounted(() => {
|
|
|
+ getroter();
|
|
|
+ // childfun();
|
|
|
+
|
|
|
+});
|
|
|
+// 获取链接
|
|
|
+const getroter=()=>{
|
|
|
+ console.log(11111)
|
|
|
+ console.log(route.query);
|
|
|
+ if(route.query.id=='0'){
|
|
|
+ console.log(route.query);
|
|
|
+ nodes.value=initialNodes;
|
|
|
+ edges.value=initialEdges;
|
|
|
+ }
|
|
|
+}
|
|
|
</script>
|
|
|
|
|
|
<style>
|
|
|
- .vue-flow__edge {
|
|
|
- text-align: left; /* 设置edges的左对齐 */
|
|
|
- }
|
|
|
- #contextMenu{
|
|
|
- display: none;
|
|
|
- position: absolute;
|
|
|
+.vue-flow__edge {
|
|
|
+ text-align: left;
|
|
|
+ /* 设置edges的左对齐 */
|
|
|
+}
|
|
|
+
|
|
|
+#contextMenu {
|
|
|
+ display: none;
|
|
|
+ position: absolute;
|
|
|
background-color: #fff;
|
|
|
border-radius: 5px;
|
|
|
padding: 10px;
|
|
@@ -244,22 +216,28 @@ function toggleDarkMode() {
|
|
|
font-weight: 400;
|
|
|
cursor: pointer;
|
|
|
z-index: 99999;
|
|
|
- }
|
|
|
- .vue-flow__node-default.selected, .vue-flow__node-default.selected:hover, .vue-flow__node-input.selected, .vue-flow__node-input.selected:hover, .vue-flow__node-output.selected, .vue-flow__node-output.selected:hover{
|
|
|
- /* // box-shadow: none; */
|
|
|
- }
|
|
|
- .vue-flow__node-default.selectable:hover, .vue-flow__node-input.selectable:hover, .vue-flow__node-output.selectable:hover{
|
|
|
- box-shadow: none;
|
|
|
- }
|
|
|
- panel{
|
|
|
- cursor: pointer;
|
|
|
- position: absolute;
|
|
|
- z-index: 100000;
|
|
|
- }
|
|
|
- .remove{
|
|
|
- background: #fff;
|
|
|
- color: #666;
|
|
|
- margin: 0 10px;
|
|
|
- font-size: 12px;
|
|
|
- }
|
|
|
+}
|
|
|
+.vue-flow__node-default.selectable:hover,
|
|
|
+.vue-flow__node-input.selectable:hover,
|
|
|
+.vue-flow__node-output.selectable:hover {
|
|
|
+ box-shadow: none;
|
|
|
+}
|
|
|
+
|
|
|
+panel {
|
|
|
+ cursor: pointer;
|
|
|
+ position: absolute;
|
|
|
+ z-index: 100000;
|
|
|
+}
|
|
|
+
|
|
|
+.remove {
|
|
|
+ background: #fff;
|
|
|
+ color: #666;
|
|
|
+ margin: 0 10px;
|
|
|
+ font-size: 12px;
|
|
|
+}
|
|
|
+.vue-flow__node-default, .vue-flow__node-input, .vue-flow__node-output{
|
|
|
+ width: auto !important;
|
|
|
+ border: none;
|
|
|
+ background-color: rgba(0,0,0,0);
|
|
|
+}
|
|
|
</style>
|