@utisha/graph-editor 1.0.0-beta.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EventEmitter,
|
|
2
|
-
import { Graph,
|
|
3
|
-
import { GraphEditorConfig, SelectionState, ValidationResult
|
|
1
|
+
import { EventEmitter, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
|
2
|
+
import { Graph, GraphEdge, GraphNode, Position } from './graph.model';
|
|
3
|
+
import { ContextMenuEvent, GraphEditorConfig, SelectionState, ValidationResult } from './graph-editor.config';
|
|
4
4
|
import * as i0 from "@angular/core";
|
|
5
5
|
/**
|
|
6
6
|
* Main graph editor component.
|
|
@@ -34,6 +34,7 @@ export declare class GraphEditorComponent implements OnInit, OnChanges {
|
|
|
34
34
|
canvasClick: EventEmitter<Position>;
|
|
35
35
|
contextMenu: EventEmitter<ContextMenuEvent>;
|
|
36
36
|
private readonly canvasSvgRef;
|
|
37
|
+
private readonly historyService;
|
|
37
38
|
internalGraph: import("@angular/core").WritableSignal<Graph>;
|
|
38
39
|
selection: import("@angular/core").WritableSignal<SelectionState>;
|
|
39
40
|
validationResult: import("@angular/core").WritableSignal<ValidationResult | null>;
|
|
@@ -42,6 +43,8 @@ export declare class GraphEditorComponent implements OnInit, OnChanges {
|
|
|
42
43
|
scale: import("@angular/core").WritableSignal<number>;
|
|
43
44
|
private draggedNode;
|
|
44
45
|
private dragOffset;
|
|
46
|
+
private draggedNodeOffsets;
|
|
47
|
+
private didDrag;
|
|
45
48
|
private isPanning;
|
|
46
49
|
private lastMousePos;
|
|
47
50
|
private draggedEdge;
|
|
@@ -57,6 +60,14 @@ export declare class GraphEditorComponent implements OnInit, OnChanges {
|
|
|
57
60
|
source: Position;
|
|
58
61
|
target: Position;
|
|
59
62
|
} | null>;
|
|
63
|
+
private isBoxSelecting;
|
|
64
|
+
private boxSelectStart;
|
|
65
|
+
selectionBox: import("@angular/core").WritableSignal<{
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
width: number;
|
|
69
|
+
height: number;
|
|
70
|
+
} | null>;
|
|
60
71
|
transform: import("@angular/core").Signal<string>;
|
|
61
72
|
gridBounds: import("@angular/core").Signal<{
|
|
62
73
|
x: number;
|
|
@@ -64,6 +75,7 @@ export declare class GraphEditorComponent implements OnInit, OnChanges {
|
|
|
64
75
|
width: number;
|
|
65
76
|
height: number;
|
|
66
77
|
}>;
|
|
78
|
+
shadowsEnabled: import("@angular/core").Signal<boolean>;
|
|
67
79
|
selectedEdgeMidpoint: import("@angular/core").Signal<{
|
|
68
80
|
edge: GraphEdge;
|
|
69
81
|
x: number;
|
|
@@ -78,6 +90,10 @@ export declare class GraphEditorComponent implements OnInit, OnChanges {
|
|
|
78
90
|
updateNode(nodeId: string, updates: Partial<GraphNode>): void;
|
|
79
91
|
selectNode(nodeId: string | null): void;
|
|
80
92
|
selectEdge(edgeId: string | null): void;
|
|
93
|
+
/** Toggle a node in/out of the current selection (for Ctrl+Click) */
|
|
94
|
+
toggleNodeSelection(nodeId: string): void;
|
|
95
|
+
/** Toggle an edge in/out of the current selection (for Ctrl+Click) */
|
|
96
|
+
toggleEdgeSelection(edgeId: string): void;
|
|
81
97
|
onKeyDown(event: KeyboardEvent): void;
|
|
82
98
|
switchTool(tool: 'hand' | 'line'): void;
|
|
83
99
|
/** @deprecated Use switchTool('line') instead */
|
|
@@ -100,6 +116,16 @@ export declare class GraphEditorComponent implements OnInit, OnChanges {
|
|
|
100
116
|
onWheel(event: WheelEvent): void;
|
|
101
117
|
onContextMenu(event: MouseEvent): void;
|
|
102
118
|
private emitGraphChange;
|
|
119
|
+
/** Undo the last action (Ctrl+Z) */
|
|
120
|
+
undo(): boolean;
|
|
121
|
+
/** Redo the last undone action (Ctrl+Y / Ctrl+Shift+Z) */
|
|
122
|
+
redo(): boolean;
|
|
123
|
+
/** Check if undo is available */
|
|
124
|
+
canUndo(): boolean;
|
|
125
|
+
/** Check if redo is available */
|
|
126
|
+
canRedo(): boolean;
|
|
127
|
+
/** Clear history and reset to current state */
|
|
128
|
+
clearHistory(): void;
|
|
103
129
|
private generateId;
|
|
104
130
|
private recalculateEdgePorts;
|
|
105
131
|
getNodeSize(node: GraphNode): {
|
|
@@ -114,7 +140,27 @@ export declare class GraphEditorComponent implements OnInit, OnChanges {
|
|
|
114
140
|
getEdgeSourcePoint(edge: GraphEdge): Position;
|
|
115
141
|
getEdgeTargetPoint(edge: GraphEdge): Position;
|
|
116
142
|
getNodeTypeIcon(node: GraphNode): string;
|
|
143
|
+
/**
|
|
144
|
+
* Get custom image URL for a node.
|
|
145
|
+
* Checks node.data['imageUrl'] first, then falls back to nodeType.defaultData['imageUrl'].
|
|
146
|
+
* Returns null if no image is configured (will render text icon instead).
|
|
147
|
+
*/
|
|
148
|
+
getNodeImage(node: GraphNode): string | null;
|
|
149
|
+
/**
|
|
150
|
+
* Get the position for the node image (top-left corner of image).
|
|
151
|
+
* Uses same positioning logic as icon but accounts for image dimensions.
|
|
152
|
+
*/
|
|
153
|
+
getImagePosition(node: GraphNode): Position;
|
|
154
|
+
/**
|
|
155
|
+
* Get the size (width/height) for node images.
|
|
156
|
+
* Images are rendered as squares, sized proportionally to node height.
|
|
157
|
+
*/
|
|
158
|
+
getImageSize(node: GraphNode): number;
|
|
159
|
+
getIconPosition(node: GraphNode): Position;
|
|
160
|
+
getLabelPosition(node: GraphNode): Position;
|
|
117
161
|
private findNodeAtPosition;
|
|
162
|
+
private findEdgeAtPosition;
|
|
163
|
+
private pointToSegmentDistance;
|
|
118
164
|
getNodePorts(node: GraphNode): Array<{
|
|
119
165
|
position: 'top' | 'bottom' | 'left' | 'right';
|
|
120
166
|
x: number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Type } from '@angular/core';
|
|
2
|
-
import {
|
|
2
|
+
import { EdgeStyle, Graph, Position } from './graph.model';
|
|
3
3
|
export interface GraphEditorConfig {
|
|
4
4
|
/** Node type definitions */
|
|
5
5
|
nodes: NodesConfig;
|
|
@@ -28,6 +28,8 @@ export interface NodesConfig {
|
|
|
28
28
|
height: number;
|
|
29
29
|
};
|
|
30
30
|
constrainToBounds?: boolean;
|
|
31
|
+
/** Icon position within the node (default: 'top-left') */
|
|
32
|
+
iconPosition?: 'top-left' | 'top' | 'top-right' | 'right' | 'bottom-right' | 'bottom' | 'bottom-left' | 'left';
|
|
31
33
|
}
|
|
32
34
|
/**
|
|
33
35
|
* Node type definition.
|
|
@@ -47,6 +49,13 @@ export interface NodeTypeDefinition {
|
|
|
47
49
|
configComponent?: Type<any>;
|
|
48
50
|
/** Default data when node is created */
|
|
49
51
|
defaultData: Record<string, any>;
|
|
52
|
+
/**
|
|
53
|
+
* Optional image URL for node icon. When set, renders an <image> element instead of text icon.
|
|
54
|
+
* Can be overridden per-instance via node.data['imageUrl'].
|
|
55
|
+
* Supports: SVG, PNG, JPG, data URLs, or any valid image URL.
|
|
56
|
+
* @example '/assets/icons/agent.svg'
|
|
57
|
+
* @example 'data:image/svg+xml;base64,...'
|
|
58
|
+
*/
|
|
50
59
|
/** Port definitions */
|
|
51
60
|
ports?: PortConfig;
|
|
52
61
|
/** Connection constraints */
|
|
@@ -192,6 +201,8 @@ export interface ContextMenuContext {
|
|
|
192
201
|
export interface ThemeConfig {
|
|
193
202
|
/** CSS custom property values */
|
|
194
203
|
variables?: Record<string, string>;
|
|
204
|
+
/** Enable drop shadows on nodes and edges (default: true) */
|
|
205
|
+
shadows?: boolean;
|
|
195
206
|
}
|
|
196
207
|
/**
|
|
197
208
|
* Palette configuration.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Graph } from '../graph.model';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Service for managing undo/redo history of graph state.
|
|
5
|
+
*
|
|
6
|
+
* Uses a simple snapshot-based approach where each history entry
|
|
7
|
+
* is a deep copy of the entire graph state.
|
|
8
|
+
*/
|
|
9
|
+
export declare class GraphHistoryService {
|
|
10
|
+
private history;
|
|
11
|
+
private historyIndex;
|
|
12
|
+
private maxHistorySize;
|
|
13
|
+
/** Signal to track if an undo/redo operation is in progress */
|
|
14
|
+
readonly isUndoRedo: import("@angular/core").WritableSignal<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* Initialize history with the given graph state.
|
|
17
|
+
* Clears any existing history.
|
|
18
|
+
*/
|
|
19
|
+
init(graph: Graph): void;
|
|
20
|
+
/**
|
|
21
|
+
* Push a new state to the history stack.
|
|
22
|
+
* If we're not at the end of history, truncates future states.
|
|
23
|
+
* Prevents duplicate consecutive states.
|
|
24
|
+
*
|
|
25
|
+
* @returns true if state was pushed, false if it was a duplicate
|
|
26
|
+
*/
|
|
27
|
+
push(graph: Graph): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Undo the last action.
|
|
30
|
+
* @returns The previous graph state, or null if nothing to undo
|
|
31
|
+
*/
|
|
32
|
+
undo(): Graph | null;
|
|
33
|
+
/**
|
|
34
|
+
* Redo the last undone action.
|
|
35
|
+
* @returns The next graph state, or null if nothing to redo
|
|
36
|
+
*/
|
|
37
|
+
redo(): Graph | null;
|
|
38
|
+
/**
|
|
39
|
+
* Complete an undo/redo operation.
|
|
40
|
+
* Call this after applying the state returned by undo() or redo().
|
|
41
|
+
*/
|
|
42
|
+
completeUndoRedo(): void;
|
|
43
|
+
/** Check if undo is available */
|
|
44
|
+
canUndo(): boolean;
|
|
45
|
+
/** Check if redo is available */
|
|
46
|
+
canRedo(): boolean;
|
|
47
|
+
/** Clear history and reset to given state */
|
|
48
|
+
clear(graph: Graph): void;
|
|
49
|
+
/** Get current history size */
|
|
50
|
+
get size(): number;
|
|
51
|
+
/** Get current position in history (0-indexed) */
|
|
52
|
+
get position(): number;
|
|
53
|
+
/** Set maximum history size */
|
|
54
|
+
setMaxSize(size: number): void;
|
|
55
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<GraphHistoryService, never>;
|
|
56
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<GraphHistoryService>;
|
|
57
|
+
}
|