@react-fabric/graph 1.0.0-beta.58
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 +10 -0
- package/css/styles.css +56 -0
- package/dist/cjs/_virtual/_commonjs-dynamic-modules.js +7 -0
- package/dist/cjs/_virtual/_commonjsHelpers.js +7 -0
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__auto__createBase64WorkerFactory.js +14 -0
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__auto__isNodeJS.js +9 -0
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__browser__createBase64WorkerFactory.js +35 -0
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__node__WorkerClass.js +11 -0
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__node__createBase64WorkerFactory.js +20 -0
- package/dist/cjs/_virtual/elk-worker.js +8 -0
- package/dist/cjs/_virtual/elk.bundled.js +5 -0
- package/dist/cjs/node_modules/elkjs/lib/elk.bundled.js +6667 -0
- package/dist/cjs/packages/graph/src/components/Context.js +108 -0
- package/dist/cjs/packages/graph/src/components/ContextMenu.js +134 -0
- package/dist/cjs/packages/graph/src/components/Tools.js +127 -0
- package/dist/cjs/packages/graph/src/components/Viewer.js +57 -0
- package/dist/cjs/packages/graph/src/constants/index.js +16 -0
- package/dist/cjs/packages/graph/src/graph/index.js +425 -0
- package/dist/cjs/packages/graph/src/hooks/sigmaDragSelect.js +169 -0
- package/dist/cjs/packages/graph/src/hooks/sigmaHilighter.js +83 -0
- package/dist/cjs/packages/graph/src/hooks/sigmaMouseActions.js +145 -0
- package/dist/cjs/packages/graph/src/hooks/useGraphology.js +41 -0
- package/dist/cjs/packages/graph/src/hooks/useSigma.js +112 -0
- package/dist/cjs/packages/graph/src/index.js +33 -0
- package/dist/cjs/packages/graph/src/programs/arrow-head/frag.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/arrow-head/index.js +142 -0
- package/dist/cjs/packages/graph/src/programs/arrow-head/vert.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/edge-curve/drawLabel.js +136 -0
- package/dist/cjs/packages/graph/src/programs/edge-curve/frag.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/edge-curve/index.js +157 -0
- package/dist/cjs/packages/graph/src/programs/edge-curve/vert.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/edge-line/drawLabel.js +70 -0
- package/dist/cjs/packages/graph/src/programs/edge-line/frag.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/edge-line/index.js +166 -0
- package/dist/cjs/packages/graph/src/programs/edge-line/vert.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/node-badge/factory.js +249 -0
- package/dist/cjs/packages/graph/src/programs/node-badge/frag.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/node-badge/index.js +33 -0
- package/dist/cjs/packages/graph/src/programs/node-badge/texture.js +455 -0
- package/dist/cjs/packages/graph/src/programs/node-badge/vert.glsl.js +19 -0
- package/dist/cjs/packages/graph/src/programs/node-circle/base/drawHover.js +70 -0
- package/dist/cjs/packages/graph/src/programs/node-circle/base/drawLabel.js +112 -0
- package/dist/cjs/packages/graph/src/programs/node-circle/base/frag.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/node-circle/base/index.js +136 -0
- package/dist/cjs/packages/graph/src/programs/node-circle/base/vert.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/node-circle/index.js +15 -0
- package/dist/cjs/packages/graph/src/programs/node-image/factory.js +223 -0
- package/dist/cjs/packages/graph/src/programs/node-image/frag.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/node-image/index.js +14 -0
- package/dist/cjs/packages/graph/src/programs/node-image/texture.js +472 -0
- package/dist/cjs/packages/graph/src/programs/node-image/vert.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/node-rect/base/drawHover.js +67 -0
- package/dist/cjs/packages/graph/src/programs/node-rect/base/drawLabel.js +106 -0
- package/dist/cjs/packages/graph/src/programs/node-rect/base/frag.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/node-rect/base/index.js +135 -0
- package/dist/cjs/packages/graph/src/programs/node-rect/base/vert.glsl.js +8 -0
- package/dist/cjs/packages/graph/src/programs/node-rect/index.js +15 -0
- package/dist/esm/_virtual/_commonjs-dynamic-modules.js +7 -0
- package/dist/esm/_virtual/_commonjsHelpers.js +7 -0
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__auto__createBase64WorkerFactory.js +14 -0
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__auto__isNodeJS.js +9 -0
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__browser__createBase64WorkerFactory.js +34 -0
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__node__WorkerClass.js +13 -0
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__node__createBase64WorkerFactory.js +20 -0
- package/dist/esm/_virtual/elk-worker.js +8 -0
- package/dist/esm/_virtual/elk.bundled.js +5 -0
- package/dist/esm/node_modules/elkjs/lib/elk.bundled.js +6667 -0
- package/dist/esm/packages/graph/src/components/Context.js +107 -0
- package/dist/esm/packages/graph/src/components/ContextMenu.js +134 -0
- package/dist/esm/packages/graph/src/components/Tools.js +127 -0
- package/dist/esm/packages/graph/src/components/Viewer.js +57 -0
- package/dist/esm/packages/graph/src/constants/index.js +16 -0
- package/dist/esm/packages/graph/src/graph/index.js +425 -0
- package/dist/esm/packages/graph/src/hooks/sigmaDragSelect.js +169 -0
- package/dist/esm/packages/graph/src/hooks/sigmaHilighter.js +83 -0
- package/dist/esm/packages/graph/src/hooks/sigmaMouseActions.js +145 -0
- package/dist/esm/packages/graph/src/hooks/useGraphology.js +41 -0
- package/dist/esm/packages/graph/src/hooks/useSigma.js +112 -0
- package/dist/esm/packages/graph/src/index.js +30 -0
- package/dist/esm/packages/graph/src/programs/arrow-head/frag.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/arrow-head/index.js +141 -0
- package/dist/esm/packages/graph/src/programs/arrow-head/vert.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/edge-curve/drawLabel.js +136 -0
- package/dist/esm/packages/graph/src/programs/edge-curve/frag.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/edge-curve/index.js +156 -0
- package/dist/esm/packages/graph/src/programs/edge-curve/vert.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/edge-line/drawLabel.js +70 -0
- package/dist/esm/packages/graph/src/programs/edge-line/frag.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/edge-line/index.js +166 -0
- package/dist/esm/packages/graph/src/programs/edge-line/vert.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/node-badge/factory.js +249 -0
- package/dist/esm/packages/graph/src/programs/node-badge/frag.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/node-badge/index.js +32 -0
- package/dist/esm/packages/graph/src/programs/node-badge/texture.js +445 -0
- package/dist/esm/packages/graph/src/programs/node-badge/vert.glsl.js +19 -0
- package/dist/esm/packages/graph/src/programs/node-circle/base/drawHover.js +70 -0
- package/dist/esm/packages/graph/src/programs/node-circle/base/drawLabel.js +112 -0
- package/dist/esm/packages/graph/src/programs/node-circle/base/frag.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/node-circle/base/index.js +136 -0
- package/dist/esm/packages/graph/src/programs/node-circle/base/vert.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/node-circle/index.js +15 -0
- package/dist/esm/packages/graph/src/programs/node-image/factory.js +223 -0
- package/dist/esm/packages/graph/src/programs/node-image/frag.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/node-image/index.js +13 -0
- package/dist/esm/packages/graph/src/programs/node-image/texture.js +462 -0
- package/dist/esm/packages/graph/src/programs/node-image/vert.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/node-rect/base/drawHover.js +67 -0
- package/dist/esm/packages/graph/src/programs/node-rect/base/drawLabel.js +106 -0
- package/dist/esm/packages/graph/src/programs/node-rect/base/frag.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/node-rect/base/index.js +135 -0
- package/dist/esm/packages/graph/src/programs/node-rect/base/vert.glsl.js +8 -0
- package/dist/esm/packages/graph/src/programs/node-rect/index.js +15 -0
- package/dist/types/components/Context.d.ts +18 -0
- package/dist/types/components/ContextMenu.d.ts +1 -0
- package/dist/types/components/Tools.d.ts +1 -0
- package/dist/types/components/Viewer.d.ts +2 -0
- package/dist/types/constants/index.d.ts +12 -0
- package/dist/types/graph/index.d.ts +30 -0
- package/dist/types/graph/layout.worker.d.ts +1 -0
- package/dist/types/hooks/sigmaDragSelect.d.ts +8 -0
- package/dist/types/hooks/sigmaHilighter.d.ts +3 -0
- package/dist/types/hooks/sigmaMouseActions.d.ts +3 -0
- package/dist/types/hooks/useGraphology.d.ts +6 -0
- package/dist/types/hooks/useSigma.d.ts +8 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/programs/arrow-head/frag.glsl.d.ts +2 -0
- package/dist/types/programs/arrow-head/index.d.ts +9 -0
- package/dist/types/programs/arrow-head/vert.glsl.d.ts +2 -0
- package/dist/types/programs/edge-curve/drawLabel.d.ts +6 -0
- package/dist/types/programs/edge-curve/frag.glsl.d.ts +2 -0
- package/dist/types/programs/edge-curve/index.d.ts +43 -0
- package/dist/types/programs/edge-curve/vert.glsl.d.ts +2 -0
- package/dist/types/programs/edge-line/drawLabel.d.ts +5 -0
- package/dist/types/programs/edge-line/frag.glsl.d.ts +2 -0
- package/dist/types/programs/edge-line/index.d.ts +11 -0
- package/dist/types/programs/edge-line/vert.glsl.d.ts +2 -0
- package/dist/types/programs/node-badge/factory.d.ts +27 -0
- package/dist/types/programs/node-badge/frag.glsl.d.ts +2 -0
- package/dist/types/programs/node-badge/index.d.ts +5 -0
- package/dist/types/programs/node-badge/texture.d.ts +102 -0
- package/dist/types/programs/node-badge/vert.glsl.d.ts +2 -0
- package/dist/types/programs/node-circle/base/drawHover.d.ts +8 -0
- package/dist/types/programs/node-circle/base/drawLabel.d.ts +8 -0
- package/dist/types/programs/node-circle/base/frag.glsl.d.ts +2 -0
- package/dist/types/programs/node-circle/base/index.d.ts +37 -0
- package/dist/types/programs/node-circle/base/vert.glsl.d.ts +2 -0
- package/dist/types/programs/node-circle/index.d.ts +11 -0
- package/dist/types/programs/node-image/factory.d.ts +25 -0
- package/dist/types/programs/node-image/frag.glsl.d.ts +2 -0
- package/dist/types/programs/node-image/index.d.ts +5 -0
- package/dist/types/programs/node-image/texture.d.ts +102 -0
- package/dist/types/programs/node-image/vert.glsl.d.ts +2 -0
- package/dist/types/programs/node-rect/base/drawHover.d.ts +8 -0
- package/dist/types/programs/node-rect/base/drawLabel.d.ts +8 -0
- package/dist/types/programs/node-rect/base/frag.glsl.d.ts +2 -0
- package/dist/types/programs/node-rect/base/index.d.ts +34 -0
- package/dist/types/programs/node-rect/base/vert.glsl.d.ts +2 -0
- package/dist/types/programs/node-rect/index.d.ts +11 -0
- package/dist/types/types/index.d.ts +189 -0
- package/package.json +69 -0
- package/src/components/Context.tsx +135 -0
- package/src/components/ContextMenu.tsx +156 -0
- package/src/components/Tools.tsx +107 -0
- package/src/components/Viewer.tsx +75 -0
- package/src/constants/index.ts +22 -0
- package/src/graph/index.ts +428 -0
- package/src/graph/layout.worker.ts +42 -0
- package/src/hooks/sigmaDragSelect.ts +219 -0
- package/src/hooks/sigmaHilighter.ts +107 -0
- package/src/hooks/sigmaMouseActions.ts +153 -0
- package/src/hooks/useGraphology.ts +31 -0
- package/src/hooks/useSigma.ts +118 -0
- package/src/index.ts +34 -0
- package/src/programs/arrow-head/frag.glsl.ts +18 -0
- package/src/programs/arrow-head/index.ts +148 -0
- package/src/programs/arrow-head/vert.glsl.ts +75 -0
- package/src/programs/edge-curve/drawLabel.ts +166 -0
- package/src/programs/edge-curve/frag.glsl.ts +86 -0
- package/src/programs/edge-curve/index.ts +158 -0
- package/src/programs/edge-curve/vert.glsl.ts +110 -0
- package/src/programs/edge-line/drawLabel.ts +113 -0
- package/src/programs/edge-line/frag.glsl.ts +34 -0
- package/src/programs/edge-line/index.ts +165 -0
- package/src/programs/edge-line/vert.glsl.ts +104 -0
- package/src/programs/node-badge/factory.ts +327 -0
- package/src/programs/node-badge/frag.glsl.ts +79 -0
- package/src/programs/node-badge/index.ts +35 -0
- package/src/programs/node-badge/texture.ts +425 -0
- package/src/programs/node-badge/vert.glsl.ts +99 -0
- package/src/programs/node-circle/base/drawHover.ts +80 -0
- package/src/programs/node-circle/base/drawLabel.ts +145 -0
- package/src/programs/node-circle/base/frag.glsl.ts +72 -0
- package/src/programs/node-circle/base/index.ts +102 -0
- package/src/programs/node-circle/base/vert.glsl.ts +83 -0
- package/src/programs/node-circle/index.ts +19 -0
- package/src/programs/node-image/factory.ts +301 -0
- package/src/programs/node-image/frag.glsl.ts +97 -0
- package/src/programs/node-image/index.ts +7 -0
- package/src/programs/node-image/texture.ts +435 -0
- package/src/programs/node-image/vert.glsl.ts +60 -0
- package/src/programs/node-rect/base/drawHover.ts +77 -0
- package/src/programs/node-rect/base/drawLabel.ts +149 -0
- package/src/programs/node-rect/base/frag.glsl.ts +67 -0
- package/src/programs/node-rect/base/index.ts +109 -0
- package/src/programs/node-rect/base/vert.glsl.ts +87 -0
- package/src/programs/node-rect/index.ts +19 -0
- package/src/types/index.ts +210 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { debounce } from "@react-fabric/utilities";
|
|
2
|
+
import type Graph from "graphology";
|
|
3
|
+
import type Sigma from "sigma";
|
|
4
|
+
import { SigmaEdgeEventPayload, SigmaNodeEventPayload } from "sigma/types";
|
|
5
|
+
import { EdgeAttributes, NodeAttributes } from "../types";
|
|
6
|
+
|
|
7
|
+
export const attachHighlighter = (
|
|
8
|
+
renderer: Sigma<NodeAttributes<any>, EdgeAttributes<any>>,
|
|
9
|
+
) => {
|
|
10
|
+
const handleEnterNode = (id: string, graph: Graph) => {
|
|
11
|
+
try {
|
|
12
|
+
const neighbors = graph.neighbors(id);
|
|
13
|
+
graph.forEachNode((node) => {
|
|
14
|
+
graph.setNodeAttribute(
|
|
15
|
+
node,
|
|
16
|
+
"opacity",
|
|
17
|
+
node !== id && !neighbors.includes(node) ? 0.1 : 1,
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
graph.forEachEdge((edge) => {
|
|
21
|
+
graph.setEdgeAttribute(
|
|
22
|
+
edge,
|
|
23
|
+
"opacity",
|
|
24
|
+
!graph.hasExtremity(edge, id) ? 0.1 : 1,
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
} catch {
|
|
28
|
+
//
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const handleLeaveNode = (graph: Graph) => {
|
|
33
|
+
graph.forEachNode((node) => {
|
|
34
|
+
graph.setNodeAttribute(node, "opacity", 1);
|
|
35
|
+
});
|
|
36
|
+
graph.forEachEdge((edge) => {
|
|
37
|
+
graph.setEdgeAttribute(edge, "opacity", 1);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const handleEnterEdge = (id: string, graph: Graph) => {
|
|
42
|
+
try {
|
|
43
|
+
const source = graph.source(id);
|
|
44
|
+
const target = graph.target(id);
|
|
45
|
+
|
|
46
|
+
graph.setEdgeAttribute(id, "zIndex", 2);
|
|
47
|
+
graph.setNodeAttribute(source, "zIndex", 2);
|
|
48
|
+
graph.setNodeAttribute(target, "zIndex", 2);
|
|
49
|
+
|
|
50
|
+
graph.setEdgeAttribute(id, "highlight", true);
|
|
51
|
+
graph.setNodeAttribute(source, "highlight", true);
|
|
52
|
+
graph.setNodeAttribute(target, "highlight", true);
|
|
53
|
+
|
|
54
|
+
graph.forEachNode((node) => {
|
|
55
|
+
graph.setNodeAttribute(
|
|
56
|
+
node,
|
|
57
|
+
"opacity",
|
|
58
|
+
node !== source && node !== target ? 0.1 : 1,
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
graph.forEachEdge((edge) => {
|
|
62
|
+
graph.setEdgeAttribute(edge, "opacity", edge !== id ? 0.1 : 1);
|
|
63
|
+
});
|
|
64
|
+
} catch {
|
|
65
|
+
//
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const handleLeaveEdge = (id: string, graph: Graph) => {
|
|
70
|
+
const source = graph.source(id);
|
|
71
|
+
const target = graph.target(id);
|
|
72
|
+
|
|
73
|
+
graph.setEdgeAttribute(id, "zIndex", 0);
|
|
74
|
+
graph.setNodeAttribute(source, "zIndex", 0);
|
|
75
|
+
graph.setNodeAttribute(target, "zIndex", 0);
|
|
76
|
+
|
|
77
|
+
graph.setEdgeAttribute(id, "highlight", false);
|
|
78
|
+
graph.setNodeAttribute(source, "highlight", false);
|
|
79
|
+
graph.setNodeAttribute(target, "highlight", false);
|
|
80
|
+
|
|
81
|
+
graph.forEachNode((node) => {
|
|
82
|
+
graph.setNodeAttribute(node, "opacity", 1);
|
|
83
|
+
graph.setNodeAttribute(node, "highlight", false);
|
|
84
|
+
});
|
|
85
|
+
graph.forEachEdge((edge) => {
|
|
86
|
+
graph.setEdgeAttribute(edge, "opacity", 1);
|
|
87
|
+
graph.setEdgeAttribute(edge, "highlight", false);
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const debouceNodeEnter = debounce((e: SigmaNodeEventPayload) => {
|
|
92
|
+
handleEnterNode(e.node, renderer.getGraph());
|
|
93
|
+
});
|
|
94
|
+
const debouceEdgeEnter = debounce((e: SigmaEdgeEventPayload) => {
|
|
95
|
+
handleEnterEdge(e.edge, renderer.getGraph());
|
|
96
|
+
}, 100);
|
|
97
|
+
renderer.on("enterNode", debouceNodeEnter);
|
|
98
|
+
renderer.on("leaveNode", (e) => {
|
|
99
|
+
debouceNodeEnter.cancel();
|
|
100
|
+
handleLeaveNode(renderer.getGraph());
|
|
101
|
+
});
|
|
102
|
+
renderer.on("enterEdge", debouceEdgeEnter);
|
|
103
|
+
renderer.on("leaveEdge", (e) => {
|
|
104
|
+
debouceEdgeEnter.cancel();
|
|
105
|
+
handleLeaveEdge(e.edge, renderer.getGraph());
|
|
106
|
+
});
|
|
107
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import type Graph from "graphology";
|
|
2
|
+
import type Sigma from "sigma";
|
|
3
|
+
import { type MouseCoords } from "sigma/types";
|
|
4
|
+
import { EdgeAttributes, NodeAttributes } from "../types";
|
|
5
|
+
|
|
6
|
+
export const attachMouseActions = (
|
|
7
|
+
renderer: Sigma<NodeAttributes<any>, EdgeAttributes<any>>,
|
|
8
|
+
) => {
|
|
9
|
+
let isDragging = false;
|
|
10
|
+
let isDragged = false;
|
|
11
|
+
let startPos = { x: 0, y: 0 };
|
|
12
|
+
let draggedNode: AnyObject;
|
|
13
|
+
|
|
14
|
+
const handleDrag =
|
|
15
|
+
(renderer: Sigma<NodeAttributes<any>, EdgeAttributes<any>>) =>
|
|
16
|
+
(e: MouseCoords) => {
|
|
17
|
+
if (!isDragging || !draggedNode) return;
|
|
18
|
+
|
|
19
|
+
isDragged = true;
|
|
20
|
+
// Get new position of node
|
|
21
|
+
const pos = renderer.viewportToGraph(e);
|
|
22
|
+
const diff = { x: pos.x - startPos.x, y: pos.y - startPos.y };
|
|
23
|
+
|
|
24
|
+
const graph = renderer.getGraph();
|
|
25
|
+
Object.entries<KeyValue>(draggedNode).forEach(([node, xy]) => {
|
|
26
|
+
graph.setNodeAttribute(node, "x", xy.x + diff.x);
|
|
27
|
+
graph.setNodeAttribute(node, "y", xy.y + diff.y);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Prevent sigma to move camera:
|
|
31
|
+
e.preventSigmaDefault();
|
|
32
|
+
e.original.preventDefault();
|
|
33
|
+
e.original.stopPropagation();
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const stopDragging = (graph: Graph) => {
|
|
37
|
+
// if (draggedNode) {
|
|
38
|
+
// Object.entries<KeyValue>(draggedNode).forEach(([node, xy]) => {
|
|
39
|
+
// const atts = graph.getNodeAttributes(node);
|
|
40
|
+
// if (atts.isGroup) {
|
|
41
|
+
// const diff = { x: atts.x - xy.x, y: atts.y - xy.y };
|
|
42
|
+
// atts.nodes?.forEach((id: string) => {
|
|
43
|
+
// try {
|
|
44
|
+
// const { x, y } = graph.getNodeAttributes(id);
|
|
45
|
+
// graph.setNodeAttribute(id, "x", x + diff.x);
|
|
46
|
+
// graph.setNodeAttribute(id, "y", y + diff.y);
|
|
47
|
+
// } catch {
|
|
48
|
+
// //
|
|
49
|
+
// }
|
|
50
|
+
// });
|
|
51
|
+
// }
|
|
52
|
+
// });
|
|
53
|
+
// }
|
|
54
|
+
isDragging = false;
|
|
55
|
+
draggedNode = undefined;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const enableDragging = (
|
|
59
|
+
renderer: Sigma<NodeAttributes<any>, EdgeAttributes<any>>,
|
|
60
|
+
) => {
|
|
61
|
+
renderer.on("downNode", (e) => {
|
|
62
|
+
if ("button" in e.event.original && e.event.original.button === 0) {
|
|
63
|
+
const graph = renderer.getGraph();
|
|
64
|
+
isDragging = true;
|
|
65
|
+
draggedNode = {};
|
|
66
|
+
const { x = 0, y = 0 } = graph.getNodeAttributes(e.node);
|
|
67
|
+
draggedNode[e.node] = { x, y };
|
|
68
|
+
startPos = { x, y };
|
|
69
|
+
graph.forEachNode((node, atts) => {
|
|
70
|
+
if (atts.selected) {
|
|
71
|
+
draggedNode[node] = { x: atts.x, y: atts.y };
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// On mouse move, if the drag mode is enabled, we change the position of the draggedNode
|
|
78
|
+
renderer.getMouseCaptor().on("mousemovebody", handleDrag(renderer));
|
|
79
|
+
|
|
80
|
+
// On mouse up, we reset the autoscale and the dragging mode
|
|
81
|
+
renderer.getMouseCaptor().on("mouseup", (e) => {
|
|
82
|
+
if (isDragging) {
|
|
83
|
+
stopDragging(renderer.getGraph());
|
|
84
|
+
e.original.preventDefault();
|
|
85
|
+
e.preventSigmaDefault();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Disable the autoscale at the first down interaction
|
|
90
|
+
renderer.getMouseCaptor().on("mousedown", () => {
|
|
91
|
+
if (!renderer.getCustomBBox()) renderer.setCustomBBox(renderer.getBBox());
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const resetSelection = (graph: Graph) => {
|
|
96
|
+
graph.forEachNode(
|
|
97
|
+
(node, atts) =>
|
|
98
|
+
atts.selected && graph.setNodeAttribute(node, "selected", false),
|
|
99
|
+
);
|
|
100
|
+
graph.forEachEdge(
|
|
101
|
+
(node, atts) =>
|
|
102
|
+
atts.selected && graph.setEdgeAttribute(node, "selected", false),
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const enableSelection = (
|
|
107
|
+
renderer: Sigma<NodeAttributes<any>, EdgeAttributes<any>>,
|
|
108
|
+
) => {
|
|
109
|
+
renderer.on("downNode", (e) => {
|
|
110
|
+
if ("button" in e.event.original && e.event.original.button === 2) {
|
|
111
|
+
const isSelected = renderer
|
|
112
|
+
.getGraph()
|
|
113
|
+
.getNodeAttribute(e.node, "selected");
|
|
114
|
+
|
|
115
|
+
!isSelected && resetSelection(renderer.getGraph());
|
|
116
|
+
!isSelected &&
|
|
117
|
+
renderer.getGraph().setNodeAttribute(e.node, "selected", true);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
renderer.on("downEdge", (e) => {
|
|
121
|
+
if ("button" in e.event.original && e.event.original.button === 2) {
|
|
122
|
+
const isSelected = renderer
|
|
123
|
+
.getGraph()
|
|
124
|
+
.getEdgeAttribute(e.edge, "selected");
|
|
125
|
+
|
|
126
|
+
!isSelected && resetSelection(renderer.getGraph());
|
|
127
|
+
!isSelected &&
|
|
128
|
+
renderer.getGraph().setEdgeAttribute(e.edge, "selected", true);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
renderer.on("clickNode", (e) => {
|
|
132
|
+
if (
|
|
133
|
+
!isDragged &&
|
|
134
|
+
"button" in e.event.original &&
|
|
135
|
+
e.event.original.button === 0
|
|
136
|
+
) {
|
|
137
|
+
const isSelected = renderer
|
|
138
|
+
.getGraph()
|
|
139
|
+
.getNodeAttribute(e.node, "selected");
|
|
140
|
+
|
|
141
|
+
!e.event.original.shiftKey && resetSelection(renderer.getGraph());
|
|
142
|
+
renderer.getGraph().setNodeAttribute(e.node, "selected", !isSelected);
|
|
143
|
+
}
|
|
144
|
+
isDragged = false;
|
|
145
|
+
});
|
|
146
|
+
renderer.on("downStage", (e) => {
|
|
147
|
+
resetSelection(renderer.getGraph());
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
enableSelection(renderer);
|
|
152
|
+
enableDragging(renderer);
|
|
153
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { Graph } from "../graph";
|
|
3
|
+
import { GraphProps } from "../types";
|
|
4
|
+
|
|
5
|
+
export const useGraphology = <N, E>(data: GraphProps<N, E>["data"]) => {
|
|
6
|
+
const [graph, setGraph] = useState(new Graph<N, E>({ multi: true }));
|
|
7
|
+
|
|
8
|
+
const [selected, setSelected] = useState<string[]>([]);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (data instanceof Graph) {
|
|
12
|
+
setGraph(data);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
graph.clear();
|
|
16
|
+
data && graph.import(data, false);
|
|
17
|
+
}, [data]);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const handler = (nodes: string[]) => {
|
|
21
|
+
setSelected(nodes);
|
|
22
|
+
};
|
|
23
|
+
graph.on("nodesSelected", handler);
|
|
24
|
+
|
|
25
|
+
return () => {
|
|
26
|
+
graph.off("nodesSelected", handler);
|
|
27
|
+
};
|
|
28
|
+
}, [graph]);
|
|
29
|
+
|
|
30
|
+
return { graph, selected };
|
|
31
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { useIsDark } from "@react-fabric/core";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import Sigma from "sigma";
|
|
4
|
+
import { Graph } from "../graph";
|
|
5
|
+
import { EdgeCurveProgram } from "../programs/edge-curve";
|
|
6
|
+
import { EdgeLineProgram } from "../programs/edge-line";
|
|
7
|
+
import { NodeCircleProgram } from "../programs/node-circle";
|
|
8
|
+
import { NodeRectProgram } from "../programs/node-rect";
|
|
9
|
+
import {
|
|
10
|
+
EdgeAttributes,
|
|
11
|
+
InternalEdgeAttributes,
|
|
12
|
+
InternalNodeAttributes,
|
|
13
|
+
NodeAttributes,
|
|
14
|
+
} from "../types";
|
|
15
|
+
import { attachHighlighter } from "./sigmaHilighter";
|
|
16
|
+
import { attachMouseActions } from "./sigmaMouseActions";
|
|
17
|
+
|
|
18
|
+
export const useSigma = <N, E>(
|
|
19
|
+
graph: Graph<N, E>,
|
|
20
|
+
nodeReducer?: (node: NodeAttributes<N>) => NodeAttributes<N>,
|
|
21
|
+
edgeReducer?: (edge: EdgeAttributes<E>) => EdgeAttributes<E>,
|
|
22
|
+
) => {
|
|
23
|
+
const [containerRef, setContainerRef] = useState<HTMLDivElement | null>(null);
|
|
24
|
+
const [componentsRef, setComponentsRef] = useState<HTMLDivElement | null>(
|
|
25
|
+
null,
|
|
26
|
+
);
|
|
27
|
+
const isDark = useIsDark();
|
|
28
|
+
|
|
29
|
+
const [sigma, updateSigma] =
|
|
30
|
+
useState<Sigma<NodeAttributes<N>, EdgeAttributes<E>>>();
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (containerRef) {
|
|
34
|
+
const renderer = new Sigma<
|
|
35
|
+
InternalNodeAttributes<N>,
|
|
36
|
+
InternalEdgeAttributes<E>
|
|
37
|
+
>(graph as any, containerRef, {
|
|
38
|
+
allowInvalidContainer: true,
|
|
39
|
+
enableEdgeEvents: true,
|
|
40
|
+
renderEdgeLabels: true,
|
|
41
|
+
renderLabels: true,
|
|
42
|
+
labelSize: 14,
|
|
43
|
+
defaultEdgeType: "line",
|
|
44
|
+
defaultNodeType: "circle",
|
|
45
|
+
edgeProgramClasses: {
|
|
46
|
+
line: EdgeLineProgram,
|
|
47
|
+
curved: EdgeCurveProgram,
|
|
48
|
+
},
|
|
49
|
+
// for some reason max ratio is min zoom and min ratio is max zoom
|
|
50
|
+
maxCameraRatio: 10,
|
|
51
|
+
minCameraRatio: 0.01,
|
|
52
|
+
nodeProgramClasses: {
|
|
53
|
+
rect: NodeRectProgram,
|
|
54
|
+
circle: NodeCircleProgram,
|
|
55
|
+
},
|
|
56
|
+
nodeReducer(key, data) {
|
|
57
|
+
const nodeData: InternalNodeAttributes<N> =
|
|
58
|
+
nodeReducer?.(data) || data;
|
|
59
|
+
// Ensure node size is at least 16 for visibility
|
|
60
|
+
if (!nodeData.size && nodeData.weight) {
|
|
61
|
+
nodeData.size = Math.max(16, nodeData.weight * 3);
|
|
62
|
+
}
|
|
63
|
+
if ((nodeData.size ?? 0) < 16) {
|
|
64
|
+
nodeData.size = 16;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ensure node label renderer is called in order to render selected border
|
|
68
|
+
nodeData.label = nodeData.label || "";
|
|
69
|
+
nodeData.id = key;
|
|
70
|
+
return nodeData;
|
|
71
|
+
},
|
|
72
|
+
edgeReducer(key, data) {
|
|
73
|
+
const edgeData: InternalEdgeAttributes<E> =
|
|
74
|
+
edgeReducer?.(data) || data;
|
|
75
|
+
// Ensure edge size is at least 0.5 for visibility
|
|
76
|
+
if (!edgeData.size && edgeData.weight) {
|
|
77
|
+
edgeData.size = Math.max(0.5, edgeData.weight * 6);
|
|
78
|
+
}
|
|
79
|
+
if ((edgeData.size ?? 0) < 0.5) {
|
|
80
|
+
edgeData.size = 0.5;
|
|
81
|
+
}
|
|
82
|
+
edgeData.id = key;
|
|
83
|
+
return edgeData;
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
attachMouseActions(renderer);
|
|
88
|
+
attachHighlighter(renderer);
|
|
89
|
+
|
|
90
|
+
// containerRef?.insertBefore(
|
|
91
|
+
// componentsRef,
|
|
92
|
+
// renderer.getCanvases().mouse,
|
|
93
|
+
// );
|
|
94
|
+
|
|
95
|
+
// @ts-expect-error ignore
|
|
96
|
+
window.sigma = renderer;
|
|
97
|
+
updateSigma(renderer);
|
|
98
|
+
|
|
99
|
+
return () => {
|
|
100
|
+
renderer.kill();
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}, [graph, containerRef, componentsRef]);
|
|
104
|
+
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
sigma?.setSettings({
|
|
107
|
+
defaultNodeColor: isDark ? "#000" : "#fff",
|
|
108
|
+
defaultEdgeColor: isDark ? "#fff" : "#000",
|
|
109
|
+
labelColor: { color: isDark ? "#fff" : "#000", attribute: "labelColor" },
|
|
110
|
+
});
|
|
111
|
+
}, [isDark, sigma]);
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
instance: sigma,
|
|
115
|
+
containerRef: setContainerRef,
|
|
116
|
+
componentsRef: setComponentsRef,
|
|
117
|
+
};
|
|
118
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* React Fabric
|
|
3
|
+
* @version: 1.0.0
|
|
4
|
+
*
|
|
5
|
+
*
|
|
6
|
+
* The MIT License (MIT)
|
|
7
|
+
* Copyright (c) 2024 Adarsh Pastakia
|
|
8
|
+
*
|
|
9
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
|
10
|
+
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
11
|
+
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
12
|
+
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
|
13
|
+
* subject to the following conditions:
|
|
14
|
+
*
|
|
15
|
+
* The above copyright notice and this permission notice shall be included in all copies or substantial
|
|
16
|
+
* portions of the Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
19
|
+
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
20
|
+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
export { SigmaGraph } from "./components/Viewer";
|
|
25
|
+
export { Graph } from "./graph";
|
|
26
|
+
export type {
|
|
27
|
+
EdgeAttributes,
|
|
28
|
+
GraphRef,
|
|
29
|
+
NodeAttributes,
|
|
30
|
+
RawGraph,
|
|
31
|
+
} from "./types";
|
|
32
|
+
|
|
33
|
+
// @ts-expect-error ignore
|
|
34
|
+
window.__GRAPH_LAYOUT_DURATION_MULTIPLIER__ = 10;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/* istanbul ignore file */
|
|
2
|
+
|
|
3
|
+
// language=GLSL
|
|
4
|
+
const SHADER_SOURCE = /*glsl*/ `
|
|
5
|
+
precision mediump float;
|
|
6
|
+
|
|
7
|
+
varying vec4 v_color;
|
|
8
|
+
varying float v_opacity;
|
|
9
|
+
|
|
10
|
+
const vec4 transparent = vec4(0.0, 0.0, 0.0, 0.0);
|
|
11
|
+
|
|
12
|
+
void main(void) {
|
|
13
|
+
gl_FragColor = v_color;
|
|
14
|
+
gl_FragColor = mix(transparent, gl_FragColor, v_opacity);
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export default SHADER_SOURCE;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { Attributes } from "graphology-types";
|
|
2
|
+
|
|
3
|
+
import { EdgeProgram, EdgeProgramType, ProgramInfo } from "sigma/rendering";
|
|
4
|
+
import { EdgeDisplayData, NodeDisplayData, RenderParams } from "sigma/types";
|
|
5
|
+
import { floatColor } from "sigma/utils";
|
|
6
|
+
import { InternalEdgeAttributes } from "../../types";
|
|
7
|
+
import FRAGMENT_SHADER_SOURCE from "./frag.glsl";
|
|
8
|
+
import VERTEX_SHADER_SOURCE from "./vert.glsl";
|
|
9
|
+
|
|
10
|
+
const { UNSIGNED_BYTE, FLOAT } = WebGLRenderingContext;
|
|
11
|
+
|
|
12
|
+
const UNIFORMS = [
|
|
13
|
+
"u_matrix",
|
|
14
|
+
"u_sizeRatio",
|
|
15
|
+
"u_correctionRatio",
|
|
16
|
+
"u_minEdgeThickness",
|
|
17
|
+
"u_lengthToThicknessRatio",
|
|
18
|
+
"u_widenessToThicknessRatio",
|
|
19
|
+
] as const;
|
|
20
|
+
|
|
21
|
+
export type CreateEdgeArrowHeadProgramOptions = {
|
|
22
|
+
extremity: "source" | "target";
|
|
23
|
+
lengthToThicknessRatio: number;
|
|
24
|
+
widenessToThicknessRatio: number;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const DEFAULT_EDGE_ARROW_HEAD_PROGRAM_OPTIONS: CreateEdgeArrowHeadProgramOptions =
|
|
28
|
+
{
|
|
29
|
+
extremity: "target",
|
|
30
|
+
lengthToThicknessRatio: 2.5,
|
|
31
|
+
widenessToThicknessRatio: 2,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export function createEdgeArrowHeadProgram<
|
|
35
|
+
N extends Attributes = Attributes,
|
|
36
|
+
E extends Attributes = Attributes,
|
|
37
|
+
G extends Attributes = Attributes,
|
|
38
|
+
>(
|
|
39
|
+
inputOptions?: Partial<CreateEdgeArrowHeadProgramOptions>,
|
|
40
|
+
): EdgeProgramType<N, E, G> {
|
|
41
|
+
const options = {
|
|
42
|
+
...DEFAULT_EDGE_ARROW_HEAD_PROGRAM_OPTIONS,
|
|
43
|
+
...(inputOptions || {}),
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return class EdgeArrowHeadProgram<
|
|
47
|
+
N extends Attributes = Attributes,
|
|
48
|
+
E extends Attributes = Attributes,
|
|
49
|
+
G extends Attributes = Attributes,
|
|
50
|
+
> extends EdgeProgram<(typeof UNIFORMS)[number], N, E, G> {
|
|
51
|
+
getDefinition() {
|
|
52
|
+
return {
|
|
53
|
+
VERTICES: 3,
|
|
54
|
+
VERTEX_SHADER_SOURCE,
|
|
55
|
+
FRAGMENT_SHADER_SOURCE,
|
|
56
|
+
METHOD: WebGLRenderingContext.TRIANGLES,
|
|
57
|
+
UNIFORMS,
|
|
58
|
+
ATTRIBUTES: [
|
|
59
|
+
{ name: "a_position", size: 2, type: FLOAT },
|
|
60
|
+
{ name: "a_normal", size: 2, type: FLOAT },
|
|
61
|
+
{ name: "a_radius", size: 1, type: FLOAT },
|
|
62
|
+
{ name: "a_color", size: 4, type: UNSIGNED_BYTE, normalized: true },
|
|
63
|
+
{ name: "a_opacity", size: 1, type: FLOAT },
|
|
64
|
+
{ name: "a_id", size: 4, type: UNSIGNED_BYTE, normalized: true },
|
|
65
|
+
],
|
|
66
|
+
CONSTANT_ATTRIBUTES: [{ name: "a_barycentric", size: 3, type: FLOAT }],
|
|
67
|
+
CONSTANT_DATA: [
|
|
68
|
+
[1, 0, 0],
|
|
69
|
+
[0, 1, 0],
|
|
70
|
+
[0, 0, 1],
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
processVisibleItem(
|
|
76
|
+
edgeIndex: number,
|
|
77
|
+
startIndex: number,
|
|
78
|
+
sourceData: NodeDisplayData,
|
|
79
|
+
targetData: NodeDisplayData,
|
|
80
|
+
data: EdgeDisplayData & InternalEdgeAttributes,
|
|
81
|
+
) {
|
|
82
|
+
if (options.extremity === "source") {
|
|
83
|
+
[sourceData, targetData] = [targetData, sourceData];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const thickness = Math.min(data.size || 1, 0.5) * 8;
|
|
87
|
+
const radius = targetData.size || 1;
|
|
88
|
+
const x1 = sourceData.x;
|
|
89
|
+
const y1 = sourceData.y;
|
|
90
|
+
const x2 = targetData.x;
|
|
91
|
+
const y2 = targetData.y;
|
|
92
|
+
let color = data.color;
|
|
93
|
+
if (data.selected) color = "#f00";
|
|
94
|
+
if (data.highlight) color = "#F54A4A";
|
|
95
|
+
|
|
96
|
+
// Computing normals
|
|
97
|
+
const dx = x2 - x1;
|
|
98
|
+
const dy = y2 - y1;
|
|
99
|
+
|
|
100
|
+
let len = dx * dx + dy * dy;
|
|
101
|
+
let n1 = 0;
|
|
102
|
+
let n2 = 0;
|
|
103
|
+
|
|
104
|
+
if (len) {
|
|
105
|
+
len = 1 / Math.sqrt(len);
|
|
106
|
+
|
|
107
|
+
n1 = -dy * len * thickness;
|
|
108
|
+
n2 = dx * len * thickness;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const array = this.array;
|
|
112
|
+
|
|
113
|
+
array[startIndex++] = x2;
|
|
114
|
+
array[startIndex++] = y2;
|
|
115
|
+
array[startIndex++] = -n1;
|
|
116
|
+
array[startIndex++] = -n2;
|
|
117
|
+
array[startIndex++] = radius;
|
|
118
|
+
array[startIndex++] = floatColor(color);
|
|
119
|
+
array[startIndex++] = ["both", options.extremity].includes(
|
|
120
|
+
data.arrow ?? "",
|
|
121
|
+
)
|
|
122
|
+
? data.opacity ?? 1
|
|
123
|
+
: 0;
|
|
124
|
+
array[startIndex++] = edgeIndex;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
setUniforms(
|
|
128
|
+
params: RenderParams,
|
|
129
|
+
{ gl, uniformLocations }: ProgramInfo,
|
|
130
|
+
): void {
|
|
131
|
+
const {
|
|
132
|
+
u_matrix,
|
|
133
|
+
u_sizeRatio,
|
|
134
|
+
u_correctionRatio,
|
|
135
|
+
u_minEdgeThickness,
|
|
136
|
+
u_lengthToThicknessRatio,
|
|
137
|
+
u_widenessToThicknessRatio,
|
|
138
|
+
} = uniformLocations;
|
|
139
|
+
|
|
140
|
+
gl.uniformMatrix3fv(u_matrix, false, params.matrix);
|
|
141
|
+
gl.uniform1f(u_sizeRatio, params.sizeRatio);
|
|
142
|
+
gl.uniform1f(u_correctionRatio, params.correctionRatio);
|
|
143
|
+
gl.uniform1f(u_minEdgeThickness, params.minEdgeThickness);
|
|
144
|
+
gl.uniform1f(u_lengthToThicknessRatio, 2.5);
|
|
145
|
+
gl.uniform1f(u_widenessToThicknessRatio, 2);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/* istanbul ignore file */
|
|
2
|
+
|
|
3
|
+
// language=GLSL
|
|
4
|
+
const SHADER_SOURCE = /*glsl*/ `
|
|
5
|
+
attribute vec2 a_position;
|
|
6
|
+
attribute vec2 a_normal;
|
|
7
|
+
attribute float a_radius;
|
|
8
|
+
attribute vec3 a_barycentric;
|
|
9
|
+
attribute float a_opacity;
|
|
10
|
+
|
|
11
|
+
#ifdef PICKING_MODE
|
|
12
|
+
attribute vec4 a_id;
|
|
13
|
+
#else
|
|
14
|
+
attribute vec4 a_color;
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
uniform mat3 u_matrix;
|
|
18
|
+
uniform float u_sizeRatio;
|
|
19
|
+
uniform float u_correctionRatio;
|
|
20
|
+
uniform float u_minEdgeThickness;
|
|
21
|
+
uniform float u_lengthToThicknessRatio;
|
|
22
|
+
uniform float u_widenessToThicknessRatio;
|
|
23
|
+
|
|
24
|
+
varying vec4 v_color;
|
|
25
|
+
varying float v_opacity;
|
|
26
|
+
|
|
27
|
+
const float bias = 255.0 / 254.0;
|
|
28
|
+
|
|
29
|
+
void main() {
|
|
30
|
+
float minThickness = u_minEdgeThickness;
|
|
31
|
+
|
|
32
|
+
float normalLength = length(a_normal);
|
|
33
|
+
vec2 unitNormal = a_normal / normalLength;
|
|
34
|
+
|
|
35
|
+
// These first computations are taken from edge.vert.glsl and
|
|
36
|
+
// edge.clamped.vert.glsl. Please read it to get better comments on what's
|
|
37
|
+
// happening:
|
|
38
|
+
float pixelsThickness = max(normalLength / u_sizeRatio, minThickness);
|
|
39
|
+
float webGLThickness = pixelsThickness * u_correctionRatio;
|
|
40
|
+
float webGLNodeRadius = a_radius * 2.0 * u_correctionRatio / u_sizeRatio;
|
|
41
|
+
float webGLArrowHeadLength = webGLThickness * u_lengthToThicknessRatio * 2.0;
|
|
42
|
+
float webGLArrowHeadThickness = webGLThickness * u_widenessToThicknessRatio;
|
|
43
|
+
|
|
44
|
+
float da = a_barycentric.x;
|
|
45
|
+
float db = a_barycentric.y;
|
|
46
|
+
float dc = a_barycentric.z;
|
|
47
|
+
|
|
48
|
+
vec2 delta = vec2(
|
|
49
|
+
da * (webGLNodeRadius * unitNormal.y)
|
|
50
|
+
+ db * ((webGLNodeRadius + webGLArrowHeadLength) * unitNormal.y + webGLArrowHeadThickness * unitNormal.x)
|
|
51
|
+
+ dc * ((webGLNodeRadius + webGLArrowHeadLength) * unitNormal.y - webGLArrowHeadThickness * unitNormal.x),
|
|
52
|
+
|
|
53
|
+
da * (-webGLNodeRadius * unitNormal.x)
|
|
54
|
+
+ db * (-(webGLNodeRadius + webGLArrowHeadLength) * unitNormal.x + webGLArrowHeadThickness * unitNormal.y)
|
|
55
|
+
+ dc * (-(webGLNodeRadius + webGLArrowHeadLength) * unitNormal.x - webGLArrowHeadThickness * unitNormal.y)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
vec2 position = (u_matrix * vec3(a_position + delta, 1)).xy;
|
|
59
|
+
|
|
60
|
+
gl_Position = vec4(position, 0, 1);
|
|
61
|
+
|
|
62
|
+
#ifdef PICKING_MODE
|
|
63
|
+
// For picking mode, we use the ID as the color:
|
|
64
|
+
v_color = a_id;
|
|
65
|
+
#else
|
|
66
|
+
// For normal mode, we use the color:
|
|
67
|
+
v_color = a_color;
|
|
68
|
+
v_opacity = a_opacity;
|
|
69
|
+
#endif
|
|
70
|
+
|
|
71
|
+
v_color.a *= bias;
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
export default SHADER_SOURCE;
|