feat(nodes): Add PositionFunc as node position type
* Allows position to be set relative to another node
This commit is contained in:
@@ -99,10 +99,16 @@ const createGraphNodes = (nodes: Node[], getNode: Getters['getNode'], currGraphN
|
|||||||
})
|
})
|
||||||
|
|
||||||
graphNodes.forEach((node) => {
|
graphNodes.forEach((node) => {
|
||||||
if (node.parentNode && ![...graphNodes, ...currGraphNodes].find((n) => n.id === node.parentNode)) {
|
const nextNodes = [...graphNodes, ...currGraphNodes]
|
||||||
|
if (node.parentNode && !nextNodes.find((n) => n.id === node.parentNode)) {
|
||||||
console.warn(`[vueflow]: Parent node ${node.parentNode} not found`)
|
console.warn(`[vueflow]: Parent node ${node.parentNode} not found`)
|
||||||
}
|
}
|
||||||
|
const position =
|
||||||
|
(<any>node).position instanceof Function
|
||||||
|
? (<any>node).position(node, currGraphNodes, node.parentNode ? getNode(node.parentNode) : undefined)
|
||||||
|
: node.position
|
||||||
|
|
||||||
|
if (position) node.position = position
|
||||||
if (node.parentNode || parentNodes[node.id]) {
|
if (node.parentNode || parentNodes[node.id]) {
|
||||||
if (parentNodes[node.id]) {
|
if (parentNodes[node.id]) {
|
||||||
node.isParent = true
|
node.isParent = true
|
||||||
|
|||||||
@@ -10,13 +10,17 @@ export type NodeHandleBounds = {
|
|||||||
target?: HandleElement[]
|
target?: HandleElement[]
|
||||||
}
|
}
|
||||||
|
|
||||||
type WidthHeight = number | `${`parent` | string}(${`+` | `-`}${number})`
|
type PositionFunc = <Data = ElementData>(
|
||||||
|
node: GraphNode<Data>,
|
||||||
|
currNodes: GraphNode<Data>[],
|
||||||
|
parentNode: GraphNode<Data>,
|
||||||
|
) => XYPosition
|
||||||
type WidthFunc = <Data = ElementData>(node: GraphNode<Data>) => number | string | void
|
type WidthFunc = <Data = ElementData>(node: GraphNode<Data>) => number | string | void
|
||||||
type HeightFunc = <Data = ElementData>(node: GraphNode<Data>) => number | string | void
|
type HeightFunc = <Data = ElementData>(node: GraphNode<Data>) => number | string | void
|
||||||
|
|
||||||
export interface Node<Data = ElementData> extends Element<Data> {
|
export interface Node<Data = ElementData> extends Element<Data> {
|
||||||
/** node position x, y */
|
/** initial node position x, y */
|
||||||
position: XYPosition
|
position: XYPosition | PositionFunc
|
||||||
/** node type, can be a default type or a custom type */
|
/** node type, can be a default type or a custom type */
|
||||||
type?: keyof DefaultNodeTypes | string
|
type?: keyof DefaultNodeTypes | string
|
||||||
/** handle position */
|
/** handle position */
|
||||||
@@ -56,6 +60,8 @@ export interface Node<Data = ElementData> extends Element<Data> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GraphNode<Data = ElementData> extends Node<Data> {
|
export interface GraphNode<Data = ElementData> extends Node<Data> {
|
||||||
|
/** current node position x, y */
|
||||||
|
position: XYPosition
|
||||||
/** absolute position in relation to parent elements + z-index */
|
/** absolute position in relation to parent elements + z-index */
|
||||||
computedPosition: XYZPosition
|
computedPosition: XYZPosition
|
||||||
handleBounds: NodeHandleBounds
|
handleBounds: NodeHandleBounds
|
||||||
|
|||||||
+25
-23
@@ -62,31 +62,33 @@ export const isGraphNode = (element: Node | Edge | Connection): element is Graph
|
|||||||
isNode(element) && 'computedPosition' in element
|
isNode(element) && 'computedPosition' in element
|
||||||
|
|
||||||
export const parseNode = (node: Node, nodeExtent: CoordinateExtent, defaults?: Partial<GraphNode>): GraphNode => {
|
export const parseNode = (node: Node, nodeExtent: CoordinateExtent, defaults?: Partial<GraphNode>): GraphNode => {
|
||||||
defaults = !isGraphNode(node)
|
let defaultValues = defaults
|
||||||
? {
|
if (!isGraphNode(node)) {
|
||||||
type: node.type ?? 'default',
|
defaultValues = {
|
||||||
dimensions: {
|
type: node.type ?? 'default',
|
||||||
width: 0,
|
dimensions: {
|
||||||
height: 0,
|
width: 0,
|
||||||
},
|
height: 0,
|
||||||
handleBounds: {
|
},
|
||||||
source: [],
|
handleBounds: {
|
||||||
target: [],
|
source: [],
|
||||||
},
|
target: [],
|
||||||
computedPosition: {
|
},
|
||||||
z: 0,
|
computedPosition: {
|
||||||
...clampPosition(node.position, nodeExtent),
|
z: 0,
|
||||||
},
|
x: 0,
|
||||||
dragging: false,
|
y: 0,
|
||||||
draggable: undefined,
|
},
|
||||||
selectable: undefined,
|
dragging: false,
|
||||||
connectable: undefined,
|
draggable: undefined,
|
||||||
...defaults,
|
selectable: undefined,
|
||||||
}
|
connectable: undefined,
|
||||||
: defaults
|
...defaults,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...(defaults as GraphNode),
|
...defaultValues,
|
||||||
...(node as GraphNode),
|
...(node as GraphNode),
|
||||||
id: node.id.toString(),
|
id: node.id.toString(),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user