chore: lint files
Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
@@ -49,7 +49,7 @@ watchEffect(() => {
|
|||||||
vh.value = `${window.innerHeight}px`
|
vh.value = `${window.innerHeight}px`
|
||||||
})
|
})
|
||||||
|
|
||||||
const files: Record<string, typeof imports[keyof typeof imports]> = {}
|
const files: Record<string, (typeof imports)[keyof typeof imports]> = {}
|
||||||
const imports = exampleImports[props.example]
|
const imports = exampleImports[props.example]
|
||||||
const additionalImports = 'additionalImports' in imports ? imports.additionalImports : {}
|
const additionalImports = 'additionalImports' in imports ? imports.additionalImports : {}
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ const dark = ref(false)
|
|||||||
* To update node properties you can simply use your elements v-model and mutate the elements directly
|
* To update node properties you can simply use your elements v-model and mutate the elements directly
|
||||||
* Changes should always be reflected on the graph reactively, without the need to overwrite the elements
|
* Changes should always be reflected on the graph reactively, without the need to overwrite the elements
|
||||||
*/
|
*/
|
||||||
const updatePos = () =>
|
function updatePos() {
|
||||||
elements.value.forEach((el) => {
|
return elements.value.forEach((el) => {
|
||||||
if (isNode(el)) {
|
if (isNode(el)) {
|
||||||
el.position = {
|
el.position = {
|
||||||
x: Math.random() * 400,
|
x: Math.random() * 400,
|
||||||
@@ -49,18 +49,25 @@ const updatePos = () =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toObject transforms your current graph data to an easily persist-able object
|
* toObject transforms your current graph data to an easily persist-able object
|
||||||
*/
|
*/
|
||||||
const logToObject = () => console.log(toObject())
|
function logToObject() {
|
||||||
|
return console.log(toObject())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the current viewpane transformation (zoom & pan)
|
* Resets the current viewpane transformation (zoom & pan)
|
||||||
*/
|
*/
|
||||||
const resetTransform = () => setTransform({ x: 0, y: 0, zoom: 1 })
|
function resetTransform() {
|
||||||
|
return setTransform({ x: 0, y: 0, zoom: 1 })
|
||||||
|
}
|
||||||
|
|
||||||
const toggleClass = () => (dark.value = !dark.value)
|
function toggleClass() {
|
||||||
|
return (dark.value = !dark.value)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({
|
defineProps({
|
||||||
sourceX: {
|
sourceX: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
|
|||||||
@@ -18,23 +18,27 @@ const bgName = ref('AYAME')
|
|||||||
const connectionLineStyle = { stroke: '#fff' }
|
const connectionLineStyle = { stroke: '#fff' }
|
||||||
|
|
||||||
// minimap stroke color functions
|
// minimap stroke color functions
|
||||||
const nodeStroke = (n) => {
|
function nodeStroke(n) {
|
||||||
if (n.type === 'input') return '#0041d0'
|
if (n.type === 'input') return '#0041d0'
|
||||||
if (n.type === 'custom') return presets.sumi
|
if (n.type === 'custom') return presets.sumi
|
||||||
if (n.type === 'output') return '#ff0072'
|
if (n.type === 'output') return '#ff0072'
|
||||||
return '#eee'
|
return '#eee'
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeColor = (n) => {
|
function nodeColor(n) {
|
||||||
if (n.type === 'custom') return bgColor.value
|
if (n.type === 'custom') return bgColor.value
|
||||||
return '#fff'
|
return '#fff'
|
||||||
}
|
}
|
||||||
|
|
||||||
// output labels
|
// output labels
|
||||||
const outputColorLabel = () => h('div', {}, bgColor.value)
|
function outputColorLabel() {
|
||||||
const outputNameLabel = () => h('div', {}, bgName.value)
|
return h('div', {}, bgColor.value)
|
||||||
|
}
|
||||||
|
function outputNameLabel() {
|
||||||
|
return h('div', {}, bgName.value)
|
||||||
|
}
|
||||||
|
|
||||||
const onChange = (color) => {
|
function onChange(color) {
|
||||||
gradient.value = false
|
gradient.value = false
|
||||||
bgColor.value = color.value
|
bgColor.value = color.value
|
||||||
bgName.value = color.name
|
bgName.value = color.name
|
||||||
@@ -42,7 +46,7 @@ const onChange = (color) => {
|
|||||||
findNode('3').hidden = false
|
findNode('3').hidden = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const onGradient = () => {
|
function onGradient() {
|
||||||
gradient.value = true
|
gradient.value = true
|
||||||
bgColor.value = null
|
bgColor.value = null
|
||||||
bgName.value = 'gradient'
|
bgName.value = 'gradient'
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(['change', 'gradient'])
|
const emit = defineEmits(['change', 'gradient'])
|
||||||
|
|
||||||
const onSelect = (color) => {
|
function onSelect(color) {
|
||||||
emit('change', color)
|
emit('change', color)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onGradient = () => {
|
function onGradient() {
|
||||||
emit('gradient')
|
emit('gradient')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import { nextTick, watch } from 'vue'
|
|||||||
import Sidebar from './Sidebar.vue'
|
import Sidebar from './Sidebar.vue'
|
||||||
|
|
||||||
let id = 0
|
let id = 0
|
||||||
const getId = () => `dndnode_${id++}`
|
function getId() {
|
||||||
|
return `dndnode_${id++}`
|
||||||
|
}
|
||||||
|
|
||||||
const { findNode, onConnect, nodes, edges, addEdges, addNodes, viewport, project, vueFlowRef } = useVueFlow({
|
const { findNode, onConnect, addEdges, addNodes, project, vueFlowRef } = useVueFlow({
|
||||||
nodes: [
|
nodes: [
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -17,7 +19,7 @@ const { findNode, onConnect, nodes, edges, addEdges, addNodes, viewport, project
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
const onDragOver = (event) => {
|
function onDragOver(event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
if (event.dataTransfer) {
|
if (event.dataTransfer) {
|
||||||
@@ -27,7 +29,7 @@ const onDragOver = (event) => {
|
|||||||
|
|
||||||
onConnect((params) => addEdges([params]))
|
onConnect((params) => addEdges([params]))
|
||||||
|
|
||||||
const onDrop = (event) => {
|
function onDrop(event) {
|
||||||
const type = event.dataTransfer?.getData('application/vueflow')
|
const type = event.dataTransfer?.getData('application/vueflow')
|
||||||
|
|
||||||
const { left, top } = vueFlowRef.value.getBoundingClientRect()
|
const { left, top } = vueFlowRef.value.getBoundingClientRect()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
const onDragStart = (event, nodeType) => {
|
function onDragStart(event, nodeType) {
|
||||||
if (event.dataTransfer) {
|
if (event.dataTransfer) {
|
||||||
event.dataTransfer.setData('application/vueflow', nodeType)
|
event.dataTransfer.setData('application/vueflow', nodeType)
|
||||||
event.dataTransfer.effectAllowed = 'move'
|
event.dataTransfer.effectAllowed = 'move'
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import { Panel, PanelPosition, VueFlow, useVueFlow } from '@vue-flow/core'
|
|||||||
import { Background, BackgroundVariant } from '@vue-flow/background'
|
import { Background, BackgroundVariant } from '@vue-flow/background'
|
||||||
import { MiniMap } from '@vue-flow/minimap'
|
import { MiniMap } from '@vue-flow/minimap'
|
||||||
|
|
||||||
const { nodes, addNodes, edges, addEdges, onConnect, onPaneReady, onNodeDragStop, dimensions } = useVueFlow()
|
const { nodes, addNodes, addEdges, onConnect, dimensions } = useVueFlow()
|
||||||
|
|
||||||
onConnect((params) => addEdges([params]))
|
onConnect((params) => addEdges([params]))
|
||||||
|
|
||||||
const addRandomNode = () => {
|
function addRandomNode() {
|
||||||
const nodeId = (nodes.value.length + 1).toString()
|
const nodeId = (nodes.value.length + 1).toString()
|
||||||
|
|
||||||
const newNode = {
|
const newNode = {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { initialElements } from './initial-elements.js'
|
|||||||
* You can either use `getIntersectingNodes` to check if a given node intersects with others
|
* You can either use `getIntersectingNodes` to check if a given node intersects with others
|
||||||
* or `isNodeIntersecting` to check if a node is intersecting with a given area
|
* or `isNodeIntersecting` to check if a node is intersecting with a given area
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { onNodeDrag, getIntersectingNodes, isNodeIntersecting, getNodes } = useVueFlow()
|
const { onNodeDrag, getIntersectingNodes, isNodeIntersecting, getNodes } = useVueFlow()
|
||||||
|
|
||||||
const elements = ref(initialElements)
|
const elements = ref(initialElements)
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ const elements = ref([
|
|||||||
{ id: 'e1-3', source: '1', target: '3' },
|
{ id: 'e1-3', source: '1', target: '3' },
|
||||||
])
|
])
|
||||||
|
|
||||||
const toggleClass = () => elements.value.forEach((el) => (el.class = el.class === 'light' ? 'dark' : 'light'))
|
function toggleClass() {
|
||||||
|
return elements.value.forEach((el) => (el.class = el.class === 'light' ? 'dark' : 'light'))
|
||||||
|
}
|
||||||
|
|
||||||
const updatePos = () =>
|
function updatePos() {
|
||||||
elements.value.forEach((el) => {
|
return elements.value.forEach((el) => {
|
||||||
if (isNode(el)) {
|
if (isNode(el)) {
|
||||||
el.position = {
|
el.position = {
|
||||||
x: Math.random() * 400,
|
x: Math.random() * 400,
|
||||||
@@ -23,6 +25,7 @@ const updatePos = () =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Controls } from '@vue-flow/controls'
|
|||||||
import { MiniMap } from '@vue-flow/minimap'
|
import { MiniMap } from '@vue-flow/minimap'
|
||||||
import { onMounted } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
|
|
||||||
const { onConnect, nodes, edges, addEdges, addNodes } = useVueFlow({
|
const { onConnect, addEdges, addNodes } = useVueFlow({
|
||||||
fitViewOnInit: true,
|
fitViewOnInit: true,
|
||||||
// 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,
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ const flowKey = 'example-flow'
|
|||||||
|
|
||||||
const { nodes, addNodes, setNodes, setEdges, dimensions, setTransform, toObject } = useVueFlow()
|
const { nodes, addNodes, setNodes, setEdges, dimensions, setTransform, toObject } = useVueFlow()
|
||||||
|
|
||||||
const onSave = () => {
|
function onSave() {
|
||||||
localStorage.setItem(flowKey, JSON.stringify(toObject()))
|
localStorage.setItem(flowKey, JSON.stringify(toObject()))
|
||||||
}
|
}
|
||||||
|
|
||||||
const onRestore = () => {
|
function onRestore() {
|
||||||
const flow = JSON.parse(localStorage.getItem(flowKey))
|
const flow = JSON.parse(localStorage.getItem(flowKey))
|
||||||
|
|
||||||
if (flow) {
|
if (flow) {
|
||||||
@@ -20,7 +20,7 @@ const onRestore = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onAdd = () => {
|
function onAdd() {
|
||||||
const id = nodes.value.length + 1
|
const id = nodes.value.length + 1
|
||||||
|
|
||||||
const newNode = {
|
const newNode = {
|
||||||
|
|||||||
@@ -6,21 +6,22 @@ import { nextTick, ref } from 'vue'
|
|||||||
import { getElements } from './utils.js'
|
import { getElements } from './utils.js'
|
||||||
|
|
||||||
const { nodes, edges } = getElements(15, 15)
|
const { nodes, edges } = getElements(15, 15)
|
||||||
|
|
||||||
const elements = ref([...nodes, ...edges])
|
const elements = ref([...nodes, ...edges])
|
||||||
|
|
||||||
const { onPaneReady, dimensions, onNodeClick, getEdges, fitView } = useVueFlow()
|
const { onPaneReady, dimensions, fitView } = useVueFlow()
|
||||||
|
|
||||||
onPaneReady((i) => {
|
onPaneReady(({ fitView, getElements }) => {
|
||||||
i.fitView({
|
fitView({ padding: 0.2 })
|
||||||
padding: 0.2,
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log(i.getElements.value)
|
console.log(getElements.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggleClass = () => elements.value.forEach((el) => (el.class = el.class === 'light' ? 'dark' : 'light'))
|
function toggleClass() {
|
||||||
|
return elements.value.forEach((el) => (el.class = el.class === 'light' ? 'dark' : 'light'))
|
||||||
|
}
|
||||||
|
|
||||||
const updatePos = () => {
|
function updatePos() {
|
||||||
elements.value.forEach((el) => {
|
elements.value.forEach((el) => {
|
||||||
if (isNode(el)) {
|
if (isNode(el)) {
|
||||||
el.position = {
|
el.position = {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const props = defineProps({
|
|||||||
|
|
||||||
const { animation, transition, teleport, onClick } = useTeleport(props.id)
|
const { animation, transition, teleport, onClick } = useTeleport(props.id)
|
||||||
|
|
||||||
const changeAnimation = () => {
|
function changeAnimation() {
|
||||||
animation.value = animation.value === 'fade' ? 'shrink' : 'fade'
|
animation.value = animation.value === 'fade' ? 'shrink' : 'fade'
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { nextTick, ref } from 'vue'
|
|||||||
* Animations that resize a node need to call the `updateNodeDimensions` function from store to update node handle positions
|
* Animations that resize a node need to call the `updateNodeDimensions` function from store to update node handle positions
|
||||||
* Otherwise edges do not connect properly
|
* Otherwise edges do not connect properly
|
||||||
*/
|
*/
|
||||||
export const useTeleport = (id) => {
|
export function useTeleport(id) {
|
||||||
const animation = ref('fade')
|
const animation = ref('fade')
|
||||||
const transition = ref(false)
|
const transition = ref(false)
|
||||||
const teleport = ref(null)
|
const teleport = ref(null)
|
||||||
|
|||||||
@@ -26,13 +26,21 @@ const elements = ref([
|
|||||||
|
|
||||||
const { updateEdge, addEdges } = useVueFlow()
|
const { updateEdge, addEdges } = useVueFlow()
|
||||||
|
|
||||||
const onEdgeUpdateStart = (edge) => console.log('start update', edge)
|
function onEdgeUpdateStart(edge) {
|
||||||
|
return console.log('start update', edge)
|
||||||
|
}
|
||||||
|
|
||||||
const onEdgeUpdateEnd = (edge) => console.log('end update', edge)
|
function onEdgeUpdateEnd(edge) {
|
||||||
|
return console.log('end update', edge)
|
||||||
|
}
|
||||||
|
|
||||||
const onEdgeUpdate = ({ edge, connection }) => updateEdge(edge, connection)
|
function onEdgeUpdate({ edge, connection }) {
|
||||||
|
return updateEdge(edge, connection)
|
||||||
|
}
|
||||||
|
|
||||||
const onConnect = (params) => addEdges([params])
|
function onConnect(params) {
|
||||||
|
return addEdges([params])
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const opts = reactive({
|
|||||||
hidden: false,
|
hidden: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const updateNode = () => {
|
function updateNode() {
|
||||||
const node = getNode.value('1')
|
const node = getNode.value('1')
|
||||||
node.label = opts.label.trim() !== '' ? opts.label : defaultLabel
|
node.label = opts.label.trim() !== '' ? opts.label : defaultLabel
|
||||||
node.style = { backgroundColor: opts.bg }
|
node.style = { backgroundColor: opts.bg }
|
||||||
|
|||||||
@@ -16,11 +16,15 @@ 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 onConnectStart = ({ nodeId, handleType }) => console.log('on connect start', { nodeId, handleType })
|
function onConnectStart({ nodeId, handleType }) {
|
||||||
|
return console.log('on connect start', { nodeId, handleType })
|
||||||
|
}
|
||||||
|
|
||||||
const onConnectEnd = (event) => console.log('on connect end', event)
|
function onConnectEnd(event) {
|
||||||
|
return console.log('on connect end', event)
|
||||||
|
}
|
||||||
|
|
||||||
const onConnect = (params) => {
|
function onConnect(params) {
|
||||||
console.log('on connect', params)
|
console.log('on connect', params)
|
||||||
addEdge(params, elements.value)
|
addEdge(params, elements.value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ import Additional from './flows/Additional.vue'
|
|||||||
const el = ref<HTMLDivElement>()
|
const el = ref<HTMLDivElement>()
|
||||||
const instances: VueFlowStore[] = []
|
const instances: VueFlowStore[] = []
|
||||||
|
|
||||||
const onLoad = (instance: VueFlowStore) => {
|
function onLoad(instance: VueFlowStore) {
|
||||||
instances.push(instance)
|
instances.push(instance)
|
||||||
instance.fitView()
|
instance.fitView()
|
||||||
}
|
}
|
||||||
|
|
||||||
const fitViews = () => {
|
function fitViews() {
|
||||||
instances.forEach((i) => i.fitView())
|
instances.forEach((i) => i.fitView())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ function setElements() {
|
|||||||
const { stop } = useResizeObserver(el, useDebounceFn(setElements, 5))
|
const { stop } = useResizeObserver(el, useDebounceFn(setElements, 5))
|
||||||
onBeforeUnmount(stop)
|
onBeforeUnmount(stop)
|
||||||
|
|
||||||
const scrollTo = () => {
|
function scrollTo() {
|
||||||
const el = document.getElementById('acknowledgement')
|
const el = document.getElementById('acknowledgement')
|
||||||
if (el) {
|
if (el) {
|
||||||
el.scrollIntoView({ behavior: 'smooth' })
|
el.scrollIntoView({ behavior: 'smooth' })
|
||||||
@@ -235,7 +235,7 @@ const scrollTo = () => {
|
|||||||
|
|
||||||
const animationClassNames = ['checker-gb', 'checker-op', 'checker-yg', 'checker-ss']
|
const animationClassNames = ['checker-gb', 'checker-op', 'checker-yg', 'checker-ss']
|
||||||
|
|
||||||
const shuffle = (a: any[]) => {
|
function shuffle(a: any[]) {
|
||||||
for (let i = a.length - 1; i > 0; i--) {
|
for (let i = a.length - 1; i > 0; i--) {
|
||||||
const j = Math.floor(Math.random() * (i + 1))
|
const j = Math.floor(Math.random() * (i + 1))
|
||||||
;[a[i], a[j]] = [a[j], a[i]]
|
;[a[i], a[j]] = [a[j], a[i]]
|
||||||
@@ -243,7 +243,7 @@ const shuffle = (a: any[]) => {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
const createAnimationDurations = () => {
|
function createAnimationDurations() {
|
||||||
return animationClassNames.map((className) => {
|
return animationClassNames.map((className) => {
|
||||||
const duration = 5 + Math.random() * 5
|
const duration = 5 + Math.random() * 5
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,9 @@ watch(
|
|||||||
{ immediate: true },
|
{ immediate: true },
|
||||||
)
|
)
|
||||||
|
|
||||||
const onChange = ({ color: c, val }: { color: keyof Colors; val: number }) => (color.value[c] = Number(val))
|
function onChange({ color: c, val }: { color: keyof Colors; val: number }) {
|
||||||
|
return (color.value[c] = Number(val))
|
||||||
|
}
|
||||||
|
|
||||||
const nodeColor: MiniMapNodeFunc = (node) => {
|
const nodeColor: MiniMapNodeFunc = (node) => {
|
||||||
switch (node.id) {
|
switch (node.id) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import confetti from 'canvas-confetti'
|
import confetti from 'canvas-confetti'
|
||||||
|
|
||||||
export const fireworks = (colors?: string[]) => {
|
export function fireworks(colors?: string[]) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const duration = 15 * 1000
|
const duration = 15 * 1000
|
||||||
const animationEnd = Date.now() + duration
|
const animationEnd = Date.now() + duration
|
||||||
@@ -38,7 +38,7 @@ export const fireworks = (colors?: string[]) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const cheer = (colors: string[]) => {
|
export function cheer(colors: string[]) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const end = Date.now() + 2 * 1000
|
const end = Date.now() + 2 * 1000
|
||||||
|
|
||||||
|
|||||||
@@ -12,35 +12,50 @@ interface RGBNodeProps extends NodeProps {
|
|||||||
blue: number
|
blue: number
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<RGBNodeProps>()
|
const props = defineProps<RGBNodeProps>()
|
||||||
|
|
||||||
const emit = defineEmits(['change'])
|
const emit = defineEmits(['change'])
|
||||||
let color = 'red'
|
|
||||||
switch (props.data?.color) {
|
const currentColor = computed(() => {
|
||||||
case 'r':
|
let color
|
||||||
color = 'red'
|
|
||||||
break
|
switch (props.data?.color) {
|
||||||
case 'g':
|
case 'r':
|
||||||
color = 'green'
|
color = 'red'
|
||||||
break
|
break
|
||||||
case 'b':
|
case 'g':
|
||||||
color = 'blue'
|
color = 'green'
|
||||||
break
|
break
|
||||||
|
case 'b':
|
||||||
|
color = 'blue'
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
color = 'red'
|
||||||
|
}
|
||||||
|
|
||||||
|
return color
|
||||||
|
})
|
||||||
|
|
||||||
|
function onChange(e: any) {
|
||||||
|
return emit('change', { color: currentColor.value, val: e.target.value })
|
||||||
}
|
}
|
||||||
const onChange = (e: any) => emit('change', { color, val: e.target.value })
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="px-4 py-2 bg-white rounded-md border-2 border-solid border-black text-left transform scale-75 lg:scale-100">
|
<div class="px-4 py-2 bg-white rounded-md border-2 border-solid border-black text-left transform scale-75 lg:scale-100">
|
||||||
<div class="text-md" :style="{ color }">{{ `${color} Amount`.toUpperCase() }}</div>
|
<div class="text-md" :style="{ color: currentColor }">{{ `${currentColor} Amount`.toUpperCase() }}</div>
|
||||||
|
|
||||||
<input
|
<input
|
||||||
v-model="props.amount[color]"
|
:model-value="amount[currentColor]"
|
||||||
class="slider nodrag"
|
class="slider nodrag"
|
||||||
:style="{ '--color': color }"
|
:style="{ '--color': currentColor }"
|
||||||
type="range"
|
type="range"
|
||||||
min="0"
|
min="0"
|
||||||
max="255"
|
max="255"
|
||||||
@input="onChange"
|
@input="onChange"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Handle type="source" :position="Position.Right" :style="{ backgroundColor: color }" />
|
<Handle type="source" :position="Position.Right" :style="{ backgroundColor: color }" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ function capitalize(str: string) {
|
|||||||
return str.charAt(0).toUpperCase() + str.slice(1)
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
const typedocSidebarEntries = (): DefaultTheme.SidebarGroup[] => {
|
function typedocSidebarEntries(): DefaultTheme.SidebarGroup[] {
|
||||||
const filePath = resolve(__dirname, '../typedocs')
|
const filePath = resolve(__dirname, '../typedocs')
|
||||||
|
|
||||||
const docsModules = readdirSync(filePath).filter((name) => statSync(`${filePath}/${name}`).isDirectory())
|
const docsModules = readdirSync(filePath).filter((name) => statSync(`${filePath}/${name}`).isDirectory())
|
||||||
@@ -38,7 +38,7 @@ const typedocSidebarEntries = (): DefaultTheme.SidebarGroup[] => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const changelogSidebarEntries = (): DefaultTheme.SidebarGroup[] => {
|
function changelogSidebarEntries(): DefaultTheme.SidebarGroup[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
text: 'CHANGELOG',
|
text: 'CHANGELOG',
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ const dark = ref(false)
|
|||||||
* To update node properties you can simply use your elements v-model and mutate the elements directly
|
* To update node properties you can simply use your elements v-model and mutate the elements directly
|
||||||
* Changes should always be reflected on the graph reactively, without the need to overwrite the elements
|
* Changes should always be reflected on the graph reactively, without the need to overwrite the elements
|
||||||
*/
|
*/
|
||||||
const updatePos = () =>
|
function updatePos() {
|
||||||
elements.value.forEach((el) => {
|
return elements.value.forEach((el) => {
|
||||||
console.log(el, elements.value)
|
console.log(el, elements.value)
|
||||||
if (isNode(el)) {
|
if (isNode(el)) {
|
||||||
el.position = {
|
el.position = {
|
||||||
@@ -47,18 +47,23 @@ const updatePos = () =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toObject transforms your current graph data to an easily persist-able object
|
* toObject transforms your current graph data to an easily persist-able object
|
||||||
*/
|
*/
|
||||||
const logToObject = () => console.log(instance.value?.toObject())
|
function logToObject() {
|
||||||
|
return console.log(instance.value?.toObject())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the current viewpane transformation (zoom & pan)
|
* Resets the current viewpane transformation (zoom & pan)
|
||||||
*/
|
*/
|
||||||
const resetTransform = () => instance.value?.setTransform({ x: 0, y: 0, zoom: 1 })
|
function resetTransform() {
|
||||||
|
return instance.value?.setTransform({ x: 0, y: 0, zoom: 1 })
|
||||||
|
}
|
||||||
|
|
||||||
const toggleClass = () => {
|
function toggleClass() {
|
||||||
dark.value = !dark.value
|
dark.value = !dark.value
|
||||||
elements.value.forEach((el) => (el.class = dark.value ? 'dark' : 'light'))
|
elements.value.forEach((el) => (el.class = dark.value ? 'dark' : 'light'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ const dark = ref(false)
|
|||||||
* To update node properties you can simply use your elements v-model and mutate the elements directly
|
* To update node properties you can simply use your elements v-model and mutate the elements directly
|
||||||
* Changes should always be reflected on the graph reactively, without the need to overwrite the elements
|
* Changes should always be reflected on the graph reactively, without the need to overwrite the elements
|
||||||
*/
|
*/
|
||||||
const updatePos = () =>
|
function updatePos() {
|
||||||
elements.value.forEach((el) => {
|
return elements.value.forEach((el) => {
|
||||||
console.log(el, elements.value)
|
console.log(el, elements.value)
|
||||||
if (isNode(el)) {
|
if (isNode(el)) {
|
||||||
el.position = {
|
el.position = {
|
||||||
@@ -47,18 +47,23 @@ const updatePos = () =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toObject transforms your current graph data to an easily persist-able object
|
* toObject transforms your current graph data to an easily persist-able object
|
||||||
*/
|
*/
|
||||||
const logToObject = () => console.log(instance.value?.toObject())
|
function logToObject() {
|
||||||
|
return console.log(instance.value?.toObject())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the current viewpane transformation (zoom & pan)
|
* Resets the current viewpane transformation (zoom & pan)
|
||||||
*/
|
*/
|
||||||
const resetTransform = () => instance.value?.setTransform({ x: 0, y: 0, zoom: 1 })
|
function resetTransform() {
|
||||||
|
return instance.value?.setTransform({ x: 0, y: 0, zoom: 1 })
|
||||||
|
}
|
||||||
|
|
||||||
const toggleClass = () => {
|
function toggleClass() {
|
||||||
dark.value = !dark.value
|
dark.value = !dark.value
|
||||||
elements.value.forEach((el) => (el.class = dark.value ? 'dark' : 'light'))
|
elements.value.forEach((el) => (el.class = dark.value ? 'dark' : 'light'))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const router = useRouter()
|
|||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const onChange = (event: Event) => {
|
function onChange(event: Event) {
|
||||||
router.push((event.target as HTMLSelectElement).value)
|
router.push((event.target as HTMLSelectElement).value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ onNodeDragStop((e) => console.log('drag stop', e.event))
|
|||||||
onEdgeClick(console.log)
|
onEdgeClick(console.log)
|
||||||
onConnect((params) => addEdges([params]))
|
onConnect((params) => addEdges([params]))
|
||||||
|
|
||||||
const updatePos = () =>
|
function updatePos() {
|
||||||
elements.value.forEach((el) => {
|
return elements.value.forEach((el) => {
|
||||||
if (isNode(el)) {
|
if (isNode(el)) {
|
||||||
el.position = {
|
el.position = {
|
||||||
x: Math.random() * 400,
|
x: Math.random() * 400,
|
||||||
@@ -32,10 +32,17 @@ const updatePos = () =>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const logToObject = () => console.log(toObject())
|
function logToObject() {
|
||||||
const resetTransform = () => setTransform({ x: 0, y: 0, zoom: 1 })
|
return console.log(toObject())
|
||||||
const toggleclass = () => elements.value.forEach((el) => (el.class = el.class === 'light' ? 'dark' : 'light'))
|
}
|
||||||
|
function resetTransform() {
|
||||||
|
return setTransform({ x: 0, y: 0, zoom: 1 })
|
||||||
|
}
|
||||||
|
function toggleclass() {
|
||||||
|
return elements.value.forEach((el) => (el.class = el.class === 'light' ? 'dark' : 'light'))
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import { VueFlow, useVueFlow } from '@vue-flow/core'
|
|||||||
import Sidebar from './Sidebar.vue'
|
import Sidebar from './Sidebar.vue'
|
||||||
|
|
||||||
let id = 0
|
let id = 0
|
||||||
const getId = () => `dndnode_${id++}`
|
function getId() {
|
||||||
|
return `dndnode_${id++}`
|
||||||
|
}
|
||||||
|
|
||||||
const { onConnect, addEdges, addNodes, project } = useVueFlow({
|
const { onConnect, addEdges, addNodes, project } = useVueFlow({
|
||||||
nodes: [
|
nodes: [
|
||||||
@@ -16,7 +18,7 @@ const { onConnect, addEdges, addNodes, project } = useVueFlow({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
const onDragOver = (event: DragEvent) => {
|
function onDragOver(event: DragEvent) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
if (event.dataTransfer) {
|
if (event.dataTransfer) {
|
||||||
event.dataTransfer.dropEffect = 'move'
|
event.dataTransfer.dropEffect = 'move'
|
||||||
@@ -27,7 +29,7 @@ const wrapper = ref()
|
|||||||
|
|
||||||
onConnect((params) => addEdges([params]))
|
onConnect((params) => addEdges([params]))
|
||||||
|
|
||||||
const onDrop = (event: DragEvent) => {
|
function onDrop(event: DragEvent) {
|
||||||
const type = event.dataTransfer?.getData('application/vueflow')
|
const type = event.dataTransfer?.getData('application/vueflow')
|
||||||
|
|
||||||
const flowbounds = wrapper.value.$el.getBoundingClientRect()
|
const flowbounds = wrapper.value.$el.getBoundingClientRect()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const onDragStart = (event: DragEvent, nodeType: string) => {
|
function onDragStart(event: DragEvent, nodeType: string) {
|
||||||
if (event.dataTransfer) {
|
if (event.dataTransfer) {
|
||||||
event.dataTransfer.setData('application/vueflow', nodeType)
|
event.dataTransfer.setData('application/vueflow', nodeType)
|
||||||
event.dataTransfer.effectAllowed = 'move'
|
event.dataTransfer.effectAllowed = 'move'
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ const offsets = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
let id = 0
|
let id = 0
|
||||||
const getNodeId = () => (id++).toString()
|
function getNodeId() {
|
||||||
|
return (id++).toString()
|
||||||
|
}
|
||||||
|
|
||||||
export function getElements(): Elements {
|
export function getElements(): Elements {
|
||||||
const initialElements = []
|
const initialElements = []
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ onConnect((params) => addEdges([params]))
|
|||||||
onPaneReady((flowInstance) => console.log('flow loaded:', flowInstance))
|
onPaneReady((flowInstance) => console.log('flow loaded:', flowInstance))
|
||||||
onNodeDragStop((node) => console.log('drag stop', node))
|
onNodeDragStop((node) => console.log('drag stop', node))
|
||||||
|
|
||||||
const addRandomNode = () => {
|
function addRandomNode() {
|
||||||
const nodeId = (nodes.value.length + 1).toString()
|
const nodeId = (nodes.value.length + 1).toString()
|
||||||
const newNode: Node = {
|
const newNode: Node = {
|
||||||
id: nodeId,
|
id: nodeId,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const nodeExtent: CoordinateExtent = [
|
|||||||
|
|
||||||
const elements = ref<Elements>(initialElements)
|
const elements = ref<Elements>(initialElements)
|
||||||
|
|
||||||
const onLayout = (direction: string) => {
|
function onLayout(direction: string) {
|
||||||
const isHorizontal = direction === 'LR'
|
const isHorizontal = direction === 'LR'
|
||||||
dagreGraph.setGraph({ rankdir: direction })
|
dagreGraph.setGraph({ rankdir: direction })
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ onConnect((params) => addEdges([params]))
|
|||||||
|
|
||||||
onPaneReady((instance) => instance.fitView())
|
onPaneReady((instance) => instance.fitView())
|
||||||
|
|
||||||
const changeType = () => {
|
function changeType() {
|
||||||
elements.value.forEach((el) => {
|
elements.value.forEach((el) => {
|
||||||
if (isEdge(el) || el.type === 'input') return
|
if (isEdge(el) || el.type === 'input') return
|
||||||
el.type = el.type === 'default' ? 'output' : 'default'
|
el.type = el.type === 'default' ? 'output' : 'default'
|
||||||
|
|||||||
@@ -5,28 +5,62 @@ import { Background } from '@vue-flow/background'
|
|||||||
import { Controls } from '@vue-flow/controls'
|
import { Controls } from '@vue-flow/controls'
|
||||||
import { MiniMap } from '@vue-flow/minimap'
|
import { MiniMap } from '@vue-flow/minimap'
|
||||||
|
|
||||||
const onNodeDragStart = (e: FlowEvents['nodeDragStart']) => console.log('drag start', e)
|
function onNodeDragStart(e: FlowEvents['nodeDragStart']) {
|
||||||
const onNodeDrag = (e: FlowEvents['nodeDrag']) => console.log('drag', e)
|
return console.log('drag start', e)
|
||||||
const onNodeDragStop = (e: FlowEvents['nodeDragStop']) => console.log('drag stop', e)
|
}
|
||||||
const onNodeDoubleClick = (e: FlowEvents['nodeDoubleClick']) => console.log('node double click', e)
|
function onNodeDrag(e: FlowEvents['nodeDrag']) {
|
||||||
const onPaneClick = (e: FlowEvents['paneClick']) => console.log('pane click', e)
|
return console.log('drag', e)
|
||||||
const onPaneScroll = (e: FlowEvents['paneScroll']) => console.log('pane scroll', e)
|
}
|
||||||
const onPaneContextMenu = (e: FlowEvents['paneContextMenu']) => console.log('pane context menu', e)
|
function onNodeDragStop(e: FlowEvents['nodeDragStop']) {
|
||||||
const onSelectionDrag = (e: FlowEvents['selectionDrag']) => console.log('selection drag', e)
|
return console.log('drag stop', e)
|
||||||
const onSelectionDragStart = (e: FlowEvents['selectionDragStart']) => console.log('selection drag start', e)
|
}
|
||||||
const onSelectionDragStop = (e: FlowEvents['selectionDragStop']) => console.log('selection drag stop', e)
|
function onNodeDoubleClick(e: FlowEvents['nodeDoubleClick']) {
|
||||||
const onSelectionContextMenu = (e: FlowEvents['selectionContextMenu']) => console.log('selection context menu', e)
|
return console.log('node double click', e)
|
||||||
const onLoad = (flowInstance: VueFlowStore) => {
|
}
|
||||||
|
function onPaneClick(e: FlowEvents['paneClick']) {
|
||||||
|
return console.log('pane click', e)
|
||||||
|
}
|
||||||
|
function onPaneScroll(e: FlowEvents['paneScroll']) {
|
||||||
|
return console.log('pane scroll', e)
|
||||||
|
}
|
||||||
|
function onPaneContextMenu(e: FlowEvents['paneContextMenu']) {
|
||||||
|
return console.log('pane context menu', e)
|
||||||
|
}
|
||||||
|
function onSelectionDrag(e: FlowEvents['selectionDrag']) {
|
||||||
|
return console.log('selection drag', e)
|
||||||
|
}
|
||||||
|
function onSelectionDragStart(e: FlowEvents['selectionDragStart']) {
|
||||||
|
return console.log('selection drag start', e)
|
||||||
|
}
|
||||||
|
function onSelectionDragStop(e: FlowEvents['selectionDragStop']) {
|
||||||
|
return console.log('selection drag stop', e)
|
||||||
|
}
|
||||||
|
function onSelectionContextMenu(e: FlowEvents['selectionContextMenu']) {
|
||||||
|
return console.log('selection context menu', e)
|
||||||
|
}
|
||||||
|
function onLoad(flowInstance: VueFlowStore) {
|
||||||
console.log('flow loaded:', flowInstance)
|
console.log('flow loaded:', flowInstance)
|
||||||
flowInstance.fitView()
|
flowInstance.fitView()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onMoveEnd = (e: FlowEvents['moveEnd']) => console.log('zoom/move end', e.flowTransform)
|
function onMoveEnd(e: FlowEvents['moveEnd']) {
|
||||||
const onEdgeContextMenu = (e: FlowEvents['edgeContextMenu']) => console.log('edge context menu', e)
|
return console.log('zoom/move end', e.flowTransform)
|
||||||
const onEdgeMouseEnter = (e: FlowEvents['edgeMouseEnter']) => console.log('edge mouse enter', e)
|
}
|
||||||
const onEdgeMouseMove = (e: FlowEvents['edgeMouseMove']) => console.log('edge mouse move', e)
|
function onEdgeContextMenu(e: FlowEvents['edgeContextMenu']) {
|
||||||
const onEdgeMouseLeave = (e: FlowEvents['edgeMouseLeave']) => console.log('edge mouse leave', e)
|
return console.log('edge context menu', e)
|
||||||
const onEdgeDoubleClick = (e: FlowEvents['edgeDoubleClick']) => console.log('edge double click', e)
|
}
|
||||||
|
function onEdgeMouseEnter(e: FlowEvents['edgeMouseEnter']) {
|
||||||
|
return console.log('edge mouse enter', e)
|
||||||
|
}
|
||||||
|
function onEdgeMouseMove(e: FlowEvents['edgeMouseMove']) {
|
||||||
|
return console.log('edge mouse move', e)
|
||||||
|
}
|
||||||
|
function onEdgeMouseLeave(e: FlowEvents['edgeMouseLeave']) {
|
||||||
|
return console.log('edge mouse leave', e)
|
||||||
|
}
|
||||||
|
function onEdgeDoubleClick(e: FlowEvents['edgeDoubleClick']) {
|
||||||
|
return console.log('edge double click', e)
|
||||||
|
}
|
||||||
|
|
||||||
const initialElements: Elements = [
|
const initialElements: Elements = [
|
||||||
{
|
{
|
||||||
@@ -85,7 +119,7 @@ const initialElements: Elements = [
|
|||||||
|
|
||||||
const snapGrid: SnapGrid = [16, 16]
|
const snapGrid: SnapGrid = [16, 16]
|
||||||
|
|
||||||
const nodeStrokeColor = (n: Node): string => {
|
function nodeStrokeColor(n: Node): string {
|
||||||
if ((n.style as Styles)?.background) return (n.style as Styles).background as string
|
if ((n.style as Styles)?.background) return (n.style as Styles).background as string
|
||||||
if (n.type === 'input') return '#0041d0'
|
if (n.type === 'input') return '#0041d0'
|
||||||
if (n.type === 'output') return '#ff0072'
|
if (n.type === 'output') return '#ff0072'
|
||||||
@@ -94,7 +128,7 @@ const nodeStrokeColor = (n: Node): string => {
|
|||||||
return '#eee'
|
return '#eee'
|
||||||
}
|
}
|
||||||
|
|
||||||
const nodeColor = (n: Node): string => {
|
function nodeColor(n: Node): string {
|
||||||
if ((n.style as Styles)?.background) return (n.style as Styles).background as string
|
if ((n.style as Styles)?.background) return (n.style as Styles).background as string
|
||||||
|
|
||||||
return '#fff'
|
return '#fff'
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import '@vue-flow/controls/dist/style.css'
|
|||||||
|
|
||||||
import Sidebar from './Sidebar.vue'
|
import Sidebar from './Sidebar.vue'
|
||||||
|
|
||||||
const onLoad = (flowInstance: VueFlowStore) => console.log('flow loaded:', flowInstance)
|
function onLoad(flowInstance: VueFlowStore) {
|
||||||
|
return console.log('flow loaded:', flowInstance)
|
||||||
|
}
|
||||||
|
|
||||||
const initialElements: Elements = [
|
const initialElements: Elements = [
|
||||||
{ id: '1', type: 'input', label: 'Node 1', position: { x: 250, y: 5 } },
|
{ id: '1', type: 'input', label: 'Node 1', position: { x: 250, y: 5 } },
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { useVueFlow } from '@vue-flow/core'
|
import { useVueFlow } from '@vue-flow/core'
|
||||||
const { nodesSelectionActive, addSelectedNodes, getNodes, viewport } = useVueFlow()
|
const { nodesSelectionActive, addSelectedNodes, getNodes, viewport } = useVueFlow()
|
||||||
|
|
||||||
const selectAll = () => {
|
function selectAll() {
|
||||||
addSelectedNodes(getNodes.value)
|
addSelectedNodes(getNodes.value)
|
||||||
nodesSelectionActive.value = true
|
nodesSelectionActive.value = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { templateRef } from '@vueuse/core'
|
|
||||||
import type { Elements, VueFlowStore } from '@vue-flow/core'
|
import type { Elements, VueFlowStore } from '@vue-flow/core'
|
||||||
import { VueFlow } from '@vue-flow/core'
|
import { VueFlow } from '@vue-flow/core'
|
||||||
import RGBNode from './RGBNode.vue'
|
import RGBNode from './RGBNode.vue'
|
||||||
@@ -10,6 +9,7 @@ interface Colors {
|
|||||||
green: number
|
green: number
|
||||||
blue: number
|
blue: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const elements = ref<Elements>([
|
const elements = ref<Elements>([
|
||||||
{ id: '1', type: 'rgb', data: { color: 'r' }, position: { x: -25, y: 50 } },
|
{ id: '1', type: 'rgb', data: { color: 'r' }, position: { x: -25, y: 50 } },
|
||||||
{ id: '2', type: 'rgb', data: { color: 'g' }, position: { x: 50, y: -100 } },
|
{ id: '2', type: 'rgb', data: { color: 'g' }, position: { x: 50, y: -100 } },
|
||||||
@@ -20,21 +20,23 @@ const elements = ref<Elements>([
|
|||||||
{ id: 'e3-4', data: { color: 'blue' }, source: '3', target: '4', animated: true },
|
{ id: 'e3-4', data: { color: 'blue' }, source: '3', target: '4', animated: true },
|
||||||
])
|
])
|
||||||
|
|
||||||
const el = templateRef<HTMLDivElement>('page', null)
|
function onLoad(flowInstance: VueFlowStore) {
|
||||||
|
|
||||||
const onLoad = (flowInstance: VueFlowStore) => {
|
|
||||||
flowInstance.fitView({ padding: 1 })
|
flowInstance.fitView({ padding: 1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
const color = ref<Colors>({
|
const color = ref<Colors>({
|
||||||
red: 100,
|
red: 100,
|
||||||
green: 150,
|
green: 150,
|
||||||
blue: 100,
|
blue: 100,
|
||||||
})
|
})
|
||||||
const onChange = ({ color: c, val }: { color: keyof Colors; val: number }) => (color.value[c] = Number(val))
|
|
||||||
|
function onChange({ color: c, val }: { color: keyof Colors; val: number }) {
|
||||||
|
return (color.value[c] = Number(val))
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="page" class="demo-flow">
|
<div class="demo-flow">
|
||||||
<VueFlow v-model="elements" @pane-ready="onLoad">
|
<VueFlow v-model="elements" @pane-ready="onLoad">
|
||||||
<template #node-rgb="props">
|
<template #node-rgb="props">
|
||||||
<RGBNode v-bind="props" :amount="color" @change="onChange" />
|
<RGBNode v-bind="props" :amount="color" @change="onChange" />
|
||||||
|
|||||||
@@ -10,15 +10,17 @@ const state = useStorage<FlowExportObject>(flowKey, {
|
|||||||
zoom: 1,
|
zoom: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
const getNodeId = () => `randomnode_${+new Date()}`
|
function getNodeId() {
|
||||||
|
return `randomnode_${+new Date()}`
|
||||||
|
}
|
||||||
|
|
||||||
const { addNodes, setNodes, setEdges, toObject, dimensions, setTransform } = useVueFlow()
|
const { addNodes, setNodes, setEdges, toObject, dimensions, setTransform } = useVueFlow()
|
||||||
|
|
||||||
const onSave = () => {
|
function onSave() {
|
||||||
state.value = toObject()
|
state.value = toObject()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onRestore = () => {
|
function onRestore() {
|
||||||
const flow: FlowExportObject | null = state.value
|
const flow: FlowExportObject | null = state.value
|
||||||
|
|
||||||
if (flow) {
|
if (flow) {
|
||||||
@@ -32,7 +34,7 @@ const onRestore = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onAdd = () => {
|
function onAdd() {
|
||||||
const newNode = {
|
const newNode = {
|
||||||
id: `random_node-${getNodeId()}`,
|
id: `random_node-${getNodeId()}`,
|
||||||
label: 'Added node',
|
label: 'Added node',
|
||||||
|
|||||||
@@ -17,9 +17,11 @@ onPaneReady((i) => {
|
|||||||
console.log(i.getElements.value)
|
console.log(i.getElements.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
const toggleClass = () => elements.value.forEach((el) => (el.class = el.class === 'light' ? 'dark' : 'light'))
|
function toggleClass() {
|
||||||
|
return elements.value.forEach((el) => (el.class = el.class === 'light' ? 'dark' : 'light'))
|
||||||
|
}
|
||||||
|
|
||||||
const updatePos = () => {
|
function updatePos() {
|
||||||
elements.value.forEach((el) => {
|
elements.value.forEach((el) => {
|
||||||
if (isNode(el)) {
|
if (isNode(el)) {
|
||||||
el.position = {
|
el.position = {
|
||||||
|
|||||||
@@ -30,13 +30,21 @@ const { updateEdge } = useVueFlow()
|
|||||||
|
|
||||||
const elements = ref(initialElements)
|
const elements = ref(initialElements)
|
||||||
|
|
||||||
const onLoad = (flowInstance: VueFlowStore) => flowInstance.fitView()
|
function onLoad(flowInstance: VueFlowStore) {
|
||||||
|
return flowInstance.fitView()
|
||||||
|
}
|
||||||
|
|
||||||
const onEdgeUpdateStart = ({ edge }: FlowEvents['edgeUpdateStart']) => console.log('start update', edge)
|
function onEdgeUpdateStart({ edge }: FlowEvents['edgeUpdateStart']) {
|
||||||
|
return console.log('start update', edge)
|
||||||
|
}
|
||||||
|
|
||||||
const onEdgeUpdateEnd = ({ edge }: FlowEvents['edgeUpdateEnd']) => console.log('end update', edge)
|
function onEdgeUpdateEnd({ edge }: FlowEvents['edgeUpdateEnd']) {
|
||||||
|
return console.log('end update', edge)
|
||||||
|
}
|
||||||
|
|
||||||
const onEdgeUpdate = ({ edge, connection }: FlowEvents['edgeUpdate']) => updateEdge(edge, connection)
|
function onEdgeUpdate({ edge, connection }: FlowEvents['edgeUpdate']) {
|
||||||
|
return updateEdge(edge, connection)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const opts = reactive({
|
|||||||
hidden: false,
|
hidden: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const updateNode = () => {
|
function updateNode() {
|
||||||
elements.value.forEach((el) => {
|
elements.value.forEach((el) => {
|
||||||
if (el.id === '1') {
|
if (el.id === '1') {
|
||||||
// it's important that you create a new object here in order to notify react flow about the change
|
// it's important that you create a new object here in order to notify react flow about the change
|
||||||
|
|||||||
@@ -17,11 +17,17 @@ const { addEdges } = useVueFlow({
|
|||||||
{ id: 'C', type: 'customnode', position: { x: 250, y: 300 }, isValidSourcePos: (connection) => connection.target === 'B' },
|
{ id: 'C', type: 'customnode', position: { x: 250, y: 300 }, isValidSourcePos: (connection) => connection.target === 'B' },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
const onLoad = (flowInstance: VueFlowStore) => flowInstance.fitView()
|
function onLoad(flowInstance: VueFlowStore) {
|
||||||
const onConnectStart = ({ nodeId, handleType }: OnConnectStartParams) => console.log('on connect start', { nodeId, handleType })
|
return flowInstance.fitView()
|
||||||
const onConnectEnd = (event: MouseEvent) => console.log('on connect end', event)
|
}
|
||||||
|
function onConnectStart({ nodeId, handleType }: OnConnectStartParams) {
|
||||||
|
return console.log('on connect start', { nodeId, handleType })
|
||||||
|
}
|
||||||
|
function onConnectEnd(event: MouseEvent) {
|
||||||
|
return console.log('on connect end', event)
|
||||||
|
}
|
||||||
|
|
||||||
const onConnect = (params: Connection) => {
|
function onConnect(params: Connection) {
|
||||||
console.log('on connect', params)
|
console.log('on connect', params)
|
||||||
addEdges([params])
|
addEdges([params])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,22 +28,22 @@ const { nodesDraggable, nodesConnectable, elementsSelectable, setInteractive, zo
|
|||||||
|
|
||||||
const isInteractive = computed(() => nodesDraggable && nodesConnectable && elementsSelectable)
|
const isInteractive = computed(() => nodesDraggable && nodesConnectable && elementsSelectable)
|
||||||
|
|
||||||
const onZoomInHandler = () => {
|
function onZoomInHandler() {
|
||||||
zoomIn()
|
zoomIn()
|
||||||
emit('zoomIn')
|
emit('zoomIn')
|
||||||
}
|
}
|
||||||
|
|
||||||
const onZoomOutHandler = () => {
|
function onZoomOutHandler() {
|
||||||
zoomOut()
|
zoomOut()
|
||||||
emit('zoomOut')
|
emit('zoomOut')
|
||||||
}
|
}
|
||||||
|
|
||||||
const onFitViewHandler = () => {
|
function onFitViewHandler() {
|
||||||
fitView(fitViewParams)
|
fitView(fitViewParams)
|
||||||
emit('fitView')
|
emit('fitView')
|
||||||
}
|
}
|
||||||
|
|
||||||
const onInteractiveChangeHandler = () => {
|
function onInteractiveChangeHandler() {
|
||||||
setInteractive(!isInteractive.value)
|
setInteractive(!isInteractive.value)
|
||||||
emit('interactionChange', !isInteractive.value)
|
emit('interactionChange', !isInteractive.value)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const patchedSlots = `Record<string, (_: any) => any> & {
|
|||||||
[key: \`edge-\${string}\`]: (edgeProps: EdgeProps) => any
|
[key: \`edge-\${string}\`]: (edgeProps: EdgeProps) => any
|
||||||
}`
|
}`
|
||||||
|
|
||||||
const patchSlots = async () => {
|
async function patchSlots() {
|
||||||
const fileContents = await content(filePath)
|
const fileContents = await content(filePath)
|
||||||
|
|
||||||
const patchedFileContents = fileContents.replace(typeImportsString, patchedTypeImports).replace(unpatchedSlots, patchedSlots)
|
const patchedFileContents = fileContents.replace(typeImportsString, patchedTypeImports).replace(unpatchedSlots, patchedSlots)
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ interface Props extends HTMLAttributes {
|
|||||||
radius?: number
|
radius?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const shiftX = (x: number, shift: number, position: Position): number => {
|
function shiftX(x: number, shift: number, position: Position): number {
|
||||||
if (position === Position.Left) return x - shift
|
if (position === Position.Left) return x - shift
|
||||||
if (position === Position.Right) return x + shift
|
if (position === Position.Right) return x + shift
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
const shiftY = (y: number, shift: number, position: Position): number => {
|
function shiftY(y: number, shift: number, position: Position): number {
|
||||||
if (position === Position.Top) return y - shift
|
if (position === Position.Top) return y - shift
|
||||||
if (position === Position.Bottom) return y + shift
|
if (position === Position.Bottom) return y + shift
|
||||||
return y
|
return y
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const handleDirections = {
|
|||||||
[Position.Bottom]: { x: 0, y: 1 },
|
[Position.Bottom]: { x: 0, y: 1 },
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDirection = ({
|
function getDirection({
|
||||||
source,
|
source,
|
||||||
sourcePosition = Position.Bottom,
|
sourcePosition = Position.Bottom,
|
||||||
target,
|
target,
|
||||||
@@ -30,14 +30,16 @@ const getDirection = ({
|
|||||||
source: XYPosition
|
source: XYPosition
|
||||||
sourcePosition: Position
|
sourcePosition: Position
|
||||||
target: XYPosition
|
target: XYPosition
|
||||||
}): XYPosition => {
|
}): XYPosition {
|
||||||
if (sourcePosition === Position.Left || sourcePosition === Position.Right) {
|
if (sourcePosition === Position.Left || sourcePosition === Position.Right) {
|
||||||
return source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 }
|
return source.x < target.x ? { x: 1, y: 0 } : { x: -1, y: 0 }
|
||||||
}
|
}
|
||||||
return source.y < target.y ? { x: 0, y: 1 } : { x: 0, y: -1 }
|
return source.y < target.y ? { x: 0, y: 1 } : { x: 0, y: -1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
const distance = (a: XYPosition, b: XYPosition) => Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2)
|
function distance(a: XYPosition, b: XYPosition) {
|
||||||
|
return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2)
|
||||||
|
}
|
||||||
|
|
||||||
// With this function we try to mimic an orthogonal edge routing behaviour
|
// With this function we try to mimic an orthogonal edge routing behaviour
|
||||||
// It's not as good as a real orthogonal edge routing, but it's faster and good enough as a default for step and smooth step edges
|
// It's not as good as a real orthogonal edge routing, but it's faster and good enough as a default for step and smooth step edges
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import type { EdgeEventsEmit, EdgeEventsOn, GraphEdge, VueFlowStore } from '~/types'
|
import type { EdgeEventsEmit, EdgeEventsOn, GraphEdge, VueFlowStore } from '~/types'
|
||||||
|
|
||||||
const createEdgeHooks = () => ({
|
function createEdgeHooks() {
|
||||||
doubleClick: createExtendedEventHook(),
|
return {
|
||||||
click: createExtendedEventHook(),
|
doubleClick: createExtendedEventHook(),
|
||||||
mouseEnter: createExtendedEventHook(),
|
click: createExtendedEventHook(),
|
||||||
mouseMove: createExtendedEventHook(),
|
mouseEnter: createExtendedEventHook(),
|
||||||
mouseLeave: createExtendedEventHook(),
|
mouseMove: createExtendedEventHook(),
|
||||||
contextMenu: createExtendedEventHook(),
|
mouseLeave: createExtendedEventHook(),
|
||||||
updateStart: createExtendedEventHook(),
|
contextMenu: createExtendedEventHook(),
|
||||||
update: createExtendedEventHook(),
|
updateStart: createExtendedEventHook(),
|
||||||
updateEnd: createExtendedEventHook(),
|
update: createExtendedEventHook(),
|
||||||
})
|
updateEnd: createExtendedEventHook(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function useEdgeHooks(edge: GraphEdge, emits: VueFlowStore['emits']): { emit: EdgeEventsEmit; on: EdgeEventsOn } {
|
export default function useEdgeHooks(edge: GraphEdge, emits: VueFlowStore['emits']): { emit: EdgeEventsEmit; on: EdgeEventsOn } {
|
||||||
const edgeHooks = createEdgeHooks()
|
const edgeHooks = createEdgeHooks()
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ interface UseHandleProps {
|
|||||||
onEdgeUpdateEnd?: (event: MouseTouchEvent) => void
|
onEdgeUpdateEnd?: (event: MouseTouchEvent) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const alwaysValid = () => true
|
function alwaysValid() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
export default function useHandle({
|
export default function useHandle({
|
||||||
handleId: _handleId,
|
handleId: _handleId,
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import type { GraphNode, NodeEventsEmit, NodeEventsOn, VueFlowStore } from '~/types'
|
import type { GraphNode, NodeEventsEmit, NodeEventsOn, VueFlowStore } from '~/types'
|
||||||
|
|
||||||
const createNodeHooks = () => ({
|
function createNodeHooks() {
|
||||||
doubleClick: createExtendedEventHook(),
|
return {
|
||||||
click: createExtendedEventHook(),
|
doubleClick: createExtendedEventHook(),
|
||||||
mouseEnter: createExtendedEventHook(),
|
click: createExtendedEventHook(),
|
||||||
mouseMove: createExtendedEventHook(),
|
mouseEnter: createExtendedEventHook(),
|
||||||
mouseLeave: createExtendedEventHook(),
|
mouseMove: createExtendedEventHook(),
|
||||||
contextMenu: createExtendedEventHook(),
|
mouseLeave: createExtendedEventHook(),
|
||||||
dragStart: createExtendedEventHook(),
|
contextMenu: createExtendedEventHook(),
|
||||||
drag: createExtendedEventHook(),
|
dragStart: createExtendedEventHook(),
|
||||||
dragStop: createExtendedEventHook(),
|
drag: createExtendedEventHook(),
|
||||||
})
|
dragStop: createExtendedEventHook(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function useNodeHooks(node: GraphNode, emits: VueFlowStore['emits']): { emit: NodeEventsEmit; on: NodeEventsOn } {
|
export default function useNodeHooks(node: GraphNode, emits: VueFlowStore['emits']): { emit: NodeEventsEmit; on: NodeEventsOn } {
|
||||||
const nodeHooks = createNodeHooks()
|
const nodeHooks = createNodeHooks()
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ interface ExtendedViewport extends ViewportFunctions {
|
|||||||
|
|
||||||
const DEFAULT_PADDING = 0.1
|
const DEFAULT_PADDING = 0.1
|
||||||
|
|
||||||
const noop = () => {}
|
function noop() {}
|
||||||
|
|
||||||
const initialViewportHelper: ExtendedViewport = {
|
const initialViewportHelper: ExtendedViewport = {
|
||||||
zoomIn: noop,
|
zoomIn: noop,
|
||||||
|
|||||||
@@ -51,9 +51,15 @@ const groups = controlledComputed(
|
|||||||
() => groupEdgesByZLevel(getEdges, findNode, elevateEdgesOnSelect),
|
() => groupEdgesByZLevel(getEdges, findNode, elevateEdgesOnSelect),
|
||||||
)
|
)
|
||||||
|
|
||||||
const selectable = (edgeSelectable?: boolean) => (typeof edgeSelectable === 'undefined' ? elementsSelectable : edgeSelectable)
|
function selectable(edgeSelectable?: boolean) {
|
||||||
const updatable = (edgeUpdatable?: EdgeUpdatable) => (typeof edgeUpdatable === 'undefined' ? edgesUpdatable : edgeUpdatable)
|
return typeof edgeSelectable === 'undefined' ? elementsSelectable : edgeSelectable
|
||||||
const focusable = (edgeFocusable?: boolean) => (typeof edgeFocusable === 'undefined' ? edgesFocusable : edgeFocusable)
|
}
|
||||||
|
function updatable(edgeUpdatable?: EdgeUpdatable) {
|
||||||
|
return typeof edgeUpdatable === 'undefined' ? edgesUpdatable : edgeUpdatable
|
||||||
|
}
|
||||||
|
function focusable(edgeFocusable?: boolean) {
|
||||||
|
return typeof edgeFocusable === 'undefined' ? edgesFocusable : edgeFocusable
|
||||||
|
}
|
||||||
|
|
||||||
function getType(type?: string, template?: GraphEdge['template']) {
|
function getType(type?: string, template?: GraphEdge['template']) {
|
||||||
const name = type || 'default'
|
const name = type || 'default'
|
||||||
|
|||||||
@@ -44,11 +44,18 @@ onMounted(() => {
|
|||||||
|
|
||||||
onBeforeUnmount(() => resizeObserver?.disconnect())
|
onBeforeUnmount(() => resizeObserver?.disconnect())
|
||||||
|
|
||||||
const draggable = (nodeDraggable?: boolean) => (typeof nodeDraggable === 'undefined' ? nodesDraggable : nodeDraggable)
|
function draggable(nodeDraggable?: boolean) {
|
||||||
const selectable = (nodeSelectable?: boolean) => (typeof nodeSelectable === 'undefined' ? elementsSelectable : nodeSelectable)
|
return typeof nodeDraggable === 'undefined' ? nodesDraggable : nodeDraggable
|
||||||
const connectable = (nodeConnectable?: HandleConnectable) =>
|
}
|
||||||
typeof nodeConnectable === 'undefined' ? nodesConnectable : nodeConnectable
|
function selectable(nodeSelectable?: boolean) {
|
||||||
const focusable = (nodeFocusable?: boolean) => (typeof nodeFocusable === 'undefined' ? nodesFocusable : nodeFocusable)
|
return typeof nodeSelectable === 'undefined' ? elementsSelectable : nodeSelectable
|
||||||
|
}
|
||||||
|
function connectable(nodeConnectable?: HandleConnectable) {
|
||||||
|
return typeof nodeConnectable === 'undefined' ? nodesConnectable : nodeConnectable
|
||||||
|
}
|
||||||
|
function focusable(nodeFocusable?: boolean) {
|
||||||
|
return typeof nodeFocusable === 'undefined' ? nodesFocusable : nodeFocusable
|
||||||
|
}
|
||||||
|
|
||||||
function getType(type?: string, template?: GraphNode['template']) {
|
function getType(type?: string, template?: GraphNode['template']) {
|
||||||
const name = type || 'default'
|
const name = type || 'default'
|
||||||
|
|||||||
@@ -2,58 +2,60 @@ import type { Ref } from 'vue'
|
|||||||
import type { FlowHooks } from '~/types'
|
import type { FlowHooks } from '~/types'
|
||||||
|
|
||||||
// flow event hooks
|
// flow event hooks
|
||||||
export const createHooks = (): FlowHooks => ({
|
export function createHooks(): FlowHooks {
|
||||||
edgesChange: createExtendedEventHook(),
|
return {
|
||||||
nodesChange: createExtendedEventHook(),
|
edgesChange: createExtendedEventHook(),
|
||||||
nodeDoubleClick: createExtendedEventHook(),
|
nodesChange: createExtendedEventHook(),
|
||||||
nodeClick: createExtendedEventHook(),
|
nodeDoubleClick: createExtendedEventHook(),
|
||||||
nodeMouseEnter: createExtendedEventHook(),
|
nodeClick: createExtendedEventHook(),
|
||||||
nodeMouseMove: createExtendedEventHook(),
|
nodeMouseEnter: createExtendedEventHook(),
|
||||||
nodeMouseLeave: createExtendedEventHook(),
|
nodeMouseMove: createExtendedEventHook(),
|
||||||
nodeContextMenu: createExtendedEventHook(),
|
nodeMouseLeave: createExtendedEventHook(),
|
||||||
nodeDragStart: createExtendedEventHook(),
|
nodeContextMenu: createExtendedEventHook(),
|
||||||
nodeDrag: createExtendedEventHook(),
|
nodeDragStart: createExtendedEventHook(),
|
||||||
nodeDragStop: createExtendedEventHook(),
|
nodeDrag: createExtendedEventHook(),
|
||||||
nodesInitialized: createExtendedEventHook(),
|
nodeDragStop: createExtendedEventHook(),
|
||||||
miniMapNodeClick: createExtendedEventHook(),
|
nodesInitialized: createExtendedEventHook(),
|
||||||
miniMapNodeDoubleClick: createExtendedEventHook(),
|
miniMapNodeClick: createExtendedEventHook(),
|
||||||
miniMapNodeMouseEnter: createExtendedEventHook(),
|
miniMapNodeDoubleClick: createExtendedEventHook(),
|
||||||
miniMapNodeMouseMove: createExtendedEventHook(),
|
miniMapNodeMouseEnter: createExtendedEventHook(),
|
||||||
miniMapNodeMouseLeave: createExtendedEventHook(),
|
miniMapNodeMouseMove: createExtendedEventHook(),
|
||||||
connect: createExtendedEventHook(),
|
miniMapNodeMouseLeave: createExtendedEventHook(),
|
||||||
connectStart: createExtendedEventHook(),
|
connect: createExtendedEventHook(),
|
||||||
connectEnd: createExtendedEventHook(),
|
connectStart: createExtendedEventHook(),
|
||||||
paneReady: createExtendedEventHook(),
|
connectEnd: createExtendedEventHook(),
|
||||||
move: createExtendedEventHook(),
|
paneReady: createExtendedEventHook(),
|
||||||
moveStart: createExtendedEventHook(),
|
move: createExtendedEventHook(),
|
||||||
moveEnd: createExtendedEventHook(),
|
moveStart: createExtendedEventHook(),
|
||||||
selectionDragStart: createExtendedEventHook(),
|
moveEnd: createExtendedEventHook(),
|
||||||
selectionDrag: createExtendedEventHook(),
|
selectionDragStart: createExtendedEventHook(),
|
||||||
selectionDragStop: createExtendedEventHook(),
|
selectionDrag: createExtendedEventHook(),
|
||||||
selectionContextMenu: createExtendedEventHook(),
|
selectionDragStop: createExtendedEventHook(),
|
||||||
selectionStart: createExtendedEventHook(),
|
selectionContextMenu: createExtendedEventHook(),
|
||||||
selectionEnd: createExtendedEventHook(),
|
selectionStart: createExtendedEventHook(),
|
||||||
viewportChangeStart: createExtendedEventHook(),
|
selectionEnd: createExtendedEventHook(),
|
||||||
viewportChange: createExtendedEventHook(),
|
viewportChangeStart: createExtendedEventHook(),
|
||||||
viewportChangeEnd: createExtendedEventHook(),
|
viewportChange: createExtendedEventHook(),
|
||||||
paneScroll: createExtendedEventHook(),
|
viewportChangeEnd: createExtendedEventHook(),
|
||||||
paneClick: createExtendedEventHook(),
|
paneScroll: createExtendedEventHook(),
|
||||||
paneContextMenu: createExtendedEventHook(),
|
paneClick: createExtendedEventHook(),
|
||||||
paneMouseEnter: createExtendedEventHook(),
|
paneContextMenu: createExtendedEventHook(),
|
||||||
paneMouseMove: createExtendedEventHook(),
|
paneMouseEnter: createExtendedEventHook(),
|
||||||
paneMouseLeave: createExtendedEventHook(),
|
paneMouseMove: createExtendedEventHook(),
|
||||||
edgeContextMenu: createExtendedEventHook(),
|
paneMouseLeave: createExtendedEventHook(),
|
||||||
edgeMouseEnter: createExtendedEventHook(),
|
edgeContextMenu: createExtendedEventHook(),
|
||||||
edgeMouseMove: createExtendedEventHook(),
|
edgeMouseEnter: createExtendedEventHook(),
|
||||||
edgeMouseLeave: createExtendedEventHook(),
|
edgeMouseMove: createExtendedEventHook(),
|
||||||
edgeDoubleClick: createExtendedEventHook(),
|
edgeMouseLeave: createExtendedEventHook(),
|
||||||
edgeClick: createExtendedEventHook(),
|
edgeDoubleClick: createExtendedEventHook(),
|
||||||
edgeUpdateStart: createExtendedEventHook(),
|
edgeClick: createExtendedEventHook(),
|
||||||
edgeUpdate: createExtendedEventHook(),
|
edgeUpdateStart: createExtendedEventHook(),
|
||||||
edgeUpdateEnd: createExtendedEventHook(),
|
edgeUpdate: createExtendedEventHook(),
|
||||||
updateNodeInternals: createExtendedEventHook(),
|
edgeUpdateEnd: createExtendedEventHook(),
|
||||||
error: createExtendedEventHook((err) => warn(err.message)),
|
updateNodeInternals: createExtendedEventHook(),
|
||||||
})
|
error: createExtendedEventHook((err) => warn(err.message)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function useHooks(emit: (...args: any[]) => void, hooks: Ref<FlowHooks>) {
|
export function useHooks(emit: (...args: any[]) => void, hooks: Ref<FlowHooks>) {
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
|
|||||||
@@ -25,114 +25,116 @@ export const defaultEdgeTypes: DefaultEdgeTypes = {
|
|||||||
simplebezier: SimpleBezierEdge,
|
simplebezier: SimpleBezierEdge,
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultState = (): State => ({
|
function defaultState(): State {
|
||||||
vueFlowRef: null,
|
return {
|
||||||
viewportRef: null,
|
vueFlowRef: null,
|
||||||
nodes: [],
|
viewportRef: null,
|
||||||
edges: [],
|
nodes: [],
|
||||||
nodeTypes: {},
|
edges: [],
|
||||||
edgeTypes: {},
|
nodeTypes: {},
|
||||||
|
edgeTypes: {},
|
||||||
|
|
||||||
initialized: false,
|
initialized: false,
|
||||||
|
|
||||||
dimensions: {
|
dimensions: {
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
},
|
},
|
||||||
viewport: { x: 0, y: 0, zoom: 1 },
|
viewport: { x: 0, y: 0, zoom: 1 },
|
||||||
|
|
||||||
d3Zoom: null,
|
d3Zoom: null,
|
||||||
d3Selection: null,
|
d3Selection: null,
|
||||||
d3ZoomHandler: null,
|
d3ZoomHandler: null,
|
||||||
minZoom: 0.5,
|
minZoom: 0.5,
|
||||||
maxZoom: 2,
|
maxZoom: 2,
|
||||||
|
|
||||||
translateExtent: [
|
translateExtent: [
|
||||||
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
||||||
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
||||||
],
|
],
|
||||||
nodeExtent: [
|
nodeExtent: [
|
||||||
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
[Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
||||||
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
[Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
||||||
],
|
],
|
||||||
|
|
||||||
selectionMode: SelectionMode.Full,
|
selectionMode: SelectionMode.Full,
|
||||||
paneDragging: false,
|
paneDragging: false,
|
||||||
preventScrolling: true,
|
preventScrolling: true,
|
||||||
zoomOnScroll: true,
|
zoomOnScroll: true,
|
||||||
zoomOnPinch: true,
|
zoomOnPinch: true,
|
||||||
zoomOnDoubleClick: true,
|
zoomOnDoubleClick: true,
|
||||||
panOnScroll: false,
|
panOnScroll: false,
|
||||||
panOnScrollSpeed: 0.5,
|
panOnScrollSpeed: 0.5,
|
||||||
panOnScrollMode: PanOnScrollMode.Free,
|
panOnScrollMode: PanOnScrollMode.Free,
|
||||||
panOnDrag: true,
|
panOnDrag: true,
|
||||||
edgeUpdaterRadius: 10,
|
edgeUpdaterRadius: 10,
|
||||||
onlyRenderVisibleElements: false,
|
onlyRenderVisibleElements: false,
|
||||||
defaultViewport: { x: 0, y: 0, zoom: 1 },
|
defaultViewport: { x: 0, y: 0, zoom: 1 },
|
||||||
|
|
||||||
nodesSelectionActive: false,
|
nodesSelectionActive: false,
|
||||||
userSelectionActive: false,
|
userSelectionActive: false,
|
||||||
|
|
||||||
userSelectionRect: null,
|
userSelectionRect: null,
|
||||||
|
|
||||||
defaultMarkerColor: '#b1b1b7',
|
defaultMarkerColor: '#b1b1b7',
|
||||||
connectionLineStyle: {},
|
connectionLineStyle: {},
|
||||||
connectionLineType: null,
|
connectionLineType: null,
|
||||||
connectionLineOptions: {
|
connectionLineOptions: {
|
||||||
type: ConnectionLineType.Bezier,
|
type: ConnectionLineType.Bezier,
|
||||||
style: {},
|
style: {},
|
||||||
},
|
},
|
||||||
connectionMode: ConnectionMode.Loose,
|
connectionMode: ConnectionMode.Loose,
|
||||||
connectionStartHandle: null,
|
connectionStartHandle: null,
|
||||||
connectionClickStartHandle: null,
|
connectionClickStartHandle: null,
|
||||||
connectionPosition: { x: NaN, y: NaN },
|
connectionPosition: { x: NaN, y: NaN },
|
||||||
connectionRadius: 20,
|
connectionRadius: 20,
|
||||||
connectOnClick: true,
|
connectOnClick: true,
|
||||||
connectionStatus: null,
|
connectionStatus: null,
|
||||||
isValidConnection: null,
|
isValidConnection: null,
|
||||||
|
|
||||||
snapGrid: [15, 15],
|
snapGrid: [15, 15],
|
||||||
snapToGrid: false,
|
snapToGrid: false,
|
||||||
|
|
||||||
edgesUpdatable: false,
|
edgesUpdatable: false,
|
||||||
edgesFocusable: true,
|
edgesFocusable: true,
|
||||||
nodesFocusable: true,
|
nodesFocusable: true,
|
||||||
nodesConnectable: true,
|
nodesConnectable: true,
|
||||||
nodesDraggable: true,
|
nodesDraggable: true,
|
||||||
elementsSelectable: true,
|
elementsSelectable: true,
|
||||||
selectNodesOnDrag: true,
|
selectNodesOnDrag: true,
|
||||||
multiSelectionActive: false,
|
multiSelectionActive: false,
|
||||||
selectionKeyCode: 'Shift',
|
selectionKeyCode: 'Shift',
|
||||||
multiSelectionKeyCode: 'Meta',
|
multiSelectionKeyCode: 'Meta',
|
||||||
zoomActivationKeyCode: 'Meta',
|
zoomActivationKeyCode: 'Meta',
|
||||||
deleteKeyCode: 'Backspace',
|
deleteKeyCode: 'Backspace',
|
||||||
panActivationKeyCode: 'Space',
|
panActivationKeyCode: 'Space',
|
||||||
|
|
||||||
hooks: createHooks(),
|
hooks: createHooks(),
|
||||||
|
|
||||||
applyDefault: true,
|
applyDefault: true,
|
||||||
autoConnect: false,
|
autoConnect: false,
|
||||||
|
|
||||||
fitViewOnInit: false,
|
fitViewOnInit: false,
|
||||||
noDragClassName: 'nodrag',
|
noDragClassName: 'nodrag',
|
||||||
noWheelClassName: 'nowheel',
|
noWheelClassName: 'nowheel',
|
||||||
noPanClassName: 'nopan',
|
noPanClassName: 'nopan',
|
||||||
defaultEdgeOptions: undefined,
|
defaultEdgeOptions: undefined,
|
||||||
elevateEdgesOnSelect: false,
|
elevateEdgesOnSelect: false,
|
||||||
elevateNodesOnSelect: true,
|
elevateNodesOnSelect: true,
|
||||||
|
|
||||||
autoPanOnNodeDrag: true,
|
autoPanOnNodeDrag: true,
|
||||||
autoPanOnConnect: true,
|
autoPanOnConnect: true,
|
||||||
|
|
||||||
disableKeyboardA11y: false,
|
disableKeyboardA11y: false,
|
||||||
ariaLiveMessage: '',
|
ariaLiveMessage: '',
|
||||||
|
|
||||||
__experimentalFeatures: {
|
__experimentalFeatures: {
|
||||||
nestedFlow: false,
|
nestedFlow: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
vueFlowVersion: typeof __VUE_FLOW_VERSION__ !== 'undefined' ? __VUE_FLOW_VERSION__ : '-',
|
vueFlowVersion: typeof __VUE_FLOW_VERSION__ !== 'undefined' ? __VUE_FLOW_VERSION__ : '-',
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function useState(opts?: FlowOptions): State {
|
export function useState(opts?: FlowOptions): State {
|
||||||
const state = defaultState()
|
const state = defaultState()
|
||||||
|
|||||||
@@ -185,30 +185,37 @@ export function applyChanges<
|
|||||||
return elements
|
return elements
|
||||||
}
|
}
|
||||||
|
|
||||||
export const applyEdgeChanges = (changes: EdgeChange[], edges: GraphEdge[]) => applyChanges(changes, edges)
|
export function applyEdgeChanges(changes: EdgeChange[], edges: GraphEdge[]) {
|
||||||
export const applyNodeChanges = (changes: NodeChange[], nodes: GraphNode[]) => applyChanges(changes, nodes)
|
return applyChanges(changes, edges)
|
||||||
|
}
|
||||||
|
export function applyNodeChanges(changes: NodeChange[], nodes: GraphNode[]) {
|
||||||
|
return applyChanges(changes, nodes)
|
||||||
|
}
|
||||||
|
|
||||||
export const createSelectionChange = (id: string, selected: boolean): NodeSelectionChange | EdgeSelectionChange => ({
|
export function createSelectionChange(id: string, selected: boolean): NodeSelectionChange | EdgeSelectionChange {
|
||||||
id,
|
return {
|
||||||
type: 'select',
|
id,
|
||||||
selected,
|
type: 'select',
|
||||||
})
|
selected,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const createAdditionChange = <
|
export function createAdditionChange<
|
||||||
T extends GraphNode | GraphEdge = GraphNode,
|
T extends GraphNode | GraphEdge = GraphNode,
|
||||||
C extends NodeAddChange | EdgeAddChange = T extends GraphNode ? NodeAddChange : EdgeAddChange,
|
C extends NodeAddChange | EdgeAddChange = T extends GraphNode ? NodeAddChange : EdgeAddChange,
|
||||||
>(
|
>(item: T): C {
|
||||||
item: T,
|
return <C>{
|
||||||
): C =>
|
|
||||||
<C>{
|
|
||||||
item,
|
item,
|
||||||
type: 'add',
|
type: 'add',
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const createRemoveChange = (id: string): NodeRemoveChange | EdgeRemoveChange => ({
|
export function createRemoveChange(id: string): NodeRemoveChange | EdgeRemoveChange {
|
||||||
id,
|
return {
|
||||||
type: 'remove',
|
id,
|
||||||
})
|
type: 'remove',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getSelectionChanges(elements: FlowElements, selectedIds: string[]) {
|
export function getSelectionChanges(elements: FlowElements, selectedIds: string[]) {
|
||||||
return elements.reduce(
|
return elements.reduce(
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export const isMouseEvent = (event: MouseEvent | TouchEvent): event is MouseEvent => 'clientX' in event
|
export function isMouseEvent(event: MouseEvent | TouchEvent): event is MouseEvent {
|
||||||
|
return 'clientX' in event
|
||||||
|
}
|
||||||
|
|
||||||
export function getEventPosition(event: MouseEvent | TouchEvent, bounds?: DOMRect) {
|
export function getEventPosition(event: MouseEvent | TouchEvent, bounds?: DOMRect) {
|
||||||
const isMouseTriggered = isMouseEvent(event)
|
const isMouseTriggered = isMouseEvent(event)
|
||||||
|
|||||||
@@ -21,11 +21,13 @@ import type {
|
|||||||
XYZPosition,
|
XYZPosition,
|
||||||
} from '~/types'
|
} from '~/types'
|
||||||
|
|
||||||
export const nodeToRect = (node: GraphNode): Rect => ({
|
export function nodeToRect(node: GraphNode): Rect {
|
||||||
...(node.computedPosition || { x: 0, y: 0 }),
|
return {
|
||||||
width: node.dimensions.width || 0,
|
...(node.computedPosition || { x: 0, y: 0 }),
|
||||||
height: node.dimensions.height || 0,
|
width: node.dimensions.width || 0,
|
||||||
})
|
height: node.dimensions.height || 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getOverlappingArea(rectA: Rect, rectB: Rect) {
|
export function getOverlappingArea(rectA: Rect, rectB: Rect) {
|
||||||
const xOverlap = Math.max(0, Math.min(rectA.x + rectA.width, rectB.x + rectB.width) - Math.max(rectA.x, rectB.x))
|
const xOverlap = Math.max(0, Math.min(rectA.x + rectA.width, rectB.x + rectB.width) - Math.max(rectA.x, rectB.x))
|
||||||
@@ -34,17 +36,23 @@ export function getOverlappingArea(rectA: Rect, rectB: Rect) {
|
|||||||
return Math.ceil(xOverlap * yOverlap)
|
return Math.ceil(xOverlap * yOverlap)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getDimensions = (node: HTMLElement): Dimensions => ({
|
export function getDimensions(node: HTMLElement): Dimensions {
|
||||||
width: node.offsetWidth,
|
return {
|
||||||
height: node.offsetHeight,
|
width: node.offsetWidth,
|
||||||
})
|
height: node.offsetHeight,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const clamp = (val: number, min = 0, max = 1) => Math.min(Math.max(val, min), max)
|
export function clamp(val: number, min = 0, max = 1) {
|
||||||
|
return Math.min(Math.max(val, min), max)
|
||||||
|
}
|
||||||
|
|
||||||
export const clampPosition = (position: XYPosition, extent: CoordinateExtent): XYPosition => ({
|
export function clampPosition(position: XYPosition, extent: CoordinateExtent): XYPosition {
|
||||||
x: clamp(position.x, extent[0][0], extent[1][0]),
|
return {
|
||||||
y: clamp(position.y, extent[0][1], extent[1][1]),
|
x: clamp(position.x, extent[0][0], extent[1][0]),
|
||||||
})
|
y: clamp(position.y, extent[0][1], extent[1][1]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getHostForElement(element: HTMLElement): Document {
|
export function getHostForElement(element: HTMLElement): Document {
|
||||||
const doc = element.getRootNode() as Document
|
const doc = element.getRootNode() as Document
|
||||||
@@ -54,19 +62,25 @@ export function getHostForElement(element: HTMLElement): Document {
|
|||||||
else return window.document
|
else return window.document
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isEdge = <Data = ElementData>(element: MaybeElement): element is Edge<Data> =>
|
export function isEdge<Data = ElementData>(element: MaybeElement): element is Edge<Data> {
|
||||||
element && 'id' in element && 'source' in element && 'target' in element
|
return element && 'id' in element && 'source' in element && 'target' in element
|
||||||
|
}
|
||||||
|
|
||||||
export const isGraphEdge = <Data = ElementData>(element: MaybeElement): element is GraphEdge<Data> =>
|
export function isGraphEdge<Data = ElementData>(element: MaybeElement): element is GraphEdge<Data> {
|
||||||
isEdge(element) && 'sourceNode' in element && 'targetNode' in element
|
return isEdge(element) && 'sourceNode' in element && 'targetNode' in element
|
||||||
|
}
|
||||||
|
|
||||||
export const isNode = <Data = ElementData>(element: MaybeElement): element is Node<Data> =>
|
export function isNode<Data = ElementData>(element: MaybeElement): element is Node<Data> {
|
||||||
element && 'id' in element && !isEdge(element)
|
return element && 'id' in element && !isEdge(element)
|
||||||
|
}
|
||||||
|
|
||||||
export const isGraphNode = <Data = ElementData>(element: MaybeElement): element is GraphNode<Data> =>
|
export function isGraphNode<Data = ElementData>(element: MaybeElement): element is GraphNode<Data> {
|
||||||
isNode(element) && 'computedPosition' in element
|
return isNode(element) && 'computedPosition' in element
|
||||||
|
}
|
||||||
|
|
||||||
export const isRect = (obj: any): obj is Rect => !!obj.width && !!obj.height && !!obj.x && !!obj.y
|
export function isRect(obj: any): obj is Rect {
|
||||||
|
return !!obj.width && !!obj.height && !!obj.x && !!obj.y
|
||||||
|
}
|
||||||
|
|
||||||
export function parseNode(node: Node, defaults: Partial<GraphNode> = {}): GraphNode {
|
export function parseNode(node: Node, defaults: Partial<GraphNode> = {}): GraphNode {
|
||||||
let initialState = defaults
|
let initialState = defaults
|
||||||
@@ -128,27 +142,30 @@ export function parseEdge(edge: Edge, defaults: Partial<GraphEdge> = {}): GraphE
|
|||||||
return Object.assign({}, defaults, edge, { id: edge.id.toString() }) as GraphEdge
|
return Object.assign({}, defaults, edge, { id: edge.id.toString() }) as GraphEdge
|
||||||
}
|
}
|
||||||
|
|
||||||
const getConnectedElements = <T extends Elements = FlowElements>(
|
function getConnectedElements<T extends Elements = FlowElements>(
|
||||||
node: Node,
|
node: Node,
|
||||||
elements: T,
|
elements: T,
|
||||||
dir: 'source' | 'target',
|
dir: 'source' | 'target',
|
||||||
): T extends FlowElements ? GraphNode[] : Node[] => {
|
): T extends FlowElements ? GraphNode[] : Node[] {
|
||||||
if (!isNode(node)) return []
|
if (!isNode(node)) return []
|
||||||
const origin = dir === 'source' ? 'target' : 'source'
|
const origin = dir === 'source' ? 'target' : 'source'
|
||||||
const ids = elements.filter((e) => isEdge(e) && e[origin] === node.id).map((e) => isEdge(e) && e[dir])
|
const ids = elements.filter((e) => isEdge(e) && e[origin] === node.id).map((e) => isEdge(e) && e[dir])
|
||||||
return elements.filter((e) => ids.includes(e.id)) as T extends FlowElements ? GraphNode[] : Node[]
|
return elements.filter((e) => ids.includes(e.id)) as T extends FlowElements ? GraphNode[] : Node[]
|
||||||
}
|
}
|
||||||
export const getOutgoers = <T extends Elements = FlowElements>(node: Node, elements: T) =>
|
export function getOutgoers<T extends Elements = FlowElements>(node: Node, elements: T) {
|
||||||
getConnectedElements(node, elements, 'target')
|
return getConnectedElements(node, elements, 'target')
|
||||||
|
}
|
||||||
|
|
||||||
export const getIncomers = <T extends Elements = FlowElements>(node: Node, elements: T) =>
|
export function getIncomers<T extends Elements = FlowElements>(node: Node, elements: T) {
|
||||||
getConnectedElements(node, elements, 'source')
|
return getConnectedElements(node, elements, 'source')
|
||||||
|
}
|
||||||
|
|
||||||
export const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection) =>
|
export function getEdgeId({ source, sourceHandle, target, targetHandle }: Connection) {
|
||||||
`vueflow__edge-${source}${sourceHandle ?? ''}-${target}${targetHandle ?? ''}`
|
return `vueflow__edge-${source}${sourceHandle ?? ''}-${target}${targetHandle ?? ''}`
|
||||||
|
}
|
||||||
|
|
||||||
export const connectionExists = (edge: Edge | Connection, elements: Elements) =>
|
export function connectionExists(edge: Edge | Connection, elements: Elements) {
|
||||||
elements.some(
|
return elements.some(
|
||||||
(el) =>
|
(el) =>
|
||||||
isEdge(el) &&
|
isEdge(el) &&
|
||||||
el.source === edge.source &&
|
el.source === edge.source &&
|
||||||
@@ -156,6 +173,7 @@ export const connectionExists = (edge: Edge | Connection, elements: Elements) =>
|
|||||||
(el.sourceHandle === edge.sourceHandle || (!el.sourceHandle && !edge.sourceHandle)) &&
|
(el.sourceHandle === edge.sourceHandle || (!el.sourceHandle && !edge.sourceHandle)) &&
|
||||||
(el.targetHandle === edge.targetHandle || (!el.targetHandle && !edge.targetHandle)),
|
(el.targetHandle === edge.targetHandle || (!el.targetHandle && !edge.targetHandle)),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use store instance and call `addEdges` with template-ref or the one received by `onPaneReady` instead
|
* @deprecated Use store instance and call `addEdges` with template-ref or the one received by `onPaneReady` instead
|
||||||
@@ -249,28 +267,36 @@ export function pointToRendererPoint(
|
|||||||
return position
|
return position
|
||||||
}
|
}
|
||||||
|
|
||||||
const getBoundsOfBoxes = (box1: Box, box2: Box): Box => ({
|
function getBoundsOfBoxes(box1: Box, box2: Box): Box {
|
||||||
x: Math.min(box1.x, box2.x),
|
return {
|
||||||
y: Math.min(box1.y, box2.y),
|
x: Math.min(box1.x, box2.x),
|
||||||
x2: Math.max(box1.x2, box2.x2),
|
y: Math.min(box1.y, box2.y),
|
||||||
y2: Math.max(box1.y2, box2.y2),
|
x2: Math.max(box1.x2, box2.x2),
|
||||||
})
|
y2: Math.max(box1.y2, box2.y2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const rectToBox = ({ x, y, width, height }: Rect): Box => ({
|
export function rectToBox({ x, y, width, height }: Rect): Box {
|
||||||
x,
|
return {
|
||||||
y,
|
x,
|
||||||
x2: x + width,
|
y,
|
||||||
y2: y + height,
|
x2: x + width,
|
||||||
})
|
y2: y + height,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const boxToRect = ({ x, y, x2, y2 }: Box): Rect => ({
|
export function boxToRect({ x, y, x2, y2 }: Box): Rect {
|
||||||
x,
|
return {
|
||||||
y,
|
x,
|
||||||
width: x2 - x,
|
y,
|
||||||
height: y2 - y,
|
width: x2 - x,
|
||||||
})
|
height: y2 - y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const getBoundsofRects = (rect1: Rect, rect2: Rect) => boxToRect(getBoundsOfBoxes(rectToBox(rect1), rectToBox(rect2)))
|
export function getBoundsofRects(rect1: Rect, rect2: Rect) {
|
||||||
|
return boxToRect(getBoundsOfBoxes(rectToBox(rect1), rectToBox(rect2)))
|
||||||
|
}
|
||||||
|
|
||||||
export function getRectOfNodes(nodes: GraphNode[]) {
|
export function getRectOfNodes(nodes: GraphNode[]) {
|
||||||
const box = nodes.reduce(
|
const box = nodes.reduce(
|
||||||
@@ -288,10 +314,12 @@ export function getRectOfNodes(nodes: GraphNode[]) {
|
|||||||
return boxToRect(box)
|
return boxToRect(box)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const graphPosToZoomedPos = ({ x, y }: XYPosition, { x: tx, y: ty, zoom: tScale }: ViewportTransform): XYPosition => ({
|
export function graphPosToZoomedPos({ x, y }: XYPosition, { x: tx, y: ty, zoom: tScale }: ViewportTransform): XYPosition {
|
||||||
x: x * tScale + tx,
|
return {
|
||||||
y: y * tScale + ty,
|
x: x * tScale + tx,
|
||||||
})
|
y: y * tScale + ty,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getNodesInside(
|
export function getNodesInside(
|
||||||
nodes: GraphNode[],
|
nodes: GraphNode[],
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import type { Actions, Connection, Edge, GraphEdge, GraphNode, Node, State } from '~/types'
|
import type { Actions, Connection, Edge, GraphEdge, GraphNode, Node, State } from '~/types'
|
||||||
|
|
||||||
export const isDef = <T>(val: T): val is NonNullable<T> => typeof unref(val) !== 'undefined'
|
export function isDef<T>(val: T): val is NonNullable<T> {
|
||||||
|
return typeof unref(val) !== 'undefined'
|
||||||
|
}
|
||||||
|
|
||||||
export function addEdgeToStore(edgeParams: Edge | Connection, edges: Edge[], onError: State['hooks']['error']['trigger']) {
|
export function addEdgeToStore(edgeParams: Edge | Connection, edges: Edge[], onError: State['hooks']['error']['trigger']) {
|
||||||
if (!edgeParams.source || !edgeParams.target) {
|
if (!edgeParams.source || !edgeParams.target) {
|
||||||
|
|||||||
@@ -152,36 +152,36 @@ watchEffect(
|
|||||||
{ flush: 'post' },
|
{ flush: 'post' },
|
||||||
)
|
)
|
||||||
|
|
||||||
const onSvgClick = (event: MouseEvent) => {
|
function onSvgClick(event: MouseEvent) {
|
||||||
const [x, y] = pointer(event)
|
const [x, y] = pointer(event)
|
||||||
emit('click', { event, position: { x, y } })
|
emit('click', { event, position: { x, y } })
|
||||||
}
|
}
|
||||||
|
|
||||||
const onNodeClick = (event: MouseEvent, node: GraphNode) => {
|
function onNodeClick(event: MouseEvent, node: GraphNode) {
|
||||||
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
||||||
emits.miniMapNodeClick(param)
|
emits.miniMapNodeClick(param)
|
||||||
emit('nodeClick', param)
|
emit('nodeClick', param)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onNodeDblClick = (event: MouseEvent, node: GraphNode) => {
|
function onNodeDblClick(event: MouseEvent, node: GraphNode) {
|
||||||
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
||||||
emits.miniMapNodeDoubleClick(param)
|
emits.miniMapNodeDoubleClick(param)
|
||||||
emit('nodeDblclick', param)
|
emit('nodeDblclick', param)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onNodeMouseEnter = (event: MouseEvent, node: GraphNode) => {
|
function onNodeMouseEnter(event: MouseEvent, node: GraphNode) {
|
||||||
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
||||||
emits.miniMapNodeMouseEnter(param)
|
emits.miniMapNodeMouseEnter(param)
|
||||||
emit('nodeMouseenter', param)
|
emit('nodeMouseenter', param)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onNodeMouseMove = (event: MouseEvent, node: GraphNode) => {
|
function onNodeMouseMove(event: MouseEvent, node: GraphNode) {
|
||||||
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
||||||
emits.miniMapNodeMouseMove(param)
|
emits.miniMapNodeMouseMove(param)
|
||||||
emit('nodeMousemove', param)
|
emit('nodeMousemove', param)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onNodeMouseLeave = (event: MouseEvent, node: GraphNode) => {
|
function onNodeMouseLeave(event: MouseEvent, node: GraphNode) {
|
||||||
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
const param = { event, node, connectedEdges: getConnectedEdges([node], edges.value) }
|
||||||
emits.miniMapNodeMouseLeave(param)
|
emits.miniMapNodeMouseLeave(param)
|
||||||
emit('nodeMouseleave', param)
|
emit('nodeMouseleave', param)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export interface PointInfo {
|
|||||||
position: Position
|
position: Position
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createGrid = (graph: GraphBoundingBox, nodes: NodeBoundingBox[], source: PointInfo, target: PointInfo) => {
|
export function createGrid(graph: GraphBoundingBox, nodes: NodeBoundingBox[], source: PointInfo, target: PointInfo) {
|
||||||
const { xMin, yMin, width, height } = graph
|
const { xMin, yMin, width, height } = graph
|
||||||
|
|
||||||
// Create a grid representation of the graph box, where each cell is
|
// Create a grid representation of the graph box, where each cell is
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ import type { XYPosition } from '@vue-flow/core'
|
|||||||
* Draws an SVG path from a list of points, using straight lines.
|
* Draws an SVG path from a list of points, using straight lines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const getMidPoint = (Ax: number, Ay: number, Bx: number, By: number) => {
|
function getMidPoint(Ax: number, Ay: number, Bx: number, By: number) {
|
||||||
const Zx = (Ax - Bx) / 2 + Bx
|
const Zx = (Ax - Bx) / 2 + Bx
|
||||||
const Zy = (Ay - By) / 2 + By
|
const Zy = (Ay - By) / 2 + By
|
||||||
return [Zx, Zy]
|
return [Zx, Zy]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const drawStraightLinePath = (source: XYPosition, target: XYPosition, path: number[][]) => {
|
export function drawStraightLinePath(source: XYPosition, target: XYPosition, path: number[][]) {
|
||||||
let svgPathString = `M ${source.x}, ${source.y} `
|
let svgPathString = `M ${source.x}, ${source.y} `
|
||||||
|
|
||||||
path.forEach((point) => {
|
path.forEach((point) => {
|
||||||
@@ -23,7 +23,7 @@ export const drawStraightLinePath = (source: XYPosition, target: XYPosition, pat
|
|||||||
return svgPathString
|
return svgPathString
|
||||||
}
|
}
|
||||||
|
|
||||||
const quadraticBezierCurve = (points: number[][]) => {
|
function quadraticBezierCurve(points: number[][]) {
|
||||||
const X = 0
|
const X = 0
|
||||||
const Y = 1
|
const Y = 1
|
||||||
let point = points[0]
|
let point = points[0]
|
||||||
@@ -49,7 +49,7 @@ const quadraticBezierCurve = (points: number[][]) => {
|
|||||||
/**
|
/**
|
||||||
* Draws a SVG path from a list of points, using rounded lines.
|
* Draws a SVG path from a list of points, using rounded lines.
|
||||||
*/
|
*/
|
||||||
export const drawSmoothLinePath = (source: XYPosition, target: XYPosition, path: number[][]) => {
|
export function drawSmoothLinePath(source: XYPosition, target: XYPosition, path: number[][]) {
|
||||||
const points = [[source.x, source.y], ...path, [target.x, target.y]]
|
const points = [[source.x, source.y], ...path, [target.x, target.y]]
|
||||||
return quadraticBezierCurve(points)
|
return quadraticBezierCurve(points)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ declare module 'pathfinding' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const generatePath = (grid: Grid, start: XYPosition, end: XYPosition): number[][] => {
|
export function generatePath(grid: Grid, start: XYPosition, end: XYPosition): number[][] {
|
||||||
const finder = new AStarFinder({
|
const finder = new AStarFinder({
|
||||||
diagonalMovement: DiagonalMovement.Always,
|
diagonalMovement: DiagonalMovement.Always,
|
||||||
allowDiagonal: true,
|
allowDiagonal: true,
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export interface GraphBoundingBox {
|
|||||||
* @param roundTo If the coordinates should be rounded to this nearest integer
|
* @param roundTo If the coordinates should be rounded to this nearest integer
|
||||||
* @returns Graph and nodes bounding boxes.
|
* @returns Graph and nodes bounding boxes.
|
||||||
*/
|
*/
|
||||||
export const getBoundingBoxes = (storeNodes: GraphNode[], nodePadding = 0, graphPadding = 0, roundTo = 0) => {
|
export function getBoundingBoxes(storeNodes: GraphNode[], nodePadding = 0, graphPadding = 0, roundTo = 0) {
|
||||||
// Guarantee that the given parameters are positive integers
|
// Guarantee that the given parameters are positive integers
|
||||||
nodePadding = Math.max(Math.round(nodePadding), 0)
|
nodePadding = Math.max(Math.round(nodePadding), 0)
|
||||||
graphPadding = Math.max(Math.round(graphPadding), 0)
|
graphPadding = Math.max(Math.round(graphPadding), 0)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { Position, XYPosition } from '@vue-flow/core'
|
|||||||
|
|
||||||
type Direction = 'top' | 'bottom' | 'left' | 'right'
|
type Direction = 'top' | 'bottom' | 'left' | 'right'
|
||||||
|
|
||||||
export const getNextPointFromPosition = (point: XYPosition, position: Direction): XYPosition => {
|
export function getNextPointFromPosition(point: XYPosition, position: Direction): XYPosition {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 'top':
|
case 'top':
|
||||||
return { x: point.x, y: point.y - 1 }
|
return { x: point.x, y: point.y - 1 }
|
||||||
@@ -21,7 +21,7 @@ export const getNextPointFromPosition = (point: XYPosition, position: Direction)
|
|||||||
* walkable area, by adding a walkable path in the direction of the point's
|
* walkable area, by adding a walkable path in the direction of the point's
|
||||||
* Position.
|
* Position.
|
||||||
*/
|
*/
|
||||||
export const guaranteeWalkablePath = (grid: Grid, point: XYPosition, position: Position) => {
|
export function guaranteeWalkablePath(grid: Grid, point: XYPosition, position: Position) {
|
||||||
let node = grid.getNodeAt(point.x, point.y)
|
let node = grid.getNodeAt(point.x, point.y)
|
||||||
while (!node.walkable) {
|
while (!node.walkable) {
|
||||||
grid.setWalkableAt(node.x, node.y, true)
|
grid.setWalkableAt(node.x, node.y, true)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const gridRatio = 10
|
|||||||
* We avoid setting nodes in the border of the grid (x=0 or y=0), so there's
|
* We avoid setting nodes in the border of the grid (x=0 or y=0), so there's
|
||||||
* always a "walkable" area around the grid.
|
* always a "walkable" area around the grid.
|
||||||
*/
|
*/
|
||||||
export const graphToGridPoint = (graphPoint: XYPosition, smallestX: number, smallestY: number): XYPosition => {
|
export function graphToGridPoint(graphPoint: XYPosition, smallestX: number, smallestY: number): XYPosition {
|
||||||
let x = graphPoint.x / gridRatio
|
let x = graphPoint.x / gridRatio
|
||||||
let y = graphPoint.y / gridRatio
|
let y = graphPoint.y / gridRatio
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ export const graphToGridPoint = (graphPoint: XYPosition, smallestX: number, smal
|
|||||||
* Converts a grid point back to a graph point, using the reverse logic of
|
* Converts a grid point back to a graph point, using the reverse logic of
|
||||||
* graphToGridPoint.
|
* graphToGridPoint.
|
||||||
*/
|
*/
|
||||||
export const gridToGraphPoint = (gridPoint: XYPosition, smallestX: number, smallestY: number): XYPosition => {
|
export function gridToGraphPoint(gridPoint: XYPosition, smallestX: number, smallestY: number): XYPosition {
|
||||||
let x = gridPoint.x * gridRatio
|
let x = gridPoint.x * gridRatio
|
||||||
let y = gridPoint.y * gridRatio
|
let y = gridPoint.y * gridRatio
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
export const round = (x: number, multiple = 10) => Math.round(x / multiple) * multiple
|
export function round(x: number, multiple = 10) {
|
||||||
|
return Math.round(x / multiple) * multiple
|
||||||
|
}
|
||||||
|
|
||||||
export const roundDown = (x: number, multiple = 10) => Math.floor(x / multiple) * multiple
|
export function roundDown(x: number, multiple = 10) {
|
||||||
|
return Math.floor(x / multiple) * multiple
|
||||||
|
}
|
||||||
|
|
||||||
export const roundUp = (x: number, multiple = 10) => Math.ceil(x / multiple) * multiple
|
export function roundUp(x: number, multiple = 10) {
|
||||||
|
return Math.ceil(x / multiple) * multiple
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { mount } from 'cypress/vue'
|
|||||||
import { VueFlow } from '@vue-flow/core'
|
import { VueFlow } from '@vue-flow/core'
|
||||||
import type { FlowProps } from '@vue-flow/core'
|
import type { FlowProps } from '@vue-flow/core'
|
||||||
|
|
||||||
const mountVueFlow = (props?: FlowProps, attrs?: Record<string, any>, slots?: Record<string, any>) => {
|
function mountVueFlow(props?: FlowProps, attrs?: Record<string, any>, slots?: Record<string, any>) {
|
||||||
cy.mount(VueFlow as any, {
|
cy.mount(VueFlow as any, {
|
||||||
props: {
|
props: {
|
||||||
id: 'test',
|
id: 'test',
|
||||||
@@ -26,11 +26,15 @@ const mountVueFlow = (props?: FlowProps, attrs?: Record<string, any>, slots?: Re
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const useViewPort = () => cy.get('.vue-flow__viewport')
|
function useViewPort() {
|
||||||
|
return cy.get('.vue-flow__viewport')
|
||||||
|
}
|
||||||
|
|
||||||
const useTransformationPane = () => cy.get('.vue-flow__transformationpane')
|
function useTransformationPane() {
|
||||||
|
return cy.get('.vue-flow__transformationpane')
|
||||||
|
}
|
||||||
|
|
||||||
const retry = (assertion: Function, { interval = 20, timeout = 1000 } = {}) => {
|
function retry(assertion: Function, { interval = 20, timeout = 1000 } = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const startTime = Date.now()
|
const startTime = Date.now()
|
||||||
|
|
||||||
@@ -48,7 +52,7 @@ const retry = (assertion: Function, { interval = 20, timeout = 1000 } = {}) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const dragConnection = (from: string, to: string) => {
|
function dragConnection(from: string, to: string) {
|
||||||
cy.window().then((win) => {
|
cy.window().then((win) => {
|
||||||
const sourceHandle = cy.get(`[data-nodeid="${from}"].source`)
|
const sourceHandle = cy.get(`[data-nodeid="${from}"].source`)
|
||||||
const targetHandle = cy.get(`[data-nodeid="${to}"].target`)
|
const targetHandle = cy.get(`[data-nodeid="${to}"].target`)
|
||||||
@@ -78,7 +82,7 @@ const dragConnection = (from: string, to: string) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const connect = (from: string, to: string) => {
|
function connect(from: string, to: string) {
|
||||||
const sourceHandle = cy.get(`[data-nodeid="${from}"].source`)
|
const sourceHandle = cy.get(`[data-nodeid="${from}"].source`)
|
||||||
const targetHandle = cy.get(`[data-nodeid="${to}"].target`)
|
const targetHandle = cy.get(`[data-nodeid="${to}"].target`)
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ module.exports = {
|
|||||||
rules: {
|
rules: {
|
||||||
'vue/no-setup-props-destructure': 0,
|
'vue/no-setup-props-destructure': 0,
|
||||||
'no-console': 0,
|
'no-console': 0,
|
||||||
|
'unused-imports/no-unused-vars': 0,
|
||||||
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
||||||
'prettier/prettier': [
|
'prettier/prettier': [
|
||||||
'error',
|
'error',
|
||||||
|
|||||||
Reference in New Issue
Block a user