docs: update examples
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Background, Controls, MiniMap } from '@vue-flow/additional-components'
|
import { Background, Controls, MiniMap, Panel, PanelPosition } from '@vue-flow/additional-components'
|
||||||
import { VueFlow, isNode, useVueFlow } from '@vue-flow/core'
|
import { VueFlow, isNode, useVueFlow } from '@vue-flow/core'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { initialElements } from './initial-elements.js'
|
import { initialElements } from './initial-elements.js'
|
||||||
@@ -58,28 +58,62 @@ const logToObject = () => console.log(toObject())
|
|||||||
*/
|
*/
|
||||||
const resetTransform = () => setTransform({ x: 0, y: 0, zoom: 1 })
|
const resetTransform = () => setTransform({ x: 0, y: 0, zoom: 1 })
|
||||||
|
|
||||||
const toggleClass = () => {
|
const toggleClass = () => (dark.value = !dark.value)
|
||||||
dark.value = !dark.value
|
|
||||||
elements.value.forEach((el) => (el.class = dark.value ? 'dark' : 'light'))
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow v-model="elements" class="basicflow" :default-zoom="1.5" :min-zoom="0.2" :max-zoom="4">
|
<VueFlow v-model="elements" :class="{ dark }" class="basicflow" :default-zoom="1.5" :min-zoom="0.2" :max-zoom="4">
|
||||||
<Background pattern-color="#aaa" gap="8" />
|
<Background :pattern-color="dark ? '#FFFFFB' : '#aaa'" gap="8" />
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
<Controls />
|
<Controls />
|
||||||
|
|
||||||
<div class="controls">
|
<Panel :position="PanelPosition.TopRight" class="controls">
|
||||||
<button style="background-color: #113285; color: white" @click="resetTransform">reset transform</button>
|
<button style="background-color: #113285; color: white" title="Reset Transform" @click="resetTransform">
|
||||||
<button style="background-color: #6f3381; color: white" @click="updatePos">update positions</button>
|
<svg width="16" height="16" viewBox="0 0 32 32">
|
||||||
|
<path fill="#FFFFFB" d="M18 28A12 12 0 1 0 6 16v6.2l-3.6-3.6L1 20l6 6l6-6l-1.4-1.4L8 22.2V16a10 10 0 1 1 10 10Z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button style="background-color: #6f3381" title="Shuffle Node Positions" @click="updatePos">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
fill="#FFFFFB"
|
||||||
|
d="M14 20v-2h2.6l-3.2-3.2l1.425-1.425L18 16.55V14h2v6Zm-8.6 0L4 18.6L16.6 6H14V4h6v6h-2V7.4Zm3.775-9.425L4 5.4L5.4 4l5.175 5.175Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
:style="{ backgroundColor: dark ? '#FFFFFB' : '#1C1C1C', color: dark ? '#1C1C1C' : '#FFFFFB' }"
|
:style="{ backgroundColor: dark ? '#FFFFFB' : '#292524', color: dark ? '#292524' : '#FFFFFB' }"
|
||||||
@click="toggleClass"
|
@click="toggleClass"
|
||||||
>
|
>
|
||||||
toggle {{ dark ? 'light' : 'dark' }}
|
<template v-if="dark">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
fill="#292524"
|
||||||
|
d="M12 17q-2.075 0-3.537-1.463Q7 14.075 7 12t1.463-3.538Q9.925 7 12 7t3.538 1.462Q17 9.925 17 12q0 2.075-1.462 3.537Q14.075 17 12 17ZM2 13q-.425 0-.712-.288Q1 12.425 1 12t.288-.713Q1.575 11 2 11h2q.425 0 .713.287Q5 11.575 5 12t-.287.712Q4.425 13 4 13Zm18 0q-.425 0-.712-.288Q19 12.425 19 12t.288-.713Q19.575 11 20 11h2q.425 0 .712.287q.288.288.288.713t-.288.712Q22.425 13 22 13Zm-8-8q-.425 0-.712-.288Q11 4.425 11 4V2q0-.425.288-.713Q11.575 1 12 1t.713.287Q13 1.575 13 2v2q0 .425-.287.712Q12.425 5 12 5Zm0 18q-.425 0-.712-.288Q11 22.425 11 22v-2q0-.425.288-.712Q11.575 19 12 19t.713.288Q13 19.575 13 20v2q0 .425-.287.712Q12.425 23 12 23ZM5.65 7.05L4.575 6q-.3-.275-.288-.7q.013-.425.288-.725q.3-.3.725-.3t.7.3L7.05 5.65q.275.3.275.7q0 .4-.275.7q-.275.3-.687.287q-.413-.012-.713-.287ZM18 19.425l-1.05-1.075q-.275-.3-.275-.712q0-.413.275-.688q.275-.3.688-.287q.412.012.712.287L19.425 18q.3.275.288.7q-.013.425-.288.725q-.3.3-.725.3t-.7-.3ZM16.95 7.05q-.3-.275-.287-.688q.012-.412.287-.712L18 4.575q.275-.3.7-.288q.425.013.725.288q.3.3.3.725t-.3.7L18.35 7.05q-.3.275-.7.275q-.4 0-.7-.275ZM4.575 19.425q-.3-.3-.3-.725t.3-.7l1.075-1.05q.3-.275.713-.275q.412 0 .687.275q.3.275.288.688q-.013.412-.288.712L6 19.425q-.275.3-.7.287q-.425-.012-.725-.287Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
fill="#FFFFFB"
|
||||||
|
d="M12 21q-3.75 0-6.375-2.625T3 12q0-3.75 2.625-6.375T12 3q.35 0 .688.025q.337.025.662.075q-1.025.725-1.637 1.887Q11.1 6.15 11.1 7.5q0 2.25 1.575 3.825Q14.25 12.9 16.5 12.9q1.375 0 2.525-.613q1.15-.612 1.875-1.637q.05.325.075.662Q21 11.65 21 12q0 3.75-2.625 6.375T12 21Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
</button>
|
</button>
|
||||||
<button @click="logToObject">log toObject</button>
|
|
||||||
</div>
|
<button title="Log `toObject`" @click="logToObject">
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24">
|
||||||
|
<path
|
||||||
|
fill="#292524"
|
||||||
|
d="M20 19V7H4v12h16m0-16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16m-7 14v-2h5v2h-5m-3.42-4L5.57 9H8.4l3.3 3.3c.39.39.39 1.03 0 1.42L8.42 17H5.59l3.99-4Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</Panel>
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import { MarkerType } from '@vue-flow/core'
|
|||||||
* or split them up into nodes and edges and pass them to the `nodes` and `edges` props of Vue Flow (or useVueFlow composable)
|
* or split them up into nodes and edges and pass them to the `nodes` and `edges` props of Vue Flow (or useVueFlow composable)
|
||||||
*/
|
*/
|
||||||
export const initialElements = [
|
export const initialElements = [
|
||||||
{ id: '1', type: 'input', label: 'Node 1', position: { x: 250, y: 5 }, class: 'light' },
|
{ id: '1', type: 'input', label: 'Node 1', position: { x: 250, y: 0 }, class: 'light' },
|
||||||
{ id: '2', type: 'output', label: 'Node 2', position: { x: 100, y: 100 }, class: 'light' },
|
{ id: '2', type: 'output', label: 'Node 2', position: { x: 100, y: 100 }, class: 'light' },
|
||||||
{ id: '3', label: 'Node 3', position: { x: 400, y: 100 }, class: 'light' },
|
{ id: '3', label: 'Node 3', position: { x: 400, y: 100 }, class: 'light' },
|
||||||
{ id: '4', label: 'Node 4', position: { x: 150, y: 200 }, class: 'light' },
|
{ id: '4', label: 'Node 4', position: { x: 150, y: 200 }, class: 'light' },
|
||||||
{ id: '5', type: 'output', label: 'Node 5', position: { x: 300, y: 300 }, class: 'light' },
|
{ id: '5', type: 'output', label: 'Node 5', position: { x: 300, y: 300 }, class: 'light' },
|
||||||
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
{ id: 'e1-2', source: '1', target: '2', animated: true },
|
||||||
{ id: 'e1-3', label: 'edge with arrowhead', source: '1', target: '3', markerEnd: MarkerType.Arrow },
|
{ id: 'e1-3', label: 'edge with arrowhead', source: '1', target: '3', markerEnd: MarkerType.ArrowClosed },
|
||||||
{
|
{
|
||||||
id: 'e4-5',
|
id: 'e4-5',
|
||||||
type: 'step',
|
type: 'step',
|
||||||
@@ -19,7 +19,6 @@ export const initialElements = [
|
|||||||
source: '4',
|
source: '4',
|
||||||
target: '5',
|
target: '5',
|
||||||
style: { stroke: 'orange' },
|
style: { stroke: 'orange' },
|
||||||
labelStyle: { stroke: 'black' },
|
|
||||||
labelBgStyle: { fill: 'orange' },
|
labelBgStyle: { fill: 'orange' },
|
||||||
},
|
},
|
||||||
{ id: 'e3-4', type: 'smoothstep', label: 'smoothstep-edge', source: '3', target: '4' },
|
{ id: 'e3-4', type: 'smoothstep', label: 'smoothstep-edge', source: '3', target: '4' },
|
||||||
|
|||||||
@@ -1,13 +1,28 @@
|
|||||||
.basicflow .vue-flow__node.dark {
|
.basicflow.dark {
|
||||||
background: #1C1C1C;
|
background: #57534e;
|
||||||
color: #FFFFFB;
|
color: #FFFFFB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.basicflow.dark .vue-flow__node {
|
||||||
|
background: #292524;
|
||||||
|
color: #FFFFFB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.basicflow.dark .vue-flow__controls .vue-flow__controls-button {
|
||||||
|
background: #292524;
|
||||||
|
fill: #FFFFFB;
|
||||||
|
border-color: #FFFFFB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.basicflow.dark .vue-flow__edge-textbg {
|
||||||
|
fill: #292524;
|
||||||
|
}
|
||||||
|
|
||||||
|
.basicflow.dark .vue-flow__edge-text {
|
||||||
|
fill: #FFFFFB;
|
||||||
|
}
|
||||||
|
|
||||||
.basicflow .controls {
|
.basicflow .controls {
|
||||||
position: absolute;
|
|
||||||
left: 10px;
|
|
||||||
top: 10px;
|
|
||||||
z-index: 4;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -15,16 +30,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.basicflow .controls button {
|
.basicflow .controls button {
|
||||||
padding: 5px;
|
padding: 4px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
-webkit-box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.3);
|
-webkit-box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.3);
|
||||||
box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.3);
|
box-shadow: 0px 5px 10px 0px rgba(0, 0, 0, 0.3);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.basicflow .controls button:hover {
|
.basicflow .controls button:hover {
|
||||||
opacity: 0.8;
|
transform: scale(102%);
|
||||||
transform: scale(105%);
|
|
||||||
transition: 250ms all ease;
|
transition: 250ms all ease;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Background, BackgroundVariant, Controls, MiniMap } from '@vue-flow/additional-components'
|
|
||||||
import { VueFlow } from '@vue-flow/core'
|
import { VueFlow } from '@vue-flow/core'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import CustomConnectionLine from './CustomConnectionLine.vue'
|
import CustomConnectionLine from './CustomConnectionLine.vue'
|
||||||
@@ -16,10 +15,8 @@ const elements = ref([
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow v-model="elements">
|
<VueFlow v-model="elements">
|
||||||
<template #connection-line="props">
|
<template #connection-line="{ sourceX, sourceY, targetX, targetY }">
|
||||||
<CustomConnectionLine v-bind="props" />
|
<CustomConnectionLine :source-x="sourceX" :source-y="sourceY" :target-x="targetX" :target-y="targetY" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<Background :variant="BackgroundVariant.Lines" />
|
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ const props = defineProps({
|
|||||||
<template>
|
<template>
|
||||||
<g>
|
<g>
|
||||||
<path
|
<path
|
||||||
class="animated"
|
class="vue-flow__connection animated"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke="#6F3381"
|
stroke="#6F3381"
|
||||||
:stroke-width="2.5"
|
:stroke-width="2.5"
|
||||||
:d="`M${sourceX},${sourceY} C ${sourceX} ${targetY} ${sourceX} ${targetY} ${targetX},${targetY}`"
|
:d="`M${sourceX},${sourceY} C ${sourceX} ${targetY} ${sourceX} ${targetY} ${targetX},${targetY}`"
|
||||||
/>
|
/>
|
||||||
<circle :cx="targetX" :cy="targetY" fill="#fff" :r="5" stroke="#6F3381" :stroke-width="1.5" />
|
|
||||||
|
<circle :cx="targetX" :cy="targetY" fill="#fff" :r="4" stroke="#6F3381" :stroke-width="1.5" />
|
||||||
</g>
|
</g>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { MiniMap } from '@vue-flow/additional-components'
|
import { MiniMap } from '@vue-flow/additional-components'
|
||||||
import { ConnectionMode, Position, VueFlow, useVueFlow } from '@vue-flow/core'
|
import { Position, VueFlow, useVueFlow } from '@vue-flow/core'
|
||||||
import { computed, h, onMounted, ref } from 'vue'
|
import { h, onMounted, ref } from 'vue'
|
||||||
import ColorSelectorNode from './CustomNode.vue'
|
import ColorSelectorNode from './CustomNode.vue'
|
||||||
import { presets } from './presets.js'
|
import { presets } from './presets.js'
|
||||||
|
|
||||||
const { getNode } = useVueFlow()
|
const { findNode } = useVueFlow()
|
||||||
|
|
||||||
const outputColorNode = computed(() => getNode.value('3'))
|
|
||||||
|
|
||||||
const elements = ref([])
|
const elements = ref([])
|
||||||
|
|
||||||
const gradient = ref(false)
|
const gradient = ref(false)
|
||||||
|
|
||||||
const bgColor = ref(presets.ayame)
|
const bgColor = ref(presets.ayame)
|
||||||
|
|
||||||
const bgName = ref('AYAME')
|
const bgName = ref('AYAME')
|
||||||
|
|
||||||
const connectionLineStyle = { stroke: '#fff' }
|
const connectionLineStyle = { stroke: '#fff' }
|
||||||
@@ -39,7 +39,7 @@ const onChange = (color) => {
|
|||||||
bgColor.value = color.value
|
bgColor.value = color.value
|
||||||
bgName.value = color.name
|
bgName.value = color.name
|
||||||
|
|
||||||
outputColorNode.value.hidden = false
|
findNode('3').hidden = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const onGradient = () => {
|
const onGradient = () => {
|
||||||
@@ -47,7 +47,7 @@ const onGradient = () => {
|
|||||||
bgColor.value = null
|
bgColor.value = null
|
||||||
bgName.value = 'gradient'
|
bgName.value = 'gradient'
|
||||||
|
|
||||||
outputColorNode.value.hidden = true
|
findNode('3').hidden = true
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -104,13 +104,12 @@ onMounted(() => {
|
|||||||
class="customnodeflow"
|
class="customnodeflow"
|
||||||
:class="[gradient ? 'animated-bg-gradient' : '']"
|
:class="[gradient ? 'animated-bg-gradient' : '']"
|
||||||
:style="{ backgroundColor: bgColor }"
|
:style="{ backgroundColor: bgColor }"
|
||||||
:connection-mode="ConnectionMode.Loose"
|
|
||||||
:connection-line-style="connectionLineStyle"
|
:connection-line-style="connectionLineStyle"
|
||||||
:default-zoom="1.5"
|
:default-zoom="1.5"
|
||||||
:fit-view-on-init="true"
|
fit-view-on-init
|
||||||
>
|
>
|
||||||
<template #node-custom="props">
|
<template #node-custom="{ data }">
|
||||||
<ColorSelectorNode :data="props.data" @change="onChange" @gradient="onGradient" />
|
<ColorSelectorNode :data="data" @change="onChange" @gradient="onGradient" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<MiniMap :node-stroke-color="nodeStroke" :node-color="nodeColor" />
|
<MiniMap :node-stroke-color="nodeStroke" :node-color="nodeColor" />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Handle, Position } from '@vue-flow/core'
|
import { Handle, Position } from '@vue-flow/core'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { presets } from './presets.js'
|
import { colors } from './presets.js'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
data: {
|
data: {
|
||||||
@@ -12,8 +12,6 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(['change', 'gradient'])
|
const emit = defineEmits(['change', 'gradient'])
|
||||||
|
|
||||||
const onConnect = (params) => console.log('handle onConnect', params)
|
|
||||||
|
|
||||||
const onSelect = (color) => {
|
const onSelect = (color) => {
|
||||||
emit('change', color)
|
emit('change', color)
|
||||||
}
|
}
|
||||||
@@ -22,20 +20,8 @@ const onGradient = () => {
|
|||||||
emit('gradient')
|
emit('gradient')
|
||||||
}
|
}
|
||||||
|
|
||||||
const colors = computed(() => {
|
|
||||||
return Object.keys(presets).map((color) => {
|
|
||||||
return {
|
|
||||||
name: color,
|
|
||||||
value: presets[color],
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const selectedColor = computed(() => {
|
|
||||||
return colors.value.find((color) => color.value === props.data.color)
|
|
||||||
})
|
|
||||||
|
|
||||||
const sourceHandleStyleA = computed(() => ({ backgroundColor: props.data.color, filter: 'invert(100%)', top: '10px' }))
|
const sourceHandleStyleA = computed(() => ({ backgroundColor: props.data.color, filter: 'invert(100%)', top: '10px' }))
|
||||||
|
|
||||||
const sourceHandleStyleB = computed(() => ({
|
const sourceHandleStyleB = computed(() => ({
|
||||||
backgroundColor: props.data.color,
|
backgroundColor: props.data.color,
|
||||||
filter: 'invert(100%)',
|
filter: 'invert(100%)',
|
||||||
@@ -46,14 +32,18 @@ const sourceHandleStyleB = computed(() => ({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>Select a color</div>
|
<div>Select a color</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
style="display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; max-width: 90%; margin: auto; gap: 3px"
|
style="display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center; max-width: 90%; margin: auto; gap: 3px"
|
||||||
>
|
>
|
||||||
<template v-for="color of colors" :key="color.name">
|
<template v-for="color of colors" :key="color.name">
|
||||||
<button :title="color.name" :style="{ backgroundColor: color.value }" type="button" @click="onSelect(color)"></button>
|
<button :title="color.name" :style="{ backgroundColor: color.value }" type="button" @click="onSelect(color)"></button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<button class="animated-bg-gradient" title="gradient" type="button" @click="onGradient"></button>
|
<button class="animated-bg-gradient" title="gradient" type="button" @click="onGradient"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Handle id="a" type="source" :position="Position.Right" :style="sourceHandleStyleA" />
|
<Handle id="a" type="source" :position="Position.Right" :style="sourceHandleStyleA" />
|
||||||
|
|
||||||
<Handle id="b" type="source" :position="Position.Right" :style="sourceHandleStyleB" />
|
<Handle id="b" type="source" :position="Position.Right" :style="sourceHandleStyleB" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -21,3 +21,10 @@ export const presets = {
|
|||||||
sakura: '#FEDFE1',
|
sakura: '#FEDFE1',
|
||||||
toki: '#EEA9A9',
|
toki: '#EEA9A9',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const colors = Object.keys(presets).map((color) => {
|
||||||
|
return {
|
||||||
|
name: color,
|
||||||
|
value: presets[color],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|||||||
@@ -15,8 +15,10 @@ const { onConnect, nodes, edges, addEdges, addNodes, viewport, project } = useVu
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
const onDragOver = (event) => {
|
const onDragOver = (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
if (event.dataTransfer) {
|
if (event.dataTransfer) {
|
||||||
event.dataTransfer.dropEffect = 'move'
|
event.dataTransfer.dropEffect = 'move'
|
||||||
}
|
}
|
||||||
@@ -26,13 +28,16 @@ onConnect((params) => addEdges([params]))
|
|||||||
|
|
||||||
const onDrop = (event) => {
|
const onDrop = (event) => {
|
||||||
const type = event.dataTransfer?.getData('application/vueflow')
|
const type = event.dataTransfer?.getData('application/vueflow')
|
||||||
|
|
||||||
const position = project({ x: event.clientX - 40, y: event.clientY - 18 })
|
const position = project({ x: event.clientX - 40, y: event.clientY - 18 })
|
||||||
|
|
||||||
const newNode = {
|
const newNode = {
|
||||||
id: getId(),
|
id: getId(),
|
||||||
type,
|
type,
|
||||||
position,
|
position,
|
||||||
label: `${type} node`,
|
label: `${type} node`,
|
||||||
}
|
}
|
||||||
|
|
||||||
addNodes([newNode])
|
addNodes([newNode])
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -40,6 +45,7 @@ const onDrop = (event) => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="dndflow" @drop="onDrop">
|
<div class="dndflow" @drop="onDrop">
|
||||||
<VueFlow @dragover="onDragOver" />
|
<VueFlow @dragover="onDragOver" />
|
||||||
|
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -10,9 +10,12 @@ const onDragStart = (event, nodeType) => {
|
|||||||
<template>
|
<template>
|
||||||
<aside>
|
<aside>
|
||||||
<div class="description">You can drag these nodes to the pane.</div>
|
<div class="description">You can drag these nodes to the pane.</div>
|
||||||
|
|
||||||
<div class="nodes">
|
<div class="nodes">
|
||||||
<div class="vue-flow__node-input" :draggable="true" @dragstart="onDragStart($event, 'input')">Input Node</div>
|
<div class="vue-flow__node-input" :draggable="true" @dragstart="onDragStart($event, 'input')">Input Node</div>
|
||||||
|
|
||||||
<div class="vue-flow__node-default" :draggable="true" @dragstart="onDragStart($event, 'default')">Default Node</div>
|
<div class="vue-flow__node-default" :draggable="true" @dragstart="onDragStart($event, 'default')">Default Node</div>
|
||||||
|
|
||||||
<div class="vue-flow__node-output" :draggable="true" @dragstart="onDragStart($event, 'output')">Output Node</div>
|
<div class="vue-flow__node-output" :draggable="true" @dragstart="onDragStart($event, 'output')">Output Node</div>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Background, Controls, MiniMap } from '@vue-flow/additional-components'
|
import { Background } from '@vue-flow/additional-components'
|
||||||
import { MarkerType, VueFlow } from '@vue-flow/core'
|
import { MarkerType, VueFlow } from '@vue-flow/core'
|
||||||
import { h, ref } from 'vue'
|
import { h, ref } from 'vue'
|
||||||
import CustomEdge from './CustomEdge.vue'
|
import CustomEdge from './CustomEdge.vue'
|
||||||
@@ -65,11 +65,11 @@ const elements = ref([
|
|||||||
<template #edge-custom="props">
|
<template #edge-custom="props">
|
||||||
<CustomEdge v-bind="props" />
|
<CustomEdge v-bind="props" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #edge-custom2="props">
|
<template #edge-custom2="props">
|
||||||
<CustomEdge2 v-bind="props" />
|
<CustomEdge2 v-bind="props" />
|
||||||
</template>
|
</template>
|
||||||
<MiniMap />
|
|
||||||
<Controls />
|
|
||||||
<Background />
|
<Background />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { EdgeLabelRenderer, getBezierPath, useVueFlow } from '@vue-flow/core'
|
import { BaseEdge, EdgeLabelRenderer, getBezierPath, useVueFlow } from '@vue-flow/core'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -57,7 +57,8 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<path :id="id" :style="style" class="vue-flow__edge-path" :d="path[0]" :marker-end="markerEnd" />
|
<!-- You can use the `BaseEdge` component to create your own custom edge more easily -->
|
||||||
|
<BaseEdge :id="id" :style="style" :path="path[0]" :marker-end="markerEnd" />
|
||||||
|
|
||||||
<!-- Use the `EdgeLabelRenderer` to escape the SVG world of edges and render your own custom label in a `<div>` ctx -->
|
<!-- Use the `EdgeLabelRenderer` to escape the SVG world of edges and render your own custom label in a `<div>` ctx -->
|
||||||
<EdgeLabelRenderer>
|
<EdgeLabelRenderer>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { EdgeText, getBezierPath } from '@vue-flow/core'
|
import { BaseEdge, getBezierPath } from '@vue-flow/core'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -63,12 +63,14 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<path :id="id" class="vue-flow__edge-path" :d="path[0]" :marker-end="markerEnd" />
|
<BaseEdge
|
||||||
|
:id="id"
|
||||||
<EdgeText
|
:style="style"
|
||||||
:x="path[1]"
|
:path="path[0]"
|
||||||
:y="path[2]"
|
:marker-end="markerEnd"
|
||||||
:label="data.text"
|
:label="data.text"
|
||||||
|
:label-x="path[1]"
|
||||||
|
:label-y="path[2]"
|
||||||
:label-style="{ fill: 'white' }"
|
:label-style="{ fill: 'white' }"
|
||||||
:label-show-bg="true"
|
:label-show-bg="true"
|
||||||
:label-bg-style="{ fill: 'red' }"
|
:label-bg-style="{ fill: 'red' }"
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Background, BackgroundVariant, Controls, MiniMap } from '@vue-flow/additional-components'
|
import { Background, BackgroundVariant, MiniMap, Panel, PanelPosition } from '@vue-flow/additional-components'
|
||||||
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
||||||
|
|
||||||
const { nodes, addNodes, edges, addEdges, onConnect, onPaneReady, onNodeDragStop, dimensions } = useVueFlow()
|
const { nodes, addNodes, edges, addEdges, onConnect, onPaneReady, onNodeDragStop, dimensions } = useVueFlow()
|
||||||
|
|
||||||
onConnect((params) => addEdges([params]))
|
onConnect((params) => addEdges([params]))
|
||||||
onPaneReady((flowInstance) => console.log('flow loaded:', flowInstance))
|
|
||||||
onNodeDragStop((node) => console.log('drag stop', node))
|
|
||||||
|
|
||||||
const addRandomNode = () => {
|
const addRandomNode = () => {
|
||||||
const nodeId = (nodes.value.length + 1).toString()
|
const nodeId = (nodes.value.length + 1).toString()
|
||||||
|
|
||||||
const newNode = {
|
const newNode = {
|
||||||
id: nodeId,
|
id: nodeId,
|
||||||
label: `Node: ${nodeId}`,
|
label: `Node: ${nodeId}`,
|
||||||
position: { x: Math.random() * dimensions.value.width, y: Math.random() * dimensions.value.height },
|
position: { x: Math.random() * dimensions.value.width, y: Math.random() * dimensions.value.height },
|
||||||
}
|
}
|
||||||
|
|
||||||
addNodes([newNode])
|
addNodes([newNode])
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -22,11 +22,11 @@ const addRandomNode = () => {
|
|||||||
<template>
|
<template>
|
||||||
<VueFlow>
|
<VueFlow>
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
<Controls />
|
|
||||||
<Background :variant="BackgroundVariant.Lines" />
|
<Background :variant="BackgroundVariant.Lines" />
|
||||||
|
|
||||||
<button type="button" :style="{ position: 'absolute', left: '10px', top: '10px', zIndex: 4 }" @click="addRandomNode">
|
<Panel :position="PanelPosition.TopRight">
|
||||||
add node
|
<button type="button" @click="addRandomNode">add node</button>
|
||||||
</button>
|
</Panel>
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Controls, MiniMap } from '@vue-flow/additional-components'
|
import { Background, Panel, PanelPosition } from '@vue-flow/additional-components'
|
||||||
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
||||||
import { ref, watchEffect } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
const isHidden = ref(false)
|
const isHidden = ref(false)
|
||||||
|
|
||||||
@@ -19,24 +19,23 @@ const { nodes, edges } = useVueFlow({
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
watchEffect(() => {
|
watch(isHidden, () => {
|
||||||
nodes.value.forEach((n) => (n.hidden = isHidden.value))
|
nodes.value.forEach((n) => (n.hidden = isHidden.value))
|
||||||
edges.value.forEach((e) => (e.hidden = isHidden.value))
|
edges.value.forEach((e) => (e.hidden = isHidden.value))
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow>
|
<VueFlow fit-view-on-init>
|
||||||
<MiniMap />
|
<Background />
|
||||||
<Controls />
|
|
||||||
|
|
||||||
<div :style="{ position: 'absolute', left: '10px', top: '10px', zIndex: 4 }">
|
<Panel :position="PanelPosition.TopRight">
|
||||||
<div>
|
<div>
|
||||||
<label for="ishidden">
|
<label for="ishidden">
|
||||||
hidden
|
hidden
|
||||||
<input id="ishidden" v-model="isHidden" type="checkbox" />
|
<input id="ishidden" v-model="isHidden" type="checkbox" />
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Panel>
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -19,10 +19,12 @@ onConnect((params) => addEdges([params]))
|
|||||||
:default-zoom="1.5"
|
:default-zoom="1.5"
|
||||||
:min-zoom="0.2"
|
:min-zoom="0.2"
|
||||||
:max-zoom="4"
|
:max-zoom="4"
|
||||||
:fit-view-on-init="true"
|
fit-view-on-init
|
||||||
>
|
>
|
||||||
<Background pattern-color="#aaa" gap="8" />
|
<Background pattern-color="#aaa" gap="8" />
|
||||||
|
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
|
|
||||||
<Controls />
|
<Controls />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ export const exampleImports = {
|
|||||||
'App.vue': TeleportApp,
|
'App.vue': TeleportApp,
|
||||||
'Sidebar.vue': TeleportSidebar,
|
'Sidebar.vue': TeleportSidebar,
|
||||||
'TeleportableNode.vue': TeleportableNode,
|
'TeleportableNode.vue': TeleportableNode,
|
||||||
'useTransition.js': TeleportableUseTransition,
|
'useTeleport.js': TeleportableUseTransition,
|
||||||
'style.css': TeleportCSS,
|
'style.css': TeleportCSS,
|
||||||
},
|
},
|
||||||
transition: {
|
transition: {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const elements = ref([
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow v-model="elements" class="interactionflow" :fit-view-on-init="true">
|
<VueFlow v-model="elements" class="interactionflow" fit-view-on-init>
|
||||||
<InteractionControls />
|
<InteractionControls />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -23,14 +23,21 @@ const {
|
|||||||
} = useVueFlow()
|
} = useVueFlow()
|
||||||
|
|
||||||
const captureZoomClick = ref(false)
|
const captureZoomClick = ref(false)
|
||||||
|
|
||||||
const captureZoomScroll = ref(false)
|
const captureZoomScroll = ref(false)
|
||||||
|
|
||||||
onConnect((params) => addEdges([params]))
|
onConnect((params) => addEdges([params]))
|
||||||
|
|
||||||
onNodeDragStart((e) => console.log('drag start', e))
|
onNodeDragStart((e) => console.log('drag start', e))
|
||||||
|
|
||||||
onNodeDragStop((e) => console.log('drag stop', e))
|
onNodeDragStop((e) => console.log('drag stop', e))
|
||||||
|
|
||||||
onPaneClick((event) => captureZoomClick.value && console.log('pane click', event))
|
onPaneClick((event) => captureZoomClick.value && console.log('pane click', event))
|
||||||
|
|
||||||
onPaneScroll((event) => captureZoomScroll.value && console.log('pane scroll', event))
|
onPaneScroll((event) => captureZoomScroll.value && console.log('pane scroll', event))
|
||||||
|
|
||||||
onPaneContextMenu((event) => captureZoomClick.value && console.log('pane ctx menu', event))
|
onPaneContextMenu((event) => captureZoomClick.value && console.log('pane ctx menu', event))
|
||||||
|
|
||||||
onMoveEnd((flowTransform) => console.log('move end', flowTransform))
|
onMoveEnd((flowTransform) => console.log('move end', flowTransform))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
background-color: lightgray;
|
background-color: lightgray;
|
||||||
border-bottom-right-radius: 10px;
|
border-bottom-right-radius: 10px;
|
||||||
padding: 12px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.interactionflow .controls .label {
|
.interactionflow .controls .label {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Flow from './Flow.vue'
|
|||||||
<template>
|
<template>
|
||||||
<div class="multiflows">
|
<div class="multiflows">
|
||||||
<Flow />
|
<Flow />
|
||||||
|
|
||||||
<Flow />
|
<Flow />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import { Background, Panel, PanelPosition } from '@vue-flow/additional-components'
|
||||||
import { VueFlow, isNode } from '@vue-flow/core'
|
import { VueFlow, isNode } from '@vue-flow/core'
|
||||||
import { Background } from '@vue-flow/additional-components'
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const elements = ref([
|
const elements = ref([
|
||||||
@@ -26,12 +26,12 @@ const updatePos = () =>
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow v-model="elements" :fit-view-on-init="true">
|
<VueFlow v-model="elements" fit-view-on-init>
|
||||||
<Background />
|
<Background />
|
||||||
|
|
||||||
<div style="position: absolute; right: 10px; top: 10px; z-index: 4">
|
<Panel :position="PanelPosition.TopRight">
|
||||||
<button style="margin-right: 5px" @click="updatePos">update positions</button>
|
<button style="margin-right: 5px" @click="updatePos">update positions</button>
|
||||||
<button style="margin-right: 5px" @click="toggleClass">toggle class</button>
|
<button @click="toggleClass">toggle class</button>
|
||||||
</div>
|
</Panel>
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Background, Controls, MiniMap } from '@vue-flow/additional-components'
|
import { Background, Controls, MiniMap } from '@vue-flow/additional-components'
|
||||||
import { ConnectionMode, VueFlow, useVueFlow } from '@vue-flow/core'
|
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
||||||
import { onMounted } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
|
|
||||||
const { onConnect, nodes, edges, addEdges, addNodes } = useVueFlow({
|
const { onConnect, nodes, edges, addEdges, addNodes } = useVueFlow({
|
||||||
fitViewOnInit: true,
|
fitViewOnInit: true,
|
||||||
connectionMode: ConnectionMode.Loose,
|
|
||||||
// set this to true so edges get elevated when selected, defaults to false
|
// set this to true so edges get elevated when selected, defaults to false
|
||||||
elevateEdgesOnSelect: true,
|
elevateEdgesOnSelect: true,
|
||||||
nodes: [
|
nodes: [
|
||||||
@@ -88,7 +87,9 @@ onMounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<VueFlow>
|
<VueFlow>
|
||||||
<MiniMap />
|
<MiniMap />
|
||||||
|
|
||||||
<Controls />
|
<Controls />
|
||||||
|
|
||||||
<Background />
|
<Background />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { VueFlow } from '@vue-flow/core'
|
import { VueFlow } from '@vue-flow/core'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import Controls from './Controls.vue'
|
import SaveRestoreControls from './Controls.vue'
|
||||||
|
|
||||||
const elements = ref([{ id: '1', label: 'Node 1', position: { x: 100, y: 100 } }])
|
const elements = ref([{ id: '1', label: 'Node 1', position: { x: 100, y: 100 } }])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow v-model="elements">
|
<VueFlow v-model="elements">
|
||||||
<Controls />
|
<SaveRestoreControls />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import { Panel, PanelPosition } from '@vue-flow/additional-components'
|
||||||
import { useVueFlow } from '@vue-flow/core'
|
import { useVueFlow } from '@vue-flow/core'
|
||||||
|
|
||||||
const flowKey = 'example-flow'
|
const flowKey = 'example-flow'
|
||||||
@@ -22,19 +23,21 @@ const onRestore = () => {
|
|||||||
|
|
||||||
const onAdd = () => {
|
const onAdd = () => {
|
||||||
const id = nodes.value.length + 1
|
const id = nodes.value.length + 1
|
||||||
|
|
||||||
const newNode = {
|
const newNode = {
|
||||||
id: `random_node-${id}`,
|
id: `random_node-${id}`,
|
||||||
label: `Node ${id}`,
|
label: `Node ${id}`,
|
||||||
position: { x: Math.random() * dimensions.value.width, y: Math.random() * dimensions.value.height },
|
position: { x: Math.random() * dimensions.value.width, y: Math.random() * dimensions.value.height },
|
||||||
}
|
}
|
||||||
|
|
||||||
addNodes([newNode])
|
addNodes([newNode])
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="save__controls">
|
<Panel :position="PanelPosition.TopRight" class="save-restore-controls">
|
||||||
<button style="background-color: #33a6b8" @click="onSave">save</button>
|
<button style="background-color: #33a6b8" @click="onSave">save</button>
|
||||||
<button style="background-color: #113285" @click="onRestore">restore</button>
|
<button style="background-color: #113285" @click="onRestore">restore</button>
|
||||||
<button style="background-color: #6f3381" @click="onAdd">add node</button>
|
<button style="background-color: #6f3381" @click="onAdd">add node</button>
|
||||||
</div>
|
</Panel>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
.save__controls {
|
.save-restore-controls {
|
||||||
position: absolute;
|
|
||||||
left: 10px;
|
|
||||||
top: 10px;
|
|
||||||
z-index: 4;
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.save__controls button {
|
.save-restore-controls button {
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@@ -18,8 +14,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.save__controls button:hover {
|
.save-restore-controls button:hover {
|
||||||
opacity: 0.8;
|
|
||||||
transform: scale(105%);
|
transform: scale(105%);
|
||||||
transition: 250ms all ease-in-out;
|
transition: 250ms all ease-in-out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import { Background, MiniMap, Panel, PanelPosition } from '@vue-flow/additional-components'
|
||||||
import { VueFlow, isNode, useVueFlow } from '@vue-flow/core'
|
import { VueFlow, isNode, useVueFlow } from '@vue-flow/core'
|
||||||
import { nextTick, ref } from 'vue'
|
import { nextTick, ref } from 'vue'
|
||||||
import { getElements } from './utils.js'
|
import { getElements } from './utils.js'
|
||||||
@@ -12,6 +13,7 @@ onPaneReady((i) => {
|
|||||||
i.fitView({
|
i.fitView({
|
||||||
padding: 0.2,
|
padding: 0.2,
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log(i.getElements.value)
|
console.log(i.getElements.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -26,6 +28,7 @@ const updatePos = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
fitView({ duration: 1000, padding: 0.5 })
|
fitView({ duration: 1000, padding: 0.5 })
|
||||||
})
|
})
|
||||||
@@ -34,9 +37,13 @@ const updatePos = () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow v-model="elements" :min-zoom="0.1">
|
<VueFlow v-model="elements" :min-zoom="0.1">
|
||||||
<div style="position: absolute; right: 10px; top: 10px; z-index: 4">
|
<MiniMap />
|
||||||
|
|
||||||
|
<Background />
|
||||||
|
|
||||||
|
<Panel :position="PanelPosition.TopRight">
|
||||||
<button style="margin-right: 5px" @click="updatePos">update positions</button>
|
<button style="margin-right: 5px" @click="updatePos">update positions</button>
|
||||||
<button style="margin-right: 5px" @click="toggleClass">toggle class</button>
|
<button @click="toggleClass">toggle class</button>
|
||||||
</div>
|
</Panel>
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -36,11 +36,12 @@ const elements = ref([
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="teleportflow">
|
<div class="teleportflow">
|
||||||
<VueFlow v-model="elements" :fit-view-on-init="true">
|
<VueFlow v-model="elements" fit-view-on-init>
|
||||||
<template #node-teleportable="props">
|
<template #node-teleportable="{ id }">
|
||||||
<TeleportableNode v-bind="props" />
|
<TeleportableNode :id="id" />
|
||||||
</template>
|
</template>
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
|
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
//
|
// ...
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<aside>
|
<aside>
|
||||||
<div class="description">Teleport destination</div>
|
<div class="description">Teleport destination</div>
|
||||||
|
|
||||||
<div id="port" class="port"></div>
|
<div id="port" class="port"></div>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Handle, Position } from '@vue-flow/core'
|
import { Handle, Position } from '@vue-flow/core'
|
||||||
import { useTeleport } from './useTransition.js'
|
import { useTeleport } from './useTeleport.js'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
@@ -27,12 +27,17 @@ export default {
|
|||||||
<transition :name="animation">
|
<transition :name="animation">
|
||||||
<div v-if="!transition" class="teleportable">
|
<div v-if="!transition" class="teleportable">
|
||||||
<Handle type="target" :position="Position.Top" />
|
<Handle type="target" :position="Position.Top" />
|
||||||
|
|
||||||
[Node {{ id }}]
|
[Node {{ id }}]
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<div v-if="teleport !== '#port'" class="button" @click.prevent="onClick('#port')">Teleport To Sidebar</div>
|
<div v-if="teleport !== '#port'" class="button" @click.prevent="onClick('#port')">Teleport To Sidebar</div>
|
||||||
|
|
||||||
<div v-if="teleport !== null" class="button" @click.prevent="onClick(null)">Teleport To Main Graph</div>
|
<div v-if="teleport !== null" class="button" @click.prevent="onClick(null)">Teleport To Main Graph</div>
|
||||||
|
|
||||||
<div class="button" @click.prevent="changeAnimation">Animation: {{ animation }}</div>
|
<div class="button" @click.prevent="changeAnimation">Animation: {{ animation }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Handle type="source" :position="Position.Bottom" />
|
<Handle type="source" :position="Position.Bottom" />
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const useTeleport = (id) => {
|
|||||||
const transition = ref(false)
|
const transition = ref(false)
|
||||||
const teleport = ref(null)
|
const teleport = ref(null)
|
||||||
|
|
||||||
const { updateNodeInternals, getNode, edges } = useVueFlow()
|
const { updateNodeInternals, findNode, edges } = useVueFlow()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* specify a selector to teleport to
|
* specify a selector to teleport to
|
||||||
@@ -65,7 +65,7 @@ export const useTeleport = (id) => {
|
|||||||
* i.e. if they emit events, they will still emit them up their regular tree
|
* i.e. if they emit events, they will still emit them up their regular tree
|
||||||
*/
|
*/
|
||||||
const onClick = (destination) => {
|
const onClick = (destination) => {
|
||||||
const node = getNode.value(id)
|
const node = findNode(id)
|
||||||
|
|
||||||
transition.value = true
|
transition.value = true
|
||||||
|
|
||||||
@@ -79,13 +79,13 @@ export const useTeleport = (id) => {
|
|||||||
// check if nodes connected to edge are teleported and hide edge if one of them is
|
// check if nodes connected to edge are teleported and hide edge if one of them is
|
||||||
if (destination) {
|
if (destination) {
|
||||||
connectedEdges.forEach(
|
connectedEdges.forEach(
|
||||||
(edge) => (edge.hidden = !!getNode.value(edge.source).data.destination || !!getNode.value(edge.target).data.destination),
|
(edge) => (edge.hidden = !!findNode(edge.source).data.destination || !!findNode(edge.target).data.destination),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onFinish = () => {
|
const onFinish = () => {
|
||||||
connectedEdges.forEach(
|
connectedEdges.forEach(
|
||||||
(edge) => (edge.hidden = !!getNode.value(edge.source).data.destination || !!getNode.value(edge.target).data.destination),
|
(edge) => (edge.hidden = !!findNode(edge.source).data.destination || !!findNode(edge.target).data.destination),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { ConnectionMode, Position, VueFlow, useVueFlow } from '@vue-flow/core'
|
import { Position, VueFlow, useVueFlow } from '@vue-flow/core'
|
||||||
import TransitionEdge from './TransitionEdge.vue'
|
import TransitionEdge from './TransitionEdge.vue'
|
||||||
|
|
||||||
const elements = ref([
|
const elements = ref([
|
||||||
@@ -21,28 +21,18 @@ const elements = ref([
|
|||||||
|
|
||||||
{ id: 'e1-2', type: 'custom', source: '1', target: '2', animated: true, style: { stroke: '#fff' } },
|
{ id: 'e1-2', type: 'custom', source: '1', target: '2', animated: true, style: { stroke: '#fff' } },
|
||||||
])
|
])
|
||||||
const bgColor = ref('#1A192B')
|
|
||||||
const connectionLineStyle = { stroke: '#fff' }
|
|
||||||
const snapGrid = [16, 16]
|
|
||||||
|
|
||||||
const { onPaneReady } = useVueFlow({
|
const { onPaneReady } = useVueFlow()
|
||||||
connectionMode: ConnectionMode.Loose,
|
|
||||||
connectionLineStyle,
|
|
||||||
snapToGrid: true,
|
|
||||||
snapGrid,
|
|
||||||
defaultZoom: 1.5,
|
|
||||||
})
|
|
||||||
|
|
||||||
onPaneReady((i) => {
|
onPaneReady((i) => {
|
||||||
i.fitView({
|
i.fitView({
|
||||||
nodes: ['1'],
|
nodes: ['1'],
|
||||||
})
|
})
|
||||||
console.log('flow loaded:', i)
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow v-model="elements" :style="{ backgroundColor: bgColor }">
|
<VueFlow v-model="elements" :style="{ backgroundColor: '#1A192B' }">
|
||||||
<template #edge-custom="props">
|
<template #edge-custom="props">
|
||||||
<TransitionEdge v-bind="props" />
|
<TransitionEdge v-bind="props" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { TransitionPresets, useDebounceFn, useTransition, watchDebounced } from '@vueuse/core'
|
import { TransitionPresets, useDebounceFn, useTransition, watchDebounced } from '@vueuse/core'
|
||||||
import { getBezierPath, useVueFlow } from '@vue-flow/core'
|
import { BezierEdge, useVueFlow } from '@vue-flow/core'
|
||||||
import { computed, ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
@@ -64,21 +64,11 @@ const showDot = ref(false)
|
|||||||
|
|
||||||
const { onNodeDoubleClick, fitBounds, fitView } = useVueFlow()
|
const { onNodeDoubleClick, fitBounds, fitView } = useVueFlow()
|
||||||
|
|
||||||
const edgePath = computed(() =>
|
|
||||||
getBezierPath({
|
|
||||||
sourceX: props.sourceX,
|
|
||||||
sourceY: props.sourceY,
|
|
||||||
sourcePosition: props.sourcePosition,
|
|
||||||
targetX: props.targetX,
|
|
||||||
targetY: props.targetY,
|
|
||||||
targetPosition: props.targetPosition,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const debouncedFitBounds = useDebounceFn(fitBounds, 1, { maxWait: 1 })
|
const debouncedFitBounds = useDebounceFn(fitBounds, 1, { maxWait: 1 })
|
||||||
|
|
||||||
onNodeDoubleClick(({ node }) => {
|
onNodeDoubleClick(({ node }) => {
|
||||||
const isSource = props.source === node.id
|
const isSource = props.source === node.id
|
||||||
|
|
||||||
const isTarget = props.target === node.id
|
const isTarget = props.target === node.id
|
||||||
|
|
||||||
if (!showDot.value && (isSource || isTarget)) {
|
if (!showDot.value && (isSource || isTarget)) {
|
||||||
@@ -150,7 +140,8 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<path :id="id" ref="curve" :style="style" class="vue-flow__edge-path" :d="edgePath" :marker-end="markerEnd" />
|
<BezierEdge v-bind="props" />
|
||||||
|
|
||||||
<Transition name="fade">
|
<Transition name="fade">
|
||||||
<circle
|
<circle
|
||||||
v-if="showDot"
|
v-if="showDot"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { Controls } from '@vue-flow/additional-components'
|
import { Background } from '@vue-flow/additional-components'
|
||||||
import { ConnectionMode, VueFlow, addEdge, updateEdge } from '@vue-flow/core'
|
import { VueFlow, useVueFlow } from '@vue-flow/core'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const elements = ref([
|
const elements = ref([
|
||||||
@@ -24,25 +24,26 @@ const elements = ref([
|
|||||||
{ id: 'e1-2', source: '1', target: '2', label: 'Updateable edge', updatable: true },
|
{ id: 'e1-2', source: '1', target: '2', label: 'Updateable edge', updatable: true },
|
||||||
])
|
])
|
||||||
|
|
||||||
const onLoad = (flowInstance) => flowInstance.fitView()
|
const { updateEdge, addEdges } = useVueFlow()
|
||||||
|
|
||||||
const onEdgeUpdateStart = (edge) => console.log('start update', edge)
|
const onEdgeUpdateStart = (edge) => console.log('start update', edge)
|
||||||
|
|
||||||
const onEdgeUpdateEnd = (edge) => console.log('end update', edge)
|
const onEdgeUpdateEnd = (edge) => console.log('end update', edge)
|
||||||
const onEdgeUpdate = ({ edge, connection }) => {
|
|
||||||
elements.value = updateEdge(edge, connection, elements.value)
|
const onEdgeUpdate = ({ edge, connection }) => updateEdge(edge, connection)
|
||||||
}
|
|
||||||
const onConnect = (params) => (elements.value = addEdge(params, elements.value))
|
const onConnect = (params) => addEdges([params])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VueFlow
|
<VueFlow
|
||||||
v-model="elements"
|
v-model="elements"
|
||||||
:connection-mode="ConnectionMode.Loose"
|
fit-view-on-init
|
||||||
@pane-ready="onLoad"
|
|
||||||
@edge-update="onEdgeUpdate"
|
@edge-update="onEdgeUpdate"
|
||||||
@connect="onConnect"
|
@connect="onConnect"
|
||||||
@edge-update-start="onEdgeUpdateStart"
|
@edge-update-start="onEdgeUpdateStart"
|
||||||
@edge-update-end="onEdgeUpdateEnd"
|
@edge-update-end="onEdgeUpdateEnd"
|
||||||
>
|
>
|
||||||
<Controls />
|
<Background />
|
||||||
</VueFlow>
|
</VueFlow>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ const elements = ref([
|
|||||||
{ id: 'C', type: 'custom', position: { x: 250, y: 300 }, isValidSourcePos: (connection) => connection.target === 'B' },
|
{ id: 'C', type: 'custom', position: { x: 250, y: 300 }, isValidSourcePos: (connection) => connection.target === 'B' },
|
||||||
])
|
])
|
||||||
|
|
||||||
const onLoad = (flowInstance) => flowInstance.fitView()
|
|
||||||
const onConnectStart = ({ nodeId, handleType }) => console.log('on connect start', { nodeId, handleType })
|
const onConnectStart = ({ nodeId, handleType }) => console.log('on connect start', { nodeId, handleType })
|
||||||
|
|
||||||
const onConnectEnd = (event) => console.log('on connect end', event)
|
const onConnectEnd = (event) => console.log('on connect end', event)
|
||||||
|
|
||||||
const onConnect = (params) => {
|
const onConnect = (params) => {
|
||||||
@@ -29,15 +29,16 @@ const onConnect = (params) => {
|
|||||||
<template>
|
<template>
|
||||||
<VueFlow
|
<VueFlow
|
||||||
v-model="elements"
|
v-model="elements"
|
||||||
|
fit-view-on-init
|
||||||
class="validationflow"
|
class="validationflow"
|
||||||
@connect="onConnect"
|
@connect="onConnect"
|
||||||
@pane-ready="onLoad"
|
|
||||||
@connect-start="onConnectStart"
|
@connect-start="onConnectStart"
|
||||||
@connect-end="onConnectEnd"
|
@connect-end="onConnectEnd"
|
||||||
>
|
>
|
||||||
<template #node-custominput="props">
|
<template #node-custominput="props">
|
||||||
<CustomInput v-bind="props" />
|
<CustomInput v-bind="props" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #node-custom="props">
|
<template #node-custom="props">
|
||||||
<CustomNode v-bind="props" />
|
<CustomNode v-bind="props" />
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
Reference in New Issue
Block a user