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.
Files changed (71) hide show
  1. package/dist/calculations/index.d.ts +15 -1
  2. package/dist/calculations/index.d.ts.map +1 -1
  3. package/dist/calculations/index.js +696 -0
  4. package/dist/calculations/index.js.map +1 -1
  5. package/dist/calculations/types.d.ts +70 -0
  6. package/dist/calculations/types.d.ts.map +1 -1
  7. package/dist/graph/index.d.ts.map +1 -1
  8. package/dist/graph/index.js +218 -16
  9. package/dist/graph/index.js.map +1 -1
  10. package/dist/hooks/connection.d.ts.map +1 -1
  11. package/dist/hooks/connection.js +5 -2
  12. package/dist/hooks/connection.js.map +1 -1
  13. package/dist/hooks/get-viewbox.d.ts +9 -0
  14. package/dist/hooks/get-viewbox.d.ts.map +1 -0
  15. package/dist/hooks/get-viewbox.js +20 -0
  16. package/dist/hooks/get-viewbox.js.map +1 -0
  17. package/dist/layouts/centralizar.d.ts +1 -0
  18. package/dist/layouts/centralizar.d.ts.map +1 -0
  19. package/dist/layouts/centralizar.js +2 -0
  20. package/dist/layouts/centralizar.js.map +1 -0
  21. package/dist/layouts/force-direction-layout.d.ts +9 -0
  22. package/dist/layouts/force-direction-layout.d.ts.map +1 -0
  23. package/dist/layouts/force-direction-layout.js +11 -0
  24. package/dist/layouts/force-direction-layout.js.map +1 -0
  25. package/dist/layouts/index.d.ts +13 -0
  26. package/dist/layouts/index.d.ts.map +1 -0
  27. package/dist/layouts/index.js +17 -0
  28. package/dist/layouts/index.js.map +1 -0
  29. package/dist/layouts/organic-layout.d.ts +9 -0
  30. package/dist/layouts/organic-layout.d.ts.map +1 -0
  31. package/dist/layouts/organic-layout.js +11 -0
  32. package/dist/layouts/organic-layout.js.map +1 -0
  33. package/dist/layouts/radial-layout.d.ts +9 -0
  34. package/dist/layouts/radial-layout.d.ts.map +1 -0
  35. package/dist/layouts/radial-layout.js +11 -0
  36. package/dist/layouts/radial-layout.js.map +1 -0
  37. package/dist/layouts/sequential-layout.d.ts +9 -0
  38. package/dist/layouts/sequential-layout.d.ts.map +1 -0
  39. package/dist/layouts/sequential-layout.js +11 -0
  40. package/dist/layouts/sequential-layout.js.map +1 -0
  41. package/dist/layouts/shared.d.ts +10 -0
  42. package/dist/layouts/shared.d.ts.map +1 -0
  43. package/dist/layouts/shared.js +39 -0
  44. package/dist/layouts/shared.js.map +1 -0
  45. package/dist/layouts/structural-layout.d.ts +9 -0
  46. package/dist/layouts/structural-layout.d.ts.map +1 -0
  47. package/dist/layouts/structural-layout.js +11 -0
  48. package/dist/layouts/structural-layout.js.map +1 -0
  49. package/dist/layouts/tree-layout.d.ts +9 -0
  50. package/dist/layouts/tree-layout.d.ts.map +1 -0
  51. package/dist/layouts/tree-layout.js +11 -0
  52. package/dist/layouts/tree-layout.js.map +1 -0
  53. package/dist/link/base.d.ts +3 -2
  54. package/dist/link/base.d.ts.map +1 -1
  55. package/dist/link/base.js +113 -20
  56. package/dist/link/base.js.map +1 -1
  57. package/dist/link/temp-link.d.ts.map +1 -1
  58. package/dist/link/temp-link.js +6 -4
  59. package/dist/link/temp-link.js.map +1 -1
  60. package/dist/module.d.ts +2 -1
  61. package/dist/module.d.ts.map +1 -1
  62. package/dist/module.js +2 -1
  63. package/dist/module.js.map +1 -1
  64. package/dist/nodes/base.d.ts +1 -1
  65. package/dist/nodes/base.d.ts.map +1 -1
  66. package/dist/nodes/base.js +59 -22
  67. package/dist/nodes/base.js.map +1 -1
  68. package/dist/ports/base.d.ts.map +1 -1
  69. package/dist/types.d.ts +153 -0
  70. package/dist/types.d.ts.map +1 -1
  71. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/hooks/connection.ts"],"names":[],"mappings":"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"}
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,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=centralizar.js.map
@@ -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"}
@@ -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
@@ -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;AAIrC,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;CAC5B,CAAC;AAEF;;;;;;;GAOG;AACH,QAAA,MAAM,iBAAiB,+LAepB,cAAc,6CA2Pf,CAAA;AAEF,eAAe,iBAAiB,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 de saida da porta baseado na posicao relativa ao centro do no
119
- const detectPortDir = useCallback((node, port) => {
120
- if (!port)
121
- return "right";
122
- const relX = port.offsetLeft + port.offsetWidth / 2 - node.offsetWidth / 2;
123
- const relY = port.offsetTop + port.offsetHeight / 2 - node.offsetHeight / 2;
124
- if (Math.abs(relX) >= Math.abs(relY)) {
125
- return relX >= 0 ? "right" : "left";
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 relY >= 0 ? "bottom" : "top";
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: fromNode.offsetLeft + (fromPort ? fromPort.offsetLeft + fromPort.offsetWidth / 2 : fromNode.offsetWidth),
137
- fromY: fromNode.offsetTop + (fromPort ? fromPort.offsetTop + fromPort.offsetHeight / 2 : fromNode.offsetHeight / 2),
138
- toX: toNode.offsetLeft + (toPort ? toPort.offsetLeft + toPort.offsetWidth / 2 : 0),
139
- toY: toNode.offsetTop + (toPort ? toPort.offsetTop + toPort.offsetHeight / 2 : toNode.offsetHeight / 2),
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
- // Observe node changes
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 rAF ao desmontar
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: "reverse",
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",