@dforge-core/diagram 0.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.
- package/LICENSE +21 -0
- package/README.md +45 -0
- package/dist/EntityNode.svelte +167 -0
- package/dist/EntityNode.svelte.d.ts +8 -0
- package/dist/EntityNode.svelte.d.ts.map +1 -0
- package/dist/IconButton.svelte +83 -0
- package/dist/IconButton.svelte.d.ts +13 -0
- package/dist/IconButton.svelte.d.ts.map +1 -0
- package/dist/SimpleDiagram/DiagramDebug.svelte +499 -0
- package/dist/SimpleDiagram/DiagramDebug.svelte.d.ts +4 -0
- package/dist/SimpleDiagram/DiagramDebug.svelte.d.ts.map +1 -0
- package/dist/SimpleDiagram/ModelDiagram.svelte +569 -0
- package/dist/SimpleDiagram/ModelDiagram.svelte.d.ts +18 -0
- package/dist/SimpleDiagram/ModelDiagram.svelte.d.ts.map +1 -0
- package/dist/SimpleDiagram/NOTE.md +14 -0
- package/dist/SimpleDiagram/SimpleDiagram.svelte +755 -0
- package/dist/SimpleDiagram/SimpleDiagram.svelte.d.ts +13 -0
- package/dist/SimpleDiagram/SimpleDiagram.svelte.d.ts.map +1 -0
- package/dist/SimpleDiagram/diagram-geometry.d.ts +33 -0
- package/dist/SimpleDiagram/diagram-geometry.d.ts.map +1 -0
- package/dist/SimpleDiagram/diagram-geometry.js +137 -0
- package/dist/SimpleDiagram/simple-layout.d.ts +27 -0
- package/dist/SimpleDiagram/simple-layout.d.ts.map +1 -0
- package/dist/SimpleDiagram/simple-layout.js +364 -0
- package/dist/WorkspaceMap/ModuleCard.svelte +165 -0
- package/dist/WorkspaceMap/ModuleCard.svelte.d.ts +8 -0
- package/dist/WorkspaceMap/ModuleCard.svelte.d.ts.map +1 -0
- package/dist/WorkspaceMap/WorkspaceMap.svelte +319 -0
- package/dist/WorkspaceMap/WorkspaceMap.svelte.d.ts +12 -0
- package/dist/WorkspaceMap/WorkspaceMap.svelte.d.ts.map +1 -0
- package/dist/WorkspaceMap/workspace-graph.d.ts +18 -0
- package/dist/WorkspaceMap/workspace-graph.d.ts.map +1 -0
- package/dist/WorkspaceMap/workspace-graph.js +168 -0
- package/dist/WorkspaceMap/workspace-types.d.ts +32 -0
- package/dist/WorkspaceMap/workspace-types.d.ts.map +1 -0
- package/dist/WorkspaceMap/workspace-types.js +1 -0
- package/dist/diagram-types.d.ts +47 -0
- package/dist/diagram-types.d.ts.map +1 -0
- package/dist/diagram-types.js +2 -0
- package/dist/edge-routing.d.ts +82 -0
- package/dist/edge-routing.d.ts.map +1 -0
- package/dist/edge-routing.js +388 -0
- package/dist/i18n.d.ts +13 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +20 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/local-storage-sync.d.ts +10 -0
- package/dist/local-storage-sync.d.ts.map +1 -0
- package/dist/local-storage-sync.js +39 -0
- package/dist/model-graph.d.ts +20 -0
- package/dist/model-graph.d.ts.map +1 -0
- package/dist/model-graph.js +100 -0
- package/dist/model-types.d.ts +55 -0
- package/dist/model-types.d.ts.map +1 -0
- package/dist/model-types.js +11 -0
- package/dist/pan-zoom.svelte.d.ts +34 -0
- package/dist/pan-zoom.svelte.d.ts.map +1 -0
- package/dist/pan-zoom.svelte.js +130 -0
- package/package.json +55 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface WorkspaceModule {
|
|
2
|
+
id: string;
|
|
3
|
+
moduleCd: string;
|
|
4
|
+
label: string;
|
|
5
|
+
color: string;
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
entities: WorkspaceEntity[];
|
|
11
|
+
}
|
|
12
|
+
export interface WorkspaceEntity {
|
|
13
|
+
entityId: number;
|
|
14
|
+
entityCd: string;
|
|
15
|
+
label: string;
|
|
16
|
+
/** Nesting depth (0 = root, 1 = child, 2 = grandchild, ...) */
|
|
17
|
+
depth: number;
|
|
18
|
+
/** Position relative to parent module card */
|
|
19
|
+
rx: number;
|
|
20
|
+
ry: number;
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
}
|
|
24
|
+
export interface WorkspaceEdge {
|
|
25
|
+
id: string;
|
|
26
|
+
sourceModuleId: string;
|
|
27
|
+
sourceEntityId: number;
|
|
28
|
+
targetModuleId: string;
|
|
29
|
+
targetEntityId: number;
|
|
30
|
+
color: string;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=workspace-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-types.d.ts","sourceRoot":"","sources":["../../src/lib/WorkspaceMap/workspace-types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ModelColumn } from './model-types';
|
|
2
|
+
export interface EntityNodeData {
|
|
3
|
+
entityCd: string;
|
|
4
|
+
resLabel?: string;
|
|
5
|
+
resIcon?: string;
|
|
6
|
+
moduleCd: string;
|
|
7
|
+
moduleColor: string;
|
|
8
|
+
columns: ModelColumn[];
|
|
9
|
+
/** Map of entityId → entityCd for resolving FK targets */
|
|
10
|
+
entityMap: Map<number, string>;
|
|
11
|
+
}
|
|
12
|
+
export interface DiagramNode {
|
|
13
|
+
id: string;
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
data: EntityNodeData;
|
|
19
|
+
}
|
|
20
|
+
export interface DiagramEdge {
|
|
21
|
+
id: string;
|
|
22
|
+
source: string;
|
|
23
|
+
sourceHandle: string;
|
|
24
|
+
target: string;
|
|
25
|
+
color: string;
|
|
26
|
+
label?: string;
|
|
27
|
+
isNullable?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** Edge with fully resolved path — no recomputation needed at render time. */
|
|
30
|
+
export interface ResolvedEdge extends DiagramEdge {
|
|
31
|
+
points: Point[];
|
|
32
|
+
}
|
|
33
|
+
export interface Point {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
}
|
|
37
|
+
export interface ViewTransform {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
k: number;
|
|
41
|
+
}
|
|
42
|
+
export interface DragSegment {
|
|
43
|
+
edgeId: string;
|
|
44
|
+
segIndex: number;
|
|
45
|
+
orientation: 'H' | 'V';
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=diagram-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram-types.d.ts","sourceRoot":"","sources":["../src/lib/diagram-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,0DAA0D;IAC1D,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,8EAA8E;AAC9E,MAAM,WAAW,YAAa,SAAQ,WAAW;IAChD,MAAM,EAAE,KAAK,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,KAAK;IACrB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACV;AAED,MAAM,WAAW,aAAa;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACV;AAED,MAAM,WAAW,WAAW;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,GAAG,GAAG,GAAG,CAAA;CACtB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { DiagramNode, DiagramEdge, Point } from './diagram-types';
|
|
2
|
+
export declare const PORT_DOT_RADIUS = 3;
|
|
3
|
+
export interface EdgePath {
|
|
4
|
+
d: string;
|
|
5
|
+
labelX: number;
|
|
6
|
+
labelY: number;
|
|
7
|
+
srcPort: Point;
|
|
8
|
+
tgtPort: Point;
|
|
9
|
+
points: Point[];
|
|
10
|
+
}
|
|
11
|
+
export interface SegmentHandle {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
segIndex: number;
|
|
15
|
+
orientation: 'H' | 'V';
|
|
16
|
+
draggable: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Compute source port position: right side of node, at the FK row's vertical center.
|
|
20
|
+
*/
|
|
21
|
+
export declare function sourcePort(node: DiagramNode, colCd: string): Point;
|
|
22
|
+
/**
|
|
23
|
+
* Compute target port position: left side of node, at vertical center.
|
|
24
|
+
*/
|
|
25
|
+
export declare const targetPort: (node: DiagramNode) => Point;
|
|
26
|
+
/**
|
|
27
|
+
* Snap first/last bend points to port Y positions.
|
|
28
|
+
* Keeps paths orthogonal when nodes are moved.
|
|
29
|
+
*
|
|
30
|
+
* Only snap when the bend forms a horizontal segment with the port
|
|
31
|
+
* (different X). If the bend shares the same X as the port, it's a
|
|
32
|
+
* vertical connection (e.g., after a segment split) and shouldn't be
|
|
33
|
+
* snapped — that would destroy jog shapes.
|
|
34
|
+
*/
|
|
35
|
+
export declare const snapBends: (src: Point, tgt: Point, bends: Point[]) => Point[];
|
|
36
|
+
/**
|
|
37
|
+
* Compute auto-routed bend points for an edge.
|
|
38
|
+
* Returns the corners where the path changes direction.
|
|
39
|
+
*/
|
|
40
|
+
export declare function extractBendPoints(edge: DiagramEdge, nodes: Record<string, DiagramNode>): Point[];
|
|
41
|
+
/**
|
|
42
|
+
* Remove redundant bend points: snap near-collinear points to exact
|
|
43
|
+
* alignment, remove zero-length duplicates, and collapse collinear midpoints.
|
|
44
|
+
*/
|
|
45
|
+
export declare function consolidateBends(edge: DiagramEdge, nodes: Record<string, DiagramNode>, bends: Point[]): Point[];
|
|
46
|
+
/**
|
|
47
|
+
* Compute the SVG path for an edge.
|
|
48
|
+
* Uses stored bend points if provided, otherwise auto-routes.
|
|
49
|
+
*/
|
|
50
|
+
export declare function computeEdgePath(edge: DiagramEdge, nodes: Record<string, DiagramNode>, storedBends?: Point[]): EdgePath | null;
|
|
51
|
+
/**
|
|
52
|
+
* Compute drag/split handles for an edge's segments.
|
|
53
|
+
*/
|
|
54
|
+
export declare function getEdgeHandles(edge: DiagramEdge, nodes: Record<string, DiagramNode>, storedBends?: Point[]): {
|
|
55
|
+
bendPoints: Point[];
|
|
56
|
+
handles: SegmentHandle[];
|
|
57
|
+
} | null;
|
|
58
|
+
/**
|
|
59
|
+
* Prepare bends for dragging by inserting clamp points where needed.
|
|
60
|
+
* When a segment's neighbors are collinear (same orientation), dragging
|
|
61
|
+
* would create diagonal lines. This inserts transition bends so that
|
|
62
|
+
* adjacent segments become perpendicular and stay orthogonal during drag.
|
|
63
|
+
* Call once at drag start, not on every move.
|
|
64
|
+
*/
|
|
65
|
+
export declare function prepareDrag(edge: DiagramEdge, nodes: Record<string, DiagramNode>, bends: Point[], segIndex: number, orientation: 'H' | 'V'): {
|
|
66
|
+
bends: Point[];
|
|
67
|
+
segIndex: number;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Move a segment by updating the two bend points that define it.
|
|
71
|
+
*/
|
|
72
|
+
export declare function dragSegment(bends: Point[], segIndex: number, orientation: 'H' | 'V', pos: Point): Point[];
|
|
73
|
+
/**
|
|
74
|
+
* Split a segment by inserting a rectangular jog.
|
|
75
|
+
* Returns the new bend points and the draggable segment info.
|
|
76
|
+
*/
|
|
77
|
+
export declare function splitSegment(edge: DiagramEdge, nodes: Record<string, DiagramNode>, storedBends: Point[], handle: SegmentHandle): {
|
|
78
|
+
bends: Point[];
|
|
79
|
+
segIndex: number;
|
|
80
|
+
orientation: 'H' | 'V';
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=edge-routing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-routing.d.ts","sourceRoot":"","sources":["../src/lib/edge-routing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAQvE,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC,MAAM,WAAW,QAAQ;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC;IACf,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,KAAK,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,GAAG,GAAG,GAAG,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;CACnB;AAMD;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CASlE;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,WAAW,KAAG,KAG9C,CAAC;AAIF;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,GAAI,KAAK,KAAK,EAAE,KAAK,KAAK,EAAE,OAAO,KAAK,EAAE,KAAG,KAAK,EASrE,CAAC;AAiHJ;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAChC,KAAK,EAAE,CA8CT;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAClC,KAAK,EAAE,KAAK,EAAE,GACZ,KAAK,EAAE,CA2CT;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAClC,WAAW,CAAC,EAAE,KAAK,EAAE,GACnB,QAAQ,GAAG,IAAI,CAajB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC7B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAClC,WAAW,CAAC,EAAE,KAAK,EAAE,GACnB;IAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,GAAG,IAAI,CAU1D;AA+CD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAC1B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAClC,KAAK,EAAE,KAAK,EAAE,EACd,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,GAAG,GAAG,GAAG,GACpB;IAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAyCtC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAC1B,KAAK,EAAE,KAAK,EAAE,EACd,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,GAAG,GAAG,GAAG,EACtB,GAAG,EAAE,KAAK,GACR,KAAK,EAAE,CAUT;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAClC,WAAW,EAAE,KAAK,EAAE,EACpB,MAAM,EAAE,aAAa,GACnB;IAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,GAAG,GAAG,GAAG,CAAA;CAAE,CA+B9D"}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
const HEADER_HEIGHT = 30;
|
|
2
|
+
const ROW_HEIGHT = 22;
|
|
3
|
+
const BEND_RADIUS = 8;
|
|
4
|
+
const STUB_LENGTH = 24;
|
|
5
|
+
const TARGET_STUB = STUB_LENGTH;
|
|
6
|
+
const SNAP = 3; // px — threshold for snapping near-collinear points
|
|
7
|
+
export const PORT_DOT_RADIUS = 3;
|
|
8
|
+
const point = (x, y) => ({ x, y });
|
|
9
|
+
// --- Port positions ---
|
|
10
|
+
/**
|
|
11
|
+
* Compute source port position: right side of node, at the FK row's vertical center.
|
|
12
|
+
*/
|
|
13
|
+
export function sourcePort(node, colCd) {
|
|
14
|
+
const colIndex = node.data.columns.findIndex((c) => c.columnCd === colCd);
|
|
15
|
+
const idx = colIndex >= 0 ? colIndex : 0;
|
|
16
|
+
return point(node.x + node.width, node.y + HEADER_HEIGHT + idx * ROW_HEIGHT + ROW_HEIGHT / 2);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Compute target port position: left side of node, at vertical center.
|
|
20
|
+
*/
|
|
21
|
+
export const targetPort = (node) => point(node.x, node.y + node.height / 2);
|
|
22
|
+
// --- Bend point snapping ---
|
|
23
|
+
/**
|
|
24
|
+
* Snap first/last bend points to port Y positions.
|
|
25
|
+
* Keeps paths orthogonal when nodes are moved.
|
|
26
|
+
*
|
|
27
|
+
* Only snap when the bend forms a horizontal segment with the port
|
|
28
|
+
* (different X). If the bend shares the same X as the port, it's a
|
|
29
|
+
* vertical connection (e.g., after a segment split) and shouldn't be
|
|
30
|
+
* snapped — that would destroy jog shapes.
|
|
31
|
+
*/
|
|
32
|
+
export const snapBends = (src, tgt, bends) => bends.length === 0
|
|
33
|
+
? bends
|
|
34
|
+
: bends.map((b, i) => i === 0 && Math.abs(b.x - src.x) > SNAP
|
|
35
|
+
? { ...b, y: src.y }
|
|
36
|
+
: i === bends.length - 1 && Math.abs(b.x - tgt.x) > SNAP
|
|
37
|
+
? { ...b, y: tgt.y }
|
|
38
|
+
: b);
|
|
39
|
+
// --- SVG path helpers ---
|
|
40
|
+
/**
|
|
41
|
+
* Build a quadratic Bezier corner between two segments.
|
|
42
|
+
* prev→corner→next defines the corner; r is the desired radius.
|
|
43
|
+
*/
|
|
44
|
+
function roundedCorner(from, corner, to, r) {
|
|
45
|
+
const d1 = Math.max(Math.abs(corner.x - from.x), Math.abs(corner.y - from.y));
|
|
46
|
+
const d2 = Math.max(Math.abs(to.x - corner.x), Math.abs(to.y - corner.y));
|
|
47
|
+
const cr = Math.min(r, d1 / 2, d2 / 2);
|
|
48
|
+
if (cr < 1)
|
|
49
|
+
return `L ${corner.x} ${corner.y}`;
|
|
50
|
+
// Use dominant-axis direction: for near-orthogonal segments the minor
|
|
51
|
+
// axis may be a few pixels off, and raw Math.sign would produce ±1
|
|
52
|
+
// instead of 0, sending the Bezier exit in the wrong direction.
|
|
53
|
+
const d1x = corner.x - from.x, d1y = corner.y - from.y;
|
|
54
|
+
const d2x = to.x - corner.x, d2y = to.y - corner.y;
|
|
55
|
+
const h1 = Math.abs(d1x) >= Math.abs(d1y);
|
|
56
|
+
const dx1 = h1 ? Math.sign(d1x) : 0;
|
|
57
|
+
const dy1 = h1 ? 0 : Math.sign(d1y);
|
|
58
|
+
const h2 = Math.abs(d2x) >= Math.abs(d2y);
|
|
59
|
+
const dx2 = h2 ? Math.sign(d2x) : 0;
|
|
60
|
+
const dy2 = h2 ? 0 : Math.sign(d2y);
|
|
61
|
+
const ax = corner.x - dx1 * cr;
|
|
62
|
+
const ay = corner.y - dy1 * cr;
|
|
63
|
+
const bx = corner.x + dx2 * cr;
|
|
64
|
+
const by = corner.y + dy2 * cr;
|
|
65
|
+
return `L ${ax} ${ay} Q ${corner.x} ${corner.y} ${bx} ${by}`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Fix diagonal segments by inserting corner points (horizontal-first).
|
|
69
|
+
*/
|
|
70
|
+
function orthogonalize(raw) {
|
|
71
|
+
const points = [raw[0]];
|
|
72
|
+
for (let i = 1; i < raw.length; i++) {
|
|
73
|
+
const prev = points[points.length - 1];
|
|
74
|
+
const curr = raw[i];
|
|
75
|
+
if (Math.abs(prev.x - curr.x) > SNAP && Math.abs(prev.y - curr.y) > SNAP) {
|
|
76
|
+
points.push(point(curr.x, prev.y)); // horizontal-first corner
|
|
77
|
+
}
|
|
78
|
+
points.push(curr);
|
|
79
|
+
}
|
|
80
|
+
return points;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Ensure the path arrives at the target with a horizontal segment.
|
|
84
|
+
* If the last non-trivial segment is vertical (same X as target),
|
|
85
|
+
* pull it back by TARGET_STUB and insert a horizontal approach.
|
|
86
|
+
*/
|
|
87
|
+
function ensureHorizontalApproach(points) {
|
|
88
|
+
if (points.length < 2)
|
|
89
|
+
return;
|
|
90
|
+
// Skip trailing zero-length duplicates to find the real approach segment
|
|
91
|
+
const tgtIdx = points.length - 1;
|
|
92
|
+
let prevIdx = tgtIdx - 1;
|
|
93
|
+
while (prevIdx >= 0
|
|
94
|
+
&& Math.abs(points[prevIdx].x - points[tgtIdx].x) < 1
|
|
95
|
+
&& Math.abs(points[prevIdx].y - points[tgtIdx].y) < 1) {
|
|
96
|
+
prevIdx--;
|
|
97
|
+
}
|
|
98
|
+
if (prevIdx < 0)
|
|
99
|
+
return;
|
|
100
|
+
const prev = points[prevIdx];
|
|
101
|
+
const tgt = points[tgtIdx];
|
|
102
|
+
// Vertical approach: same X, different Y → replace with horizontal stub.
|
|
103
|
+
// Splice out prev and any trailing duplicates, insert offset detour.
|
|
104
|
+
if (Math.abs(prev.x - tgt.x) < 1 && Math.abs(prev.y - tgt.y) > 1) {
|
|
105
|
+
const stubX = tgt.x - TARGET_STUB;
|
|
106
|
+
points.splice(prevIdx, tgtIdx - prevIdx, point(stubX, prev.y), point(stubX, tgt.y));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Build an orthogonal SVG path through a sequence of points (src + bends + tgt).
|
|
111
|
+
* Auto-fixes any diagonal segments by inserting corner points (horizontal-first).
|
|
112
|
+
*/
|
|
113
|
+
function buildPath(src, tgt, bends) {
|
|
114
|
+
const raw = orthogonalize([src, ...bends, tgt]);
|
|
115
|
+
ensureHorizontalApproach(raw);
|
|
116
|
+
// Strip consecutive duplicate points — zero-length segments cause
|
|
117
|
+
// roundedCorner to produce sharp angles (cr drops to 0).
|
|
118
|
+
const points = [raw[0]];
|
|
119
|
+
for (let i = 1; i < raw.length; i++) {
|
|
120
|
+
const prev = points[points.length - 1];
|
|
121
|
+
if (Math.abs(prev.x - raw[i].x) > 0.5 || Math.abs(prev.y - raw[i].y) > 0.5) {
|
|
122
|
+
points.push(raw[i]);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
let d = `M ${points[0].x} ${points[0].y}`;
|
|
126
|
+
for (let i = 1; i < points.length - 1; i++) {
|
|
127
|
+
d += ` ${roundedCorner(points[i - 1], points[i], points[i + 1], BEND_RADIUS)}`;
|
|
128
|
+
}
|
|
129
|
+
d += ` L ${points[points.length - 1].x} ${points[points.length - 1].y}`;
|
|
130
|
+
const mid = points[Math.floor(points.length / 2)];
|
|
131
|
+
return { d, labelX: mid.x, labelY: mid.y - 6, srcPort: src, tgtPort: tgt, points };
|
|
132
|
+
}
|
|
133
|
+
// --- Auto-routing ---
|
|
134
|
+
/**
|
|
135
|
+
* Compute auto-routed bend points for an edge.
|
|
136
|
+
* Returns the corners where the path changes direction.
|
|
137
|
+
*/
|
|
138
|
+
export function extractBendPoints(edge, nodes) {
|
|
139
|
+
const srcNode = nodes[edge.source];
|
|
140
|
+
const tgtNode = nodes[edge.target];
|
|
141
|
+
if (!srcNode || !tgtNode)
|
|
142
|
+
return [];
|
|
143
|
+
const src = sourcePort(srcNode, edge.sourceHandle);
|
|
144
|
+
const tgt = targetPort(tgtNode);
|
|
145
|
+
// Self-referencing edge
|
|
146
|
+
if (edge.source === edge.target) {
|
|
147
|
+
const loopOffset = 40;
|
|
148
|
+
const rightX = src.x + loopOffset;
|
|
149
|
+
const topY = Math.min(src.y, tgt.y) - loopOffset;
|
|
150
|
+
const leftX = tgt.x - loopOffset;
|
|
151
|
+
return [
|
|
152
|
+
point(rightX, src.y),
|
|
153
|
+
point(rightX, topY),
|
|
154
|
+
point(leftX, topY),
|
|
155
|
+
point(leftX, tgt.y),
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
// Normal case: target is to the right of source
|
|
159
|
+
if (tgt.x > src.x + STUB_LENGTH * 2) {
|
|
160
|
+
const midX = (src.x + tgt.x) / 2;
|
|
161
|
+
return [
|
|
162
|
+
point(midX, src.y),
|
|
163
|
+
point(midX, tgt.y),
|
|
164
|
+
];
|
|
165
|
+
}
|
|
166
|
+
// Backwards case: target is to the left or overlapping
|
|
167
|
+
const rightX = src.x + STUB_LENGTH;
|
|
168
|
+
const leftX = tgt.x - STUB_LENGTH;
|
|
169
|
+
const midY = (src.y + tgt.y) / 2;
|
|
170
|
+
const routeY = Math.abs(src.y - tgt.y) < ROW_HEIGHT * 2
|
|
171
|
+
? Math.min(srcNode.y, tgtNode.y) - 30
|
|
172
|
+
: midY;
|
|
173
|
+
return [
|
|
174
|
+
point(rightX, src.y),
|
|
175
|
+
point(rightX, routeY),
|
|
176
|
+
point(leftX, routeY),
|
|
177
|
+
point(leftX, tgt.y),
|
|
178
|
+
];
|
|
179
|
+
}
|
|
180
|
+
// --- Bend consolidation ---
|
|
181
|
+
/**
|
|
182
|
+
* Remove redundant bend points: snap near-collinear points to exact
|
|
183
|
+
* alignment, remove zero-length duplicates, and collapse collinear midpoints.
|
|
184
|
+
*/
|
|
185
|
+
export function consolidateBends(edge, nodes, bends) {
|
|
186
|
+
if (bends.length === 0)
|
|
187
|
+
return bends;
|
|
188
|
+
const srcNode = nodes[edge.source];
|
|
189
|
+
const tgtNode = nodes[edge.target];
|
|
190
|
+
if (!srcNode || !tgtNode)
|
|
191
|
+
return bends;
|
|
192
|
+
const src = sourcePort(srcNode, edge.sourceHandle);
|
|
193
|
+
const tgt = targetPort(tgtNode);
|
|
194
|
+
const snapped = snapBends(src, tgt, bends);
|
|
195
|
+
const points = [src, ...snapped, tgt];
|
|
196
|
+
// Snap near-collinear consecutive points to exact alignment.
|
|
197
|
+
// e.g. (380,279)→(379,74) differs by 1px in X → snap to (380,74).
|
|
198
|
+
for (let i = 1; i < points.length; i++) {
|
|
199
|
+
const prev = points[i - 1];
|
|
200
|
+
const curr = points[i];
|
|
201
|
+
if (Math.abs(prev.x - curr.x) <= SNAP && Math.abs(prev.y - curr.y) > SNAP) {
|
|
202
|
+
points[i] = point(prev.x, curr.y); // near-vertical → align X
|
|
203
|
+
}
|
|
204
|
+
else if (Math.abs(prev.y - curr.y) <= SNAP && Math.abs(prev.x - curr.x) > SNAP) {
|
|
205
|
+
points[i] = point(curr.x, prev.y); // near-horizontal → align Y
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Remove duplicates and collinear midpoints
|
|
209
|
+
const kept = [points[0]];
|
|
210
|
+
for (let i = 1; i < points.length; i++) {
|
|
211
|
+
const prev = kept[kept.length - 1];
|
|
212
|
+
const curr = points[i];
|
|
213
|
+
// Skip zero-length duplicates
|
|
214
|
+
if (Math.abs(prev.x - curr.x) <= SNAP && Math.abs(prev.y - curr.y) <= SNAP)
|
|
215
|
+
continue;
|
|
216
|
+
// Skip collinear midpoints only if monotonic (between prev and next).
|
|
217
|
+
// Direction-reversal vertices (jog peaks) must be preserved.
|
|
218
|
+
if (i < points.length - 1) {
|
|
219
|
+
const next = points[i + 1];
|
|
220
|
+
const sameX = Math.abs(prev.x - curr.x) <= SNAP && Math.abs(curr.x - next.x) <= SNAP;
|
|
221
|
+
const sameY = Math.abs(prev.y - curr.y) <= SNAP && Math.abs(curr.y - next.y) <= SNAP;
|
|
222
|
+
if (sameX && curr.y >= Math.min(prev.y, next.y) && curr.y <= Math.max(prev.y, next.y))
|
|
223
|
+
continue;
|
|
224
|
+
if (sameY && curr.x >= Math.min(prev.x, next.x) && curr.x <= Math.max(prev.x, next.x))
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
kept.push(curr);
|
|
228
|
+
}
|
|
229
|
+
// Strip src (first) and tgt (last) — return only bends
|
|
230
|
+
return kept.slice(1, -1);
|
|
231
|
+
}
|
|
232
|
+
// --- Main API ---
|
|
233
|
+
/**
|
|
234
|
+
* Compute the SVG path for an edge.
|
|
235
|
+
* Uses stored bend points if provided, otherwise auto-routes.
|
|
236
|
+
*/
|
|
237
|
+
export function computeEdgePath(edge, nodes, storedBends) {
|
|
238
|
+
const srcNode = nodes[edge.source];
|
|
239
|
+
const tgtNode = nodes[edge.target];
|
|
240
|
+
if (!srcNode || !tgtNode)
|
|
241
|
+
return null;
|
|
242
|
+
const src = sourcePort(srcNode, edge.sourceHandle);
|
|
243
|
+
const tgt = targetPort(tgtNode);
|
|
244
|
+
const bends = storedBends && storedBends.length > 0
|
|
245
|
+
? snapBends(src, tgt, storedBends)
|
|
246
|
+
: extractBendPoints(edge, nodes);
|
|
247
|
+
return buildPath(src, tgt, bends);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Compute drag/split handles for an edge's segments.
|
|
251
|
+
*/
|
|
252
|
+
export function getEdgeHandles(edge, nodes, storedBends) {
|
|
253
|
+
const srcNode = nodes[edge.source];
|
|
254
|
+
const tgtNode = nodes[edge.target];
|
|
255
|
+
if (!srcNode || !tgtNode)
|
|
256
|
+
return null;
|
|
257
|
+
const src = sourcePort(srcNode, edge.sourceHandle);
|
|
258
|
+
const tgt = targetPort(tgtNode);
|
|
259
|
+
const rawBends = storedBends ?? extractBendPoints(edge, nodes);
|
|
260
|
+
const bends = snapBends(src, tgt, rawBends);
|
|
261
|
+
return { bendPoints: bends, handles: getSegmentHandles(src, tgt, bends) };
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Get drag handles for all segments of the path.
|
|
265
|
+
* Only internal segments are draggable; first/last are split-only.
|
|
266
|
+
* Uses orthogonalized points so handles appear on the rendered path,
|
|
267
|
+
* not floating off diagonal shortcuts.
|
|
268
|
+
*/
|
|
269
|
+
function getSegmentHandles(src, tgt, bends) {
|
|
270
|
+
const raw = [src, ...bends, tgt];
|
|
271
|
+
const handles = [];
|
|
272
|
+
const lastSeg = raw.length - 2; // segment count in original (un-orthogonalized) path
|
|
273
|
+
for (let i = 0; i <= lastSeg; i++) {
|
|
274
|
+
const a = raw[i];
|
|
275
|
+
const b = raw[i + 1];
|
|
276
|
+
const isDiag = Math.abs(a.x - b.x) > 1 && Math.abs(a.y - b.y) > 1;
|
|
277
|
+
if (isDiag) {
|
|
278
|
+
// orthogonalize inserts (b.x, a.y) between a and b,
|
|
279
|
+
// creating H-leg (a → corner) then V-leg (corner → b).
|
|
280
|
+
// Place handle at midpoint of the H-leg.
|
|
281
|
+
const corner = point(b.x, a.y);
|
|
282
|
+
handles.push({
|
|
283
|
+
x: (a.x + corner.x) / 2,
|
|
284
|
+
y: a.y,
|
|
285
|
+
segIndex: i,
|
|
286
|
+
orientation: 'H',
|
|
287
|
+
draggable: i > 0 && i < lastSeg,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
const orientation = Math.abs(a.y - b.y) < 1 ? 'H' : 'V';
|
|
292
|
+
handles.push({
|
|
293
|
+
x: (a.x + b.x) / 2,
|
|
294
|
+
y: (a.y + b.y) / 2,
|
|
295
|
+
segIndex: i,
|
|
296
|
+
orientation,
|
|
297
|
+
draggable: i > 0 && i < lastSeg,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return handles;
|
|
302
|
+
}
|
|
303
|
+
// --- Bend point mutation (pure functions) ---
|
|
304
|
+
/**
|
|
305
|
+
* Prepare bends for dragging by inserting clamp points where needed.
|
|
306
|
+
* When a segment's neighbors are collinear (same orientation), dragging
|
|
307
|
+
* would create diagonal lines. This inserts transition bends so that
|
|
308
|
+
* adjacent segments become perpendicular and stay orthogonal during drag.
|
|
309
|
+
* Call once at drag start, not on every move.
|
|
310
|
+
*/
|
|
311
|
+
export function prepareDrag(edge, nodes, bends, segIndex, orientation) {
|
|
312
|
+
const srcNode = nodes[edge.source];
|
|
313
|
+
const tgtNode = nodes[edge.target];
|
|
314
|
+
const src = sourcePort(srcNode, edge.sourceHandle);
|
|
315
|
+
const tgt = targetPort(tgtNode);
|
|
316
|
+
const result = [...bends];
|
|
317
|
+
let bi = segIndex - 1; // bends-array index of left endpoint
|
|
318
|
+
let bj = segIndex; // bends-array index of right endpoint
|
|
319
|
+
if (orientation === 'H') {
|
|
320
|
+
const y = result[bi].y;
|
|
321
|
+
// Check left neighbor: if at same Y (horizontal run), insert clamp
|
|
322
|
+
const leftPt = bi > 0 ? result[bi - 1] : src;
|
|
323
|
+
if (Math.abs(leftPt.y - y) < 1 && Math.abs(leftPt.x - result[bi].x) > 1) {
|
|
324
|
+
result.splice(bi, 0, { ...result[bi] });
|
|
325
|
+
bi++;
|
|
326
|
+
bj++;
|
|
327
|
+
}
|
|
328
|
+
// Check right neighbor: if at same Y (horizontal run), insert clamp
|
|
329
|
+
const rightPt = bj + 1 < result.length ? result[bj + 1] : tgt;
|
|
330
|
+
if (Math.abs(rightPt.y - y) < 1 && Math.abs(rightPt.x - result[bj].x) > 1) {
|
|
331
|
+
result.splice(bj + 1, 0, { ...result[bj] });
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
const x = result[bi].x;
|
|
336
|
+
const leftPt = bi > 0 ? result[bi - 1] : src;
|
|
337
|
+
if (Math.abs(leftPt.x - x) < 1 && Math.abs(leftPt.y - result[bi].y) > 1) {
|
|
338
|
+
result.splice(bi, 0, { ...result[bi] });
|
|
339
|
+
bi++;
|
|
340
|
+
bj++;
|
|
341
|
+
}
|
|
342
|
+
const rightPt = bj + 1 < result.length ? result[bj + 1] : tgt;
|
|
343
|
+
if (Math.abs(rightPt.x - x) < 1 && Math.abs(rightPt.y - result[bj].y) > 1) {
|
|
344
|
+
result.splice(bj + 1, 0, { ...result[bj] });
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return { bends: result, segIndex: bi + 1 };
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Move a segment by updating the two bend points that define it.
|
|
351
|
+
*/
|
|
352
|
+
export function dragSegment(bends, segIndex, orientation, pos) {
|
|
353
|
+
const result = [...bends];
|
|
354
|
+
if (orientation === 'H') {
|
|
355
|
+
result[segIndex - 1] = { ...result[segIndex - 1], y: pos.y };
|
|
356
|
+
result[segIndex] = { ...result[segIndex], y: pos.y };
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
result[segIndex - 1] = { ...result[segIndex - 1], x: pos.x };
|
|
360
|
+
result[segIndex] = { ...result[segIndex], x: pos.x };
|
|
361
|
+
}
|
|
362
|
+
return result;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Split a segment by inserting a rectangular jog.
|
|
366
|
+
* Returns the new bend points and the draggable segment info.
|
|
367
|
+
*/
|
|
368
|
+
export function splitSegment(edge, nodes, storedBends, handle) {
|
|
369
|
+
const srcNode = nodes[edge.source];
|
|
370
|
+
const tgtNode = nodes[edge.target];
|
|
371
|
+
const src = sourcePort(srcNode, edge.sourceHandle);
|
|
372
|
+
const tgt = targetPort(tgtNode);
|
|
373
|
+
const bends = snapBends(src, tgt, [...storedBends]);
|
|
374
|
+
const points = [src, ...bends, tgt];
|
|
375
|
+
const seg = handle.segIndex;
|
|
376
|
+
const a = points[seg];
|
|
377
|
+
const b = points[seg + 1];
|
|
378
|
+
const insertAt = seg;
|
|
379
|
+
if (handle.orientation === 'H') {
|
|
380
|
+
const mx = (a.x + b.x) / 2;
|
|
381
|
+
bends.splice(insertAt, 0, point(mx, a.y), point(mx, a.y), point(b.x, a.y));
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
const my = (a.y + b.y) / 2;
|
|
385
|
+
bends.splice(insertAt, 0, point(a.x, my), point(a.x, my), point(a.x, b.y));
|
|
386
|
+
}
|
|
387
|
+
return { bends, segIndex: seg + 2, orientation: handle.orientation };
|
|
388
|
+
}
|
package/dist/i18n.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface DiagramTranslations {
|
|
2
|
+
zoom_in: string;
|
|
3
|
+
zoom_out: string;
|
|
4
|
+
fit_view: string;
|
|
5
|
+
reset_layout: string;
|
|
6
|
+
col_type_formula: string;
|
|
7
|
+
col_type_ref: string;
|
|
8
|
+
col_type_set: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const DIAGRAM_TRANSLATIONS_EN: DiagramTranslations;
|
|
11
|
+
export declare function setDiagramTranslations(translations: DiagramTranslations): void;
|
|
12
|
+
export declare function getDiagramTranslations(): DiagramTranslations;
|
|
13
|
+
//# sourceMappingURL=i18n.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/lib/i18n.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,uBAAuB,EAAE,mBAQrC,CAAC;AAIF,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAE9E;AAED,wBAAgB,sBAAsB,IAAI,mBAAmB,CAK5D"}
|
package/dist/i18n.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getContext, hasContext, setContext } from 'svelte';
|
|
2
|
+
export const DIAGRAM_TRANSLATIONS_EN = {
|
|
3
|
+
zoom_in: 'Zoom in',
|
|
4
|
+
zoom_out: 'Zoom out',
|
|
5
|
+
fit_view: 'Fit view',
|
|
6
|
+
reset_layout: 'Reset layout',
|
|
7
|
+
col_type_formula: 'formula',
|
|
8
|
+
col_type_ref: 'ref',
|
|
9
|
+
col_type_set: 'set',
|
|
10
|
+
};
|
|
11
|
+
const DIAGRAM_I18N_KEY = Symbol('dforge-diagram-i18n');
|
|
12
|
+
export function setDiagramTranslations(translations) {
|
|
13
|
+
setContext(DIAGRAM_I18N_KEY, translations);
|
|
14
|
+
}
|
|
15
|
+
export function getDiagramTranslations() {
|
|
16
|
+
if (hasContext(DIAGRAM_I18N_KEY)) {
|
|
17
|
+
return getContext(DIAGRAM_I18N_KEY);
|
|
18
|
+
}
|
|
19
|
+
return DIAGRAM_TRANSLATIONS_EN;
|
|
20
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export { setDiagramTranslations, getDiagramTranslations, DIAGRAM_TRANSLATIONS_EN } from './i18n';
|
|
2
|
+
export type { DiagramTranslations } from './i18n';
|
|
3
|
+
export type { DiagramNode, DiagramEdge, ResolvedEdge, Point, ViewTransform, EntityNodeData, DragSegment } from './diagram-types';
|
|
4
|
+
export type { ModelGetResponse, ModelModule, ModelEntity, ModelConstraint, ModelColumn } from './model-types';
|
|
5
|
+
export { default as SimpleDiagram } from './SimpleDiagram/SimpleDiagram.svelte';
|
|
6
|
+
export { default as ModelDiagram } from './SimpleDiagram/ModelDiagram.svelte';
|
|
7
|
+
export { default as EntityNode } from './EntityNode.svelte';
|
|
8
|
+
export { default as DiagramDebug } from './SimpleDiagram/DiagramDebug.svelte';
|
|
9
|
+
export { simpleLayout, moduleLayout, routeEdge, routeAllEdges } from './SimpleDiagram/simple-layout';
|
|
10
|
+
export type { NodeLookup } from './SimpleDiagram/simple-layout';
|
|
11
|
+
export { buildGraph, buildEntityMap, getModuleColor, MODULE_COLORS } from './model-graph';
|
|
12
|
+
export { buildSvgPath, edgeLabelPos, prepareDragPoints, consolidatePoints, insertJog, getSegmentHandles, applySegmentDrag } from './SimpleDiagram/diagram-geometry';
|
|
13
|
+
export type { SegHandle } from './SimpleDiagram/diagram-geometry';
|
|
14
|
+
export { createPanZoom } from './pan-zoom.svelte';
|
|
15
|
+
export type { PanZoomConfig, ContentBounds } from './pan-zoom.svelte';
|
|
16
|
+
export { createLocalStorageSync } from './local-storage-sync';
|
|
17
|
+
export type { WorkspaceModule, WorkspaceEntity, WorkspaceEdge } from './WorkspaceMap/workspace-types';
|
|
18
|
+
export { buildWorkspaceGraph } from './WorkspaceMap/workspace-graph';
|
|
19
|
+
export { default as WorkspaceMap } from './WorkspaceMap/WorkspaceMap.svelte';
|
|
20
|
+
export { default as ModuleCard } from './WorkspaceMap/ModuleCard.svelte';
|
|
21
|
+
export { computeEdgePath, extractBendPoints, getEdgeHandles, prepareDrag, dragSegment, splitSegment, consolidateBends, PORT_DOT_RADIUS } from './edge-routing';
|
|
22
|
+
export type { EdgePath, SegmentHandle } from './edge-routing';
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,QAAQ,CAAC;AACjG,YAAY,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAGlD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGjI,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG9G,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAG9E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACrG,YAAY,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG1F,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpK,YAAY,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACtG,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAGzE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC/J,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// i18n
|
|
2
|
+
export { setDiagramTranslations, getDiagramTranslations, DIAGRAM_TRANSLATIONS_EN } from './i18n';
|
|
3
|
+
// Components
|
|
4
|
+
export { default as SimpleDiagram } from './SimpleDiagram/SimpleDiagram.svelte';
|
|
5
|
+
export { default as ModelDiagram } from './SimpleDiagram/ModelDiagram.svelte';
|
|
6
|
+
export { default as EntityNode } from './EntityNode.svelte';
|
|
7
|
+
export { default as DiagramDebug } from './SimpleDiagram/DiagramDebug.svelte';
|
|
8
|
+
// Layout
|
|
9
|
+
export { simpleLayout, moduleLayout, routeEdge, routeAllEdges } from './SimpleDiagram/simple-layout';
|
|
10
|
+
// Graph building
|
|
11
|
+
export { buildGraph, buildEntityMap, getModuleColor, MODULE_COLORS } from './model-graph';
|
|
12
|
+
// Geometry
|
|
13
|
+
export { buildSvgPath, edgeLabelPos, prepareDragPoints, consolidatePoints, insertJog, getSegmentHandles, applySegmentDrag } from './SimpleDiagram/diagram-geometry';
|
|
14
|
+
// Pan/Zoom & persistence utilities
|
|
15
|
+
export { createPanZoom } from './pan-zoom.svelte';
|
|
16
|
+
export { createLocalStorageSync } from './local-storage-sync';
|
|
17
|
+
export { buildWorkspaceGraph } from './WorkspaceMap/workspace-graph';
|
|
18
|
+
export { default as WorkspaceMap } from './WorkspaceMap/WorkspaceMap.svelte';
|
|
19
|
+
export { default as ModuleCard } from './WorkspaceMap/ModuleCard.svelte';
|
|
20
|
+
// Edge routing (used by ModelDiagram)
|
|
21
|
+
export { computeEdgePath, extractBendPoints, getEdgeHandles, prepareDrag, dragSegment, splitSegment, consolidateBends, PORT_DOT_RADIUS } from './edge-routing';
|