react-html-graph 1.2.1 → 1.2.2
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/dist/calculations/index.d.ts +15 -1
- package/dist/calculations/index.d.ts.map +1 -1
- package/dist/calculations/index.js +696 -0
- package/dist/calculations/index.js.map +1 -1
- package/dist/calculations/types.d.ts +70 -0
- package/dist/calculations/types.d.ts.map +1 -1
- package/dist/graph/index.d.ts.map +1 -1
- package/dist/graph/index.js +218 -16
- package/dist/graph/index.js.map +1 -1
- package/dist/hooks/connection.d.ts.map +1 -1
- package/dist/hooks/connection.js +5 -2
- package/dist/hooks/connection.js.map +1 -1
- package/dist/hooks/get-viewbox.d.ts +9 -0
- package/dist/hooks/get-viewbox.d.ts.map +1 -0
- package/dist/hooks/get-viewbox.js +20 -0
- package/dist/hooks/get-viewbox.js.map +1 -0
- package/dist/layouts/centralizar.d.ts +1 -0
- package/dist/layouts/centralizar.d.ts.map +1 -0
- package/dist/layouts/centralizar.js +2 -0
- package/dist/layouts/centralizar.js.map +1 -0
- package/dist/layouts/force-direction-layout.d.ts +9 -0
- package/dist/layouts/force-direction-layout.d.ts.map +1 -0
- package/dist/layouts/force-direction-layout.js +11 -0
- package/dist/layouts/force-direction-layout.js.map +1 -0
- package/dist/layouts/index.d.ts +13 -0
- package/dist/layouts/index.d.ts.map +1 -0
- package/dist/layouts/index.js +17 -0
- package/dist/layouts/index.js.map +1 -0
- package/dist/layouts/organic-layout.d.ts +9 -0
- package/dist/layouts/organic-layout.d.ts.map +1 -0
- package/dist/layouts/organic-layout.js +11 -0
- package/dist/layouts/organic-layout.js.map +1 -0
- package/dist/layouts/radial-layout.d.ts +9 -0
- package/dist/layouts/radial-layout.d.ts.map +1 -0
- package/dist/layouts/radial-layout.js +11 -0
- package/dist/layouts/radial-layout.js.map +1 -0
- package/dist/layouts/sequential-layout.d.ts +9 -0
- package/dist/layouts/sequential-layout.d.ts.map +1 -0
- package/dist/layouts/sequential-layout.js +11 -0
- package/dist/layouts/sequential-layout.js.map +1 -0
- package/dist/layouts/shared.d.ts +10 -0
- package/dist/layouts/shared.d.ts.map +1 -0
- package/dist/layouts/shared.js +39 -0
- package/dist/layouts/shared.js.map +1 -0
- package/dist/layouts/structural-layout.d.ts +9 -0
- package/dist/layouts/structural-layout.d.ts.map +1 -0
- package/dist/layouts/structural-layout.js +11 -0
- package/dist/layouts/structural-layout.js.map +1 -0
- package/dist/layouts/tree-layout.d.ts +9 -0
- package/dist/layouts/tree-layout.d.ts.map +1 -0
- package/dist/layouts/tree-layout.js +11 -0
- package/dist/layouts/tree-layout.js.map +1 -0
- package/dist/link/base.d.ts +3 -2
- package/dist/link/base.d.ts.map +1 -1
- package/dist/link/base.js +113 -20
- package/dist/link/base.js.map +1 -1
- package/dist/link/temp-link.d.ts.map +1 -1
- package/dist/link/temp-link.js +6 -4
- package/dist/link/temp-link.js.map +1 -1
- package/dist/module.d.ts +2 -1
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +2 -1
- package/dist/module.js.map +1 -1
- package/dist/nodes/base.d.ts +1 -1
- package/dist/nodes/base.d.ts.map +1 -1
- package/dist/nodes/base.js +59 -22
- package/dist/nodes/base.js.map +1 -1
- package/dist/ports/base.d.ts.map +1 -1
- package/dist/types.d.ts +153 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/hooks/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,YAAY,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/hooks/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Viewbox } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Hook que retorna um getter estável para o viewbox atual, sem causar
|
|
4
|
+
* re-render quando o viewbox muda. Mesma abordagem de `useGetZoom`.
|
|
5
|
+
*
|
|
6
|
+
* @returns Função que retorna o Viewbox mais recente.
|
|
7
|
+
*/
|
|
8
|
+
export default function useGetViewbox(): () => Viewbox;
|
|
9
|
+
//# sourceMappingURL=get-viewbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-viewbox.d.ts","sourceRoot":"","sources":["../../src/hooks/get-viewbox.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGnC;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,kBAapC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
2
|
+
import useViewbox from "./viewbox";
|
|
3
|
+
/**
|
|
4
|
+
* Hook que retorna um getter estável para o viewbox atual, sem causar
|
|
5
|
+
* re-render quando o viewbox muda. Mesma abordagem de `useGetZoom`.
|
|
6
|
+
*
|
|
7
|
+
* @returns Função que retorna o Viewbox mais recente.
|
|
8
|
+
*/
|
|
9
|
+
export default function useGetViewbox() {
|
|
10
|
+
const viewbox = useViewbox();
|
|
11
|
+
const ref = useRef(viewbox);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
ref.current = viewbox;
|
|
14
|
+
}, [viewbox]);
|
|
15
|
+
const getViewbox = useCallback(() => {
|
|
16
|
+
return ref.current;
|
|
17
|
+
}, []);
|
|
18
|
+
return getViewbox;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=get-viewbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-viewbox.js","sourceRoot":"","sources":["../../src/hooks/get-viewbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,UAAU,MAAM,WAAW,CAAC;AAInC;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa;IACjC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,MAAM,CAAU,OAAO,CAAC,CAAC;IAErC,SAAS,CAAC,GAAG,EAAE;QACX,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;IAC1B,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;QAChC,OAAO,GAAG,CAAC,OAAO,CAAC;IACvB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,UAAU,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=centralizar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"centralizar.d.ts","sourceRoot":"","sources":["../../src/layouts/centralizar.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"centralizar.js","sourceRoot":"","sources":["../../src/layouts/centralizar.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GraphLayoutInput, GraphLayoutResult } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout por forças com viés direcional entre origem e destino.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default function forceDirectionLayout(input: GraphLayoutInput): Promise<GraphLayoutResult>;
|
|
9
|
+
//# sourceMappingURL=force-direction-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"force-direction-layout.d.ts","sourceRoot":"","sources":["../../src/layouts/force-direction-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAI/D;;;;;GAKG;AACH,wBAA8B,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAEtG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runLayoutAlgorithm } from "./shared";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout por forças com viés direcional entre origem e destino.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default async function forceDirectionLayout(input) {
|
|
9
|
+
return runLayoutAlgorithm("force-direction", input);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=force-direction-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"force-direction-layout.js","sourceRoot":"","sources":["../../src/layouts/force-direction-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAuB;IACtE,OAAO,kBAAkB,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { GraphLayoutAlgorithm, GraphLayoutInput, GraphLayoutResult } from "../types";
|
|
2
|
+
import forceDirectionLayout from "./force-direction-layout";
|
|
3
|
+
import organicLayout from "./organic-layout";
|
|
4
|
+
import radialLayout from "./radial-layout";
|
|
5
|
+
import sequentialLayout from "./sequential-layout";
|
|
6
|
+
import structuralLayout from "./structural-layout";
|
|
7
|
+
import treeLayout from "./tree-layout";
|
|
8
|
+
/** Assinatura compartilhada por todos os executores de layout. */
|
|
9
|
+
export type GraphLayoutExecutor = (input: GraphLayoutInput) => Promise<GraphLayoutResult>;
|
|
10
|
+
/** Mapa estável dos algoritmos de layout disponíveis. */
|
|
11
|
+
export declare const GRAPH_LAYOUT_EXECUTORS: Record<GraphLayoutAlgorithm, GraphLayoutExecutor>;
|
|
12
|
+
export { forceDirectionLayout, organicLayout, radialLayout, sequentialLayout, structuralLayout, treeLayout };
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/layouts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACrF,OAAO,oBAAoB,MAAM,0BAA0B,CAAC;AAC5D,OAAO,aAAa,MAAM,kBAAkB,CAAC;AAC7C,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAC3C,OAAO,gBAAgB,MAAM,qBAAqB,CAAC;AACnD,OAAO,gBAAgB,MAAM,qBAAqB,CAAC;AACnD,OAAO,UAAU,MAAM,eAAe,CAAC;AAGvC,kEAAkE;AAClE,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAE1F,yDAAyD;AACzD,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,oBAAoB,EAAE,mBAAmB,CAOpF,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import forceDirectionLayout from "./force-direction-layout";
|
|
2
|
+
import organicLayout from "./organic-layout";
|
|
3
|
+
import radialLayout from "./radial-layout";
|
|
4
|
+
import sequentialLayout from "./sequential-layout";
|
|
5
|
+
import structuralLayout from "./structural-layout";
|
|
6
|
+
import treeLayout from "./tree-layout";
|
|
7
|
+
/** Mapa estável dos algoritmos de layout disponíveis. */
|
|
8
|
+
export const GRAPH_LAYOUT_EXECUTORS = {
|
|
9
|
+
"force-direction": forceDirectionLayout,
|
|
10
|
+
organic: organicLayout,
|
|
11
|
+
radial: radialLayout,
|
|
12
|
+
sequential: sequentialLayout,
|
|
13
|
+
structural: structuralLayout,
|
|
14
|
+
tree: treeLayout,
|
|
15
|
+
};
|
|
16
|
+
export { forceDirectionLayout, organicLayout, radialLayout, sequentialLayout, structuralLayout, treeLayout };
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/layouts/index.ts"],"names":[],"mappings":"AACA,OAAO,oBAAoB,MAAM,0BAA0B,CAAC;AAC5D,OAAO,aAAa,MAAM,kBAAkB,CAAC;AAC7C,OAAO,YAAY,MAAM,iBAAiB,CAAC;AAC3C,OAAO,gBAAgB,MAAM,qBAAqB,CAAC;AACnD,OAAO,gBAAgB,MAAM,qBAAqB,CAAC;AACnD,OAAO,UAAU,MAAM,eAAe,CAAC;AAMvC,yDAAyD;AACzD,MAAM,CAAC,MAAM,sBAAsB,GAAsD;IACrF,iBAAiB,EAAE,oBAAoB;IACvC,OAAO,EAAE,aAAa;IACtB,MAAM,EAAE,YAAY;IACpB,UAAU,EAAE,gBAAgB;IAC5B,UAAU,EAAE,gBAAgB;IAC5B,IAAI,EAAE,UAAU;CACnB,CAAC;AAEF,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GraphLayoutInput, GraphLayoutResult } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout orgânico baseado em relaxamento por forças.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default function organicLayout(input: GraphLayoutInput): Promise<GraphLayoutResult>;
|
|
9
|
+
//# sourceMappingURL=organic-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organic-layout.d.ts","sourceRoot":"","sources":["../../src/layouts/organic-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAI/D;;;;;GAKG;AACH,wBAA8B,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAE/F"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runLayoutAlgorithm } from "./shared";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout orgânico baseado em relaxamento por forças.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default async function organicLayout(input) {
|
|
9
|
+
return runLayoutAlgorithm("organic", input);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=organic-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organic-layout.js","sourceRoot":"","sources":["../../src/layouts/organic-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,aAAa,CAAC,KAAuB;IAC/D,OAAO,kBAAkB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GraphLayoutInput, GraphLayoutResult } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout radial distribuindo camadas ao redor de uma raiz.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default function radialLayout(input: GraphLayoutInput): Promise<GraphLayoutResult>;
|
|
9
|
+
//# sourceMappingURL=radial-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radial-layout.d.ts","sourceRoot":"","sources":["../../src/layouts/radial-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAI/D;;;;;GAKG;AACH,wBAA8B,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAE9F"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runLayoutAlgorithm } from "./shared";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout radial distribuindo camadas ao redor de uma raiz.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default async function radialLayout(input) {
|
|
9
|
+
return runLayoutAlgorithm("radial", input);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=radial-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radial-layout.js","sourceRoot":"","sources":["../../src/layouts/radial-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,YAAY,CAAC,KAAuB;IAC9D,OAAO,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GraphLayoutInput, GraphLayoutResult } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout sequencial em linhas/colunas a partir da ordem do grafo.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default function sequentialLayout(input: GraphLayoutInput): Promise<GraphLayoutResult>;
|
|
9
|
+
//# sourceMappingURL=sequential-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequential-layout.d.ts","sourceRoot":"","sources":["../../src/layouts/sequential-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAI/D;;;;;GAKG;AACH,wBAA8B,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAElG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runLayoutAlgorithm } from "./shared";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout sequencial em linhas/colunas a partir da ordem do grafo.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default async function sequentialLayout(input) {
|
|
9
|
+
return runLayoutAlgorithm("sequential", input);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=sequential-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequential-layout.js","sourceRoot":"","sources":["../../src/layouts/sequential-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAuB;IAClE,OAAO,kBAAkB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GraphLayoutAlgorithm, GraphLayoutInput, GraphLayoutResult } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um algoritmo de layout no worker pool a partir do snapshot público.
|
|
4
|
+
*
|
|
5
|
+
* @param algorithm Nome do algoritmo desejado
|
|
6
|
+
* @param input Snapshot de nós/links e opções compartilhadas
|
|
7
|
+
* @returns Resultado com posições e bounds calculados
|
|
8
|
+
*/
|
|
9
|
+
export declare function runLayoutAlgorithm(algorithm: GraphLayoutAlgorithm, input: GraphLayoutInput): Promise<GraphLayoutResult>;
|
|
10
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/layouts/shared.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGrF;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACpC,SAAS,EAAE,oBAAoB,EAC/B,KAAK,EAAE,gBAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CA8B5B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { calculateLayout } from "../calculations";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um algoritmo de layout no worker pool a partir do snapshot público.
|
|
4
|
+
*
|
|
5
|
+
* @param algorithm Nome do algoritmo desejado
|
|
6
|
+
* @param input Snapshot de nós/links e opções compartilhadas
|
|
7
|
+
* @returns Resultado com posições e bounds calculados
|
|
8
|
+
*/
|
|
9
|
+
export async function runLayoutAlgorithm(algorithm, input) {
|
|
10
|
+
const result = await calculateLayout({
|
|
11
|
+
algorithm,
|
|
12
|
+
nodes: input.nodes.map(node => ({
|
|
13
|
+
id: node.id,
|
|
14
|
+
width: node.width,
|
|
15
|
+
height: node.height,
|
|
16
|
+
x: node.position.x,
|
|
17
|
+
y: node.position.y,
|
|
18
|
+
z: node.position.z,
|
|
19
|
+
})),
|
|
20
|
+
links: input.links.map(link => ({
|
|
21
|
+
id: link.id,
|
|
22
|
+
from: link.from,
|
|
23
|
+
to: link.to,
|
|
24
|
+
})),
|
|
25
|
+
options: input.options,
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
positions: result.positions.map(position => ({
|
|
29
|
+
id: position.id,
|
|
30
|
+
position: {
|
|
31
|
+
x: position.x,
|
|
32
|
+
y: position.y,
|
|
33
|
+
z: position.z,
|
|
34
|
+
},
|
|
35
|
+
})),
|
|
36
|
+
bounds: result.bounds,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/layouts/shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIlD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,SAA+B,EAC/B,KAAuB;IAEvB,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;QACjC,SAAS;QACT,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;SACrB,CAAC,CAAC;QACH,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,EAAE,EAAE,IAAI,CAAC,EAAE;SACd,CAAC,CAAC;QACH,OAAO,EAAE,KAAK,CAAC,OAAO;KACzB,CAAC,CAAC;IAEH,OAAO;QACH,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACzC,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,QAAQ,EAAE;gBACN,CAAC,EAAE,QAAQ,CAAC,CAAC;gBACb,CAAC,EAAE,QAAQ,CAAC,CAAC;gBACb,CAAC,EAAE,QAAQ,CAAC,CAAC;aAChB;SACJ,CAAC,CAAC;QACH,MAAM,EAAE,MAAM,CAAC,MAAM;KACxB,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GraphLayoutInput, GraphLayoutResult } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout estrutural hierárquico com base na conectividade.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default function structuralLayout(input: GraphLayoutInput): Promise<GraphLayoutResult>;
|
|
9
|
+
//# sourceMappingURL=structural-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-layout.d.ts","sourceRoot":"","sources":["../../src/layouts/structural-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAI/D;;;;;GAKG;AACH,wBAA8B,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAElG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runLayoutAlgorithm } from "./shared";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout estrutural hierárquico com base na conectividade.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default async function structuralLayout(input) {
|
|
9
|
+
return runLayoutAlgorithm("structural", input);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=structural-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural-layout.js","sourceRoot":"","sources":["../../src/layouts/structural-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAuB;IAClE,OAAO,kBAAkB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GraphLayoutInput, GraphLayoutResult } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout em árvore para grafos com hierarquia predominante.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default function treeLayout(input: GraphLayoutInput): Promise<GraphLayoutResult>;
|
|
9
|
+
//# sourceMappingURL=tree-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-layout.d.ts","sourceRoot":"","sources":["../../src/layouts/tree-layout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAI/D;;;;;GAKG;AACH,wBAA8B,UAAU,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAE5F"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { runLayoutAlgorithm } from "./shared";
|
|
2
|
+
/**
|
|
3
|
+
* Executa um layout em árvore para grafos com hierarquia predominante.
|
|
4
|
+
*
|
|
5
|
+
* @param input Snapshot do grafo e opções compartilhadas
|
|
6
|
+
* @returns Resultado com novas posições para os nós
|
|
7
|
+
*/
|
|
8
|
+
export default async function treeLayout(input) {
|
|
9
|
+
return runLayoutAlgorithm("tree", input);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=tree-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-layout.js","sourceRoot":"","sources":["../../src/layouts/tree-layout.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C;;;;;GAKG;AACH,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,UAAU,CAAC,KAAuB;IAC5D,OAAO,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC7C,CAAC"}
|
package/dist/link/base.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LinkLabel } from "../types";
|
|
1
|
+
import { GraphLinkRuntimeState, LinkLabel } from "../types";
|
|
2
2
|
type GraphLinkProps = {
|
|
3
3
|
id: string;
|
|
4
4
|
from: {
|
|
@@ -20,6 +20,7 @@ type GraphLinkProps = {
|
|
|
20
20
|
gapSize?: number;
|
|
21
21
|
forwardDuration?: number;
|
|
22
22
|
reverseDuration?: number;
|
|
23
|
+
onStateChange?: (state: GraphLinkRuntimeState) => void;
|
|
23
24
|
};
|
|
24
25
|
/**
|
|
25
26
|
* Componente que renderiza um link entre dois nós usando caminhos SVG.
|
|
@@ -29,6 +30,6 @@ type GraphLinkProps = {
|
|
|
29
30
|
* @param props Propriedades do link (GraphLinkProps)
|
|
30
31
|
* @returns JSX.Element
|
|
31
32
|
*/
|
|
32
|
-
declare const MemoizedGraphLink: import("react").MemoExoticComponent<({ id, from, to, width, forwardWidth, reverseWidth, spacing, labels, forwardColor, reverseColor, dashSize, gapSize, forwardDuration, reverseDuration, }: GraphLinkProps) => import("react/jsx-runtime").JSX.Element>;
|
|
33
|
+
declare const MemoizedGraphLink: import("react").MemoExoticComponent<({ id, from, to, width, forwardWidth, reverseWidth, spacing, labels, forwardColor, reverseColor, dashSize, gapSize, forwardDuration, reverseDuration, onStateChange, }: GraphLinkProps) => import("react/jsx-runtime").JSX.Element>;
|
|
33
34
|
export default MemoizedGraphLink;
|
|
34
35
|
//# sourceMappingURL=base.d.ts.map
|
package/dist/link/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/link/base.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/link/base.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAI5D,KAAK,cAAc,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAC1D,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,iBAAiB,8MAgBpB,cAAc,6CA6Wf,CAAA;AAEF,eAAe,iBAAiB,CAAC"}
|
package/dist/link/base.js
CHANGED
|
@@ -12,7 +12,7 @@ import { calculatePath, calculateLabels } from "../calculations";
|
|
|
12
12
|
* @param props Propriedades do link (GraphLinkProps)
|
|
13
13
|
* @returns JSX.Element
|
|
14
14
|
*/
|
|
15
|
-
const MemoizedGraphLink = memo(function GraphLink({ id, from, to, width = 3, forwardWidth, reverseWidth, spacing, labels, forwardColor = "#888", reverseColor = "#888", dashSize = 12, gapSize = 8, forwardDuration = 1, reverseDuration = 1, }) {
|
|
15
|
+
const MemoizedGraphLink = memo(function GraphLink({ id, from, to, width = 3, forwardWidth, reverseWidth, spacing, labels, forwardColor = "#888", reverseColor = "#888", dashSize = 12, gapSize = 8, forwardDuration = 1, reverseDuration = 1, onStateChange, }) {
|
|
16
16
|
const rootRef = useRef(null);
|
|
17
17
|
const forwardRef = useRef(null);
|
|
18
18
|
const reverseRef = useRef(null);
|
|
@@ -33,9 +33,11 @@ const MemoizedGraphLink = memo(function GraphLink({ id, from, to, width = 3, for
|
|
|
33
33
|
const gapRef = useRef(gap);
|
|
34
34
|
const labelsRef = useRef(labels);
|
|
35
35
|
const invalidRef = useRef(invalid);
|
|
36
|
+
const onStateChangeRef = useRef(onStateChange);
|
|
36
37
|
gapRef.current = gap;
|
|
37
38
|
labelsRef.current = labels;
|
|
38
39
|
invalidRef.current = invalid;
|
|
40
|
+
onStateChangeRef.current = onStateChange;
|
|
39
41
|
// Descobre nós
|
|
40
42
|
const checkNodes = useCallback(() => {
|
|
41
43
|
const root = graphRoot.current;
|
|
@@ -97,6 +99,25 @@ const MemoizedGraphLink = memo(function GraphLink({ id, from, to, width = 3, for
|
|
|
97
99
|
root.setAttribute("viewBox", `${bounds.left} ${bounds.top} ${bounds.width} ${bounds.height}`);
|
|
98
100
|
fwd.setAttribute("d", forwardD);
|
|
99
101
|
rev.setAttribute("d", reverseD);
|
|
102
|
+
onStateChangeRef.current?.({
|
|
103
|
+
id,
|
|
104
|
+
from: {
|
|
105
|
+
nodeId: from.node,
|
|
106
|
+
portId: from.port,
|
|
107
|
+
x: pos.fromX,
|
|
108
|
+
y: pos.fromY,
|
|
109
|
+
direction: pos.fromDir,
|
|
110
|
+
},
|
|
111
|
+
to: {
|
|
112
|
+
nodeId: to.node,
|
|
113
|
+
portId: to.port,
|
|
114
|
+
x: pos.toX,
|
|
115
|
+
y: pos.toY,
|
|
116
|
+
direction: pos.toDir,
|
|
117
|
+
},
|
|
118
|
+
bounds,
|
|
119
|
+
invalid: false,
|
|
120
|
+
});
|
|
100
121
|
if (labelResult) {
|
|
101
122
|
const labelGroup = labelGroupRef.current;
|
|
102
123
|
if (labelGroup) {
|
|
@@ -114,17 +135,47 @@ const MemoizedGraphLink = memo(function GraphLink({ id, from, to, width = 3, for
|
|
|
114
135
|
}
|
|
115
136
|
}
|
|
116
137
|
});
|
|
138
|
+
}, [from.node, from.port, id, to.node, to.port]);
|
|
139
|
+
// Acumula offsets do elemento até o ancestral de referência
|
|
140
|
+
const accumulateOffset = useCallback((el, ancestor) => {
|
|
141
|
+
let x = 0;
|
|
142
|
+
let y = 0;
|
|
143
|
+
let current = el;
|
|
144
|
+
while (current && current !== ancestor) {
|
|
145
|
+
x += current.offsetLeft;
|
|
146
|
+
y += current.offsetTop;
|
|
147
|
+
current = current.offsetParent;
|
|
148
|
+
}
|
|
149
|
+
return { x, y };
|
|
117
150
|
}, []);
|
|
118
|
-
// Determina direcao
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
151
|
+
// Determina a direcao da porta pela posicao real dentro do no.
|
|
152
|
+
// Quando a porta estiver centralizada, usa o vetor entre origem e destino
|
|
153
|
+
// como heuristica para escolher um lado mais natural.
|
|
154
|
+
const detectPortDir = useCallback((node, portOrigin, delta, invertDelta = false) => {
|
|
155
|
+
const normalizedDelta = invertDelta
|
|
156
|
+
? { x: -delta.x, y: -delta.y }
|
|
157
|
+
: delta;
|
|
158
|
+
if (!portOrigin) {
|
|
159
|
+
if (Math.abs(normalizedDelta.x) >= Math.abs(normalizedDelta.y)) {
|
|
160
|
+
return normalizedDelta.x >= 0 ? "right" : "left";
|
|
161
|
+
}
|
|
162
|
+
return normalizedDelta.y >= 0 ? "bottom" : "top";
|
|
163
|
+
}
|
|
164
|
+
const relX = portOrigin.x - node.offsetWidth / 2;
|
|
165
|
+
const relY = portOrigin.y - node.offsetHeight / 2;
|
|
166
|
+
const toleranceX = Math.max(4, node.offsetWidth * 0.05);
|
|
167
|
+
const toleranceY = Math.max(4, node.offsetHeight * 0.05);
|
|
168
|
+
const isCentered = Math.abs(relX) <= toleranceX && Math.abs(relY) <= toleranceY;
|
|
169
|
+
if (!isCentered) {
|
|
170
|
+
if (Math.abs(relX) >= Math.abs(relY)) {
|
|
171
|
+
return relX >= 0 ? "right" : "left";
|
|
172
|
+
}
|
|
173
|
+
return relY >= 0 ? "bottom" : "top";
|
|
174
|
+
}
|
|
175
|
+
if (Math.abs(normalizedDelta.x) >= Math.abs(normalizedDelta.y)) {
|
|
176
|
+
return normalizedDelta.x >= 0 ? "right" : "left";
|
|
126
177
|
}
|
|
127
|
-
return
|
|
178
|
+
return normalizedDelta.y >= 0 ? "bottom" : "top";
|
|
128
179
|
}, []);
|
|
129
180
|
// Le posicoes do DOM via ref (sem setState), agenda rAF
|
|
130
181
|
const readPositions = useCallback(() => {
|
|
@@ -132,18 +183,37 @@ const MemoizedGraphLink = memo(function GraphLink({ id, from, to, width = 3, for
|
|
|
132
183
|
return;
|
|
133
184
|
const fromPort = fromNode.querySelector('node-graph-port[port-id="' + from.port + '"]');
|
|
134
185
|
const toPort = toNode.querySelector('node-graph-port[port-id="' + to.port + '"]');
|
|
186
|
+
const fromOffset = fromPort
|
|
187
|
+
? accumulateOffset(fromPort, fromNode)
|
|
188
|
+
: { x: fromNode.offsetWidth / 2, y: fromNode.offsetHeight / 2 };
|
|
189
|
+
const toOffset = toPort
|
|
190
|
+
? accumulateOffset(toPort, toNode)
|
|
191
|
+
: { x: toNode.offsetWidth / 2, y: toNode.offsetHeight / 2 };
|
|
192
|
+
const fromPortOrigin = fromPort
|
|
193
|
+
? {
|
|
194
|
+
x: fromOffset.x + fromPort.offsetWidth / 2,
|
|
195
|
+
y: fromOffset.y + fromPort.offsetHeight / 2,
|
|
196
|
+
} : null;
|
|
197
|
+
const toPortOrigin = toPort
|
|
198
|
+
? {
|
|
199
|
+
x: toOffset.x + toPort.offsetWidth / 2,
|
|
200
|
+
y: toOffset.y + toPort.offsetHeight / 2,
|
|
201
|
+
} : null;
|
|
202
|
+
const fromX = fromNode.offsetLeft + (fromPortOrigin?.x ?? fromOffset.x);
|
|
203
|
+
const fromY = fromNode.offsetTop + (fromPortOrigin?.y ?? fromOffset.y);
|
|
204
|
+
const toX = toNode.offsetLeft + (toPortOrigin?.x ?? toOffset.x);
|
|
205
|
+
const toY = toNode.offsetTop + (toPortOrigin?.y ?? toOffset.y);
|
|
206
|
+
const delta = { x: toX - fromX, y: toY - fromY };
|
|
135
207
|
positionsRef.current = {
|
|
136
|
-
fromX
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
fromDir: detectPortDir(fromNode, fromPort),
|
|
141
|
-
toDir: detectPortDir(toNode, toPort),
|
|
208
|
+
fromX, fromY,
|
|
209
|
+
toX, toY,
|
|
210
|
+
fromDir: detectPortDir(fromNode, fromPortOrigin, delta),
|
|
211
|
+
toDir: detectPortDir(toNode, toPortOrigin, delta, true),
|
|
142
212
|
};
|
|
143
213
|
cancelAnimationFrame(rafIdRef.current);
|
|
144
214
|
rafIdRef.current = requestAnimationFrame(runCalculation);
|
|
145
|
-
}, [fromNode, toNode, from.port, to.port, detectPortDir, runCalculation]);
|
|
146
|
-
//
|
|
215
|
+
}, [fromNode, toNode, from.port, to.port, accumulateOffset, detectPortDir, runCalculation]);
|
|
216
|
+
// Observar mudanças nos nós (posição, tamanho, existência) e recalcular
|
|
147
217
|
useEffect(() => {
|
|
148
218
|
if (!fromNode || !toNode || invalid)
|
|
149
219
|
return;
|
|
@@ -170,10 +240,33 @@ const MemoizedGraphLink = memo(function GraphLink({ id, from, to, width = 3, for
|
|
|
170
240
|
return;
|
|
171
241
|
readPositions();
|
|
172
242
|
}, [viewbox.zoom, fromNode, toNode, invalid, readPositions]);
|
|
173
|
-
// Limpa
|
|
243
|
+
// Limpa animation frame ao desmontar
|
|
174
244
|
useEffect(() => {
|
|
175
245
|
return () => cancelAnimationFrame(rafIdRef.current);
|
|
176
246
|
}, []);
|
|
247
|
+
useEffect(() => {
|
|
248
|
+
if (!invalid)
|
|
249
|
+
return;
|
|
250
|
+
onStateChangeRef.current?.({
|
|
251
|
+
id,
|
|
252
|
+
from: {
|
|
253
|
+
nodeId: from.node,
|
|
254
|
+
portId: from.port,
|
|
255
|
+
x: 0,
|
|
256
|
+
y: 0,
|
|
257
|
+
direction: "right",
|
|
258
|
+
},
|
|
259
|
+
to: {
|
|
260
|
+
nodeId: to.node,
|
|
261
|
+
portId: to.port,
|
|
262
|
+
x: 0,
|
|
263
|
+
y: 0,
|
|
264
|
+
direction: "left",
|
|
265
|
+
},
|
|
266
|
+
bounds: { left: 0, top: 0, width: 0, height: 0 },
|
|
267
|
+
invalid: true,
|
|
268
|
+
});
|
|
269
|
+
}, [from.node, from.port, id, invalid, to.node, to.port]);
|
|
177
270
|
if (invalid)
|
|
178
271
|
return _jsx(_Fragment, {});
|
|
179
272
|
const fwdStroke = fwdW / viewbox.zoom;
|
|
@@ -184,7 +277,7 @@ const MemoizedGraphLink = memo(function GraphLink({ id, from, to, width = 3, for
|
|
|
184
277
|
const cycleLen = scaledDash + scaledGap;
|
|
185
278
|
return (_jsx("node-graph-link", { children: _jsxs("svg", { ref: rootRef, children: [_jsx("path", { ref: forwardRef, d: "", stroke: forwardColor, fill: "none", strokeWidth: fwdStroke, strokeLinecap: "round", strokeDasharray: dashPattern, style: {
|
|
186
279
|
animationDuration: forwardDuration > 0 ? forwardDuration + "s" : "0s",
|
|
187
|
-
animationDirection: "
|
|
280
|
+
animationDirection: "normal",
|
|
188
281
|
["--cycle-len"]: cycleLen + "px",
|
|
189
282
|
} }), _jsx("path", { ref: reverseRef, d: "", stroke: reverseColor, fill: "none", strokeWidth: revStroke, strokeLinecap: "round", strokeDasharray: dashPattern, style: {
|
|
190
283
|
animationDuration: reverseDuration > 0 ? reverseDuration + "s" : "0s",
|