@react-fabric/graph 1.0.0-beta.63 → 1.0.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/cjs/context/context.js +16 -0
- package/dist/cjs/graph/index.js +58 -381
- package/dist/cjs/index.js +25 -21
- package/dist/cjs/utils/edge.js +76 -0
- package/dist/cjs/utils/node.js +93 -0
- package/dist/cjs/utils/sdfFolder.js +107 -0
- package/dist/cjs/viewer/Graph.js +174 -0
- package/dist/esm/context/context.js +15 -0
- package/dist/esm/graph/index.js +59 -382
- package/dist/esm/index.js +24 -20
- package/dist/esm/utils/edge.js +75 -0
- package/dist/esm/utils/node.js +92 -0
- package/dist/esm/utils/sdfFolder.js +107 -0
- package/dist/esm/viewer/Graph.js +174 -0
- package/dist/types/context/context.d.ts +35 -0
- package/dist/types/graph/index.d.ts +47 -24
- package/dist/types/index.d.ts +28 -2
- package/dist/types/types/index.d.ts +124 -175
- package/dist/types/utils/edge.d.ts +28 -0
- package/dist/types/utils/node.d.ts +28 -0
- package/dist/types/utils/sdfFolder.d.ts +75 -0
- package/dist/types/viewer/Graph.d.ts +31 -0
- package/package.json +19 -25
- package/src/context/context.tsx +43 -0
- package/src/graph/index.ts +76 -399
- package/src/index.ts +24 -26
- package/src/types/index.ts +139 -185
- package/src/utils/edge.ts +65 -0
- package/src/utils/node.ts +105 -0
- package/src/utils/sdfFolder.ts +141 -0
- package/src/viewer/Graph.tsx +159 -0
- package/css/styles.css +0 -56
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__auto__createBase64WorkerFactory.js +0 -14
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__auto__isNodeJS.js +0 -9
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__browser__createBase64WorkerFactory.js +0 -35
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__node__WorkerClass.js +0 -11
- package/dist/cjs/_virtual/_rollup-plugin-web-worker-loader__helper__node__createBase64WorkerFactory.js +0 -20
- package/dist/cjs/_virtual/elk-worker.js +0 -8
- package/dist/cjs/components/ContextMenu.js +0 -133
- package/dist/cjs/components/Provider.js +0 -103
- package/dist/cjs/components/Tools.js +0 -205
- package/dist/cjs/components/Viewer.js +0 -59
- package/dist/cjs/components/context.js +0 -34
- package/dist/cjs/constants/index.js +0 -16
- package/dist/cjs/hooks/sigmaDragSelect.js +0 -169
- package/dist/cjs/hooks/sigmaHilighter.js +0 -83
- package/dist/cjs/hooks/sigmaMouseActions.js +0 -145
- package/dist/cjs/hooks/useGraphology.js +0 -41
- package/dist/cjs/hooks/useSigma.js +0 -112
- package/dist/cjs/programs/arrow-head/frag.glsl.js +0 -8
- package/dist/cjs/programs/arrow-head/index.js +0 -142
- package/dist/cjs/programs/arrow-head/vert.glsl.js +0 -8
- package/dist/cjs/programs/edge-curve/drawLabel.js +0 -136
- package/dist/cjs/programs/edge-curve/frag.glsl.js +0 -8
- package/dist/cjs/programs/edge-curve/index.js +0 -157
- package/dist/cjs/programs/edge-curve/vert.glsl.js +0 -8
- package/dist/cjs/programs/edge-line/drawLabel.js +0 -70
- package/dist/cjs/programs/edge-line/frag.glsl.js +0 -8
- package/dist/cjs/programs/edge-line/index.js +0 -166
- package/dist/cjs/programs/edge-line/vert.glsl.js +0 -8
- package/dist/cjs/programs/node-badge/factory.js +0 -250
- package/dist/cjs/programs/node-badge/frag.glsl.js +0 -8
- package/dist/cjs/programs/node-badge/index.js +0 -33
- package/dist/cjs/programs/node-badge/texture.js +0 -455
- package/dist/cjs/programs/node-badge/vert.glsl.js +0 -19
- package/dist/cjs/programs/node-circle/base/drawHover.js +0 -71
- package/dist/cjs/programs/node-circle/base/drawLabel.js +0 -113
- package/dist/cjs/programs/node-circle/base/frag.glsl.js +0 -8
- package/dist/cjs/programs/node-circle/base/index.js +0 -136
- package/dist/cjs/programs/node-circle/base/vert.glsl.js +0 -8
- package/dist/cjs/programs/node-circle/index.js +0 -15
- package/dist/cjs/programs/node-image/factory.js +0 -224
- package/dist/cjs/programs/node-image/frag.glsl.js +0 -8
- package/dist/cjs/programs/node-image/index.js +0 -14
- package/dist/cjs/programs/node-image/texture.js +0 -472
- package/dist/cjs/programs/node-image/vert.glsl.js +0 -8
- package/dist/cjs/programs/node-rect/base/drawHover.js +0 -68
- package/dist/cjs/programs/node-rect/base/drawLabel.js +0 -107
- package/dist/cjs/programs/node-rect/base/frag.glsl.js +0 -8
- package/dist/cjs/programs/node-rect/base/index.js +0 -135
- package/dist/cjs/programs/node-rect/base/vert.glsl.js +0 -8
- package/dist/cjs/programs/node-rect/index.js +0 -15
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__auto__createBase64WorkerFactory.js +0 -14
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__auto__isNodeJS.js +0 -9
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__browser__createBase64WorkerFactory.js +0 -34
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__node__WorkerClass.js +0 -13
- package/dist/esm/_virtual/_rollup-plugin-web-worker-loader__helper__node__createBase64WorkerFactory.js +0 -20
- package/dist/esm/_virtual/elk-worker.js +0 -8
- package/dist/esm/components/ContextMenu.js +0 -133
- package/dist/esm/components/Provider.js +0 -103
- package/dist/esm/components/Tools.js +0 -205
- package/dist/esm/components/Viewer.js +0 -59
- package/dist/esm/components/context.js +0 -33
- package/dist/esm/constants/index.js +0 -16
- package/dist/esm/hooks/sigmaDragSelect.js +0 -169
- package/dist/esm/hooks/sigmaHilighter.js +0 -83
- package/dist/esm/hooks/sigmaMouseActions.js +0 -145
- package/dist/esm/hooks/useGraphology.js +0 -41
- package/dist/esm/hooks/useSigma.js +0 -112
- package/dist/esm/programs/arrow-head/frag.glsl.js +0 -8
- package/dist/esm/programs/arrow-head/index.js +0 -141
- package/dist/esm/programs/arrow-head/vert.glsl.js +0 -8
- package/dist/esm/programs/edge-curve/drawLabel.js +0 -136
- package/dist/esm/programs/edge-curve/frag.glsl.js +0 -8
- package/dist/esm/programs/edge-curve/index.js +0 -156
- package/dist/esm/programs/edge-curve/vert.glsl.js +0 -8
- package/dist/esm/programs/edge-line/drawLabel.js +0 -70
- package/dist/esm/programs/edge-line/frag.glsl.js +0 -8
- package/dist/esm/programs/edge-line/index.js +0 -166
- package/dist/esm/programs/edge-line/vert.glsl.js +0 -8
- package/dist/esm/programs/node-badge/factory.js +0 -250
- package/dist/esm/programs/node-badge/frag.glsl.js +0 -8
- package/dist/esm/programs/node-badge/index.js +0 -32
- package/dist/esm/programs/node-badge/texture.js +0 -445
- package/dist/esm/programs/node-badge/vert.glsl.js +0 -19
- package/dist/esm/programs/node-circle/base/drawHover.js +0 -71
- package/dist/esm/programs/node-circle/base/drawLabel.js +0 -113
- package/dist/esm/programs/node-circle/base/frag.glsl.js +0 -8
- package/dist/esm/programs/node-circle/base/index.js +0 -136
- package/dist/esm/programs/node-circle/base/vert.glsl.js +0 -8
- package/dist/esm/programs/node-circle/index.js +0 -15
- package/dist/esm/programs/node-image/factory.js +0 -224
- package/dist/esm/programs/node-image/frag.glsl.js +0 -8
- package/dist/esm/programs/node-image/index.js +0 -13
- package/dist/esm/programs/node-image/texture.js +0 -462
- package/dist/esm/programs/node-image/vert.glsl.js +0 -8
- package/dist/esm/programs/node-rect/base/drawHover.js +0 -68
- package/dist/esm/programs/node-rect/base/drawLabel.js +0 -107
- package/dist/esm/programs/node-rect/base/frag.glsl.js +0 -8
- package/dist/esm/programs/node-rect/base/index.js +0 -135
- package/dist/esm/programs/node-rect/base/vert.glsl.js +0 -8
- package/dist/esm/programs/node-rect/index.js +0 -15
- package/dist/types/components/ContextMenu.d.ts +0 -1
- package/dist/types/components/Provider.d.ts +0 -3
- package/dist/types/components/Tools.d.ts +0 -1
- package/dist/types/components/Viewer.d.ts +0 -2
- package/dist/types/components/context.d.ts +0 -17
- package/dist/types/constants/index.d.ts +0 -12
- package/dist/types/graph/layout.worker.d.ts +0 -1
- package/dist/types/hooks/sigmaDragSelect.d.ts +0 -8
- package/dist/types/hooks/sigmaHilighter.d.ts +0 -3
- package/dist/types/hooks/sigmaMouseActions.d.ts +0 -3
- package/dist/types/hooks/useGraphology.d.ts +0 -6
- package/dist/types/hooks/useSigma.d.ts +0 -8
- package/dist/types/i18n/index.d.ts +0 -0
- package/dist/types/programs/arrow-head/frag.glsl.d.ts +0 -2
- package/dist/types/programs/arrow-head/index.d.ts +0 -9
- package/dist/types/programs/arrow-head/vert.glsl.d.ts +0 -2
- package/dist/types/programs/edge-curve/drawLabel.d.ts +0 -6
- package/dist/types/programs/edge-curve/frag.glsl.d.ts +0 -2
- package/dist/types/programs/edge-curve/index.d.ts +0 -43
- package/dist/types/programs/edge-curve/vert.glsl.d.ts +0 -2
- package/dist/types/programs/edge-line/drawLabel.d.ts +0 -5
- package/dist/types/programs/edge-line/frag.glsl.d.ts +0 -2
- package/dist/types/programs/edge-line/index.d.ts +0 -11
- package/dist/types/programs/edge-line/vert.glsl.d.ts +0 -2
- package/dist/types/programs/node-badge/factory.d.ts +0 -27
- package/dist/types/programs/node-badge/frag.glsl.d.ts +0 -2
- package/dist/types/programs/node-badge/index.d.ts +0 -5
- package/dist/types/programs/node-badge/texture.d.ts +0 -102
- package/dist/types/programs/node-badge/vert.glsl.d.ts +0 -2
- package/dist/types/programs/node-circle/base/drawHover.d.ts +0 -8
- package/dist/types/programs/node-circle/base/drawLabel.d.ts +0 -8
- package/dist/types/programs/node-circle/base/frag.glsl.d.ts +0 -2
- package/dist/types/programs/node-circle/base/index.d.ts +0 -37
- package/dist/types/programs/node-circle/base/vert.glsl.d.ts +0 -2
- package/dist/types/programs/node-circle/index.d.ts +0 -11
- package/dist/types/programs/node-image/factory.d.ts +0 -25
- package/dist/types/programs/node-image/frag.glsl.d.ts +0 -2
- package/dist/types/programs/node-image/index.d.ts +0 -5
- package/dist/types/programs/node-image/texture.d.ts +0 -102
- package/dist/types/programs/node-image/vert.glsl.d.ts +0 -2
- package/dist/types/programs/node-rect/base/drawHover.d.ts +0 -8
- package/dist/types/programs/node-rect/base/drawLabel.d.ts +0 -8
- package/dist/types/programs/node-rect/base/frag.glsl.d.ts +0 -2
- package/dist/types/programs/node-rect/base/index.d.ts +0 -34
- package/dist/types/programs/node-rect/base/vert.glsl.d.ts +0 -2
- package/dist/types/programs/node-rect/index.d.ts +0 -11
- package/src/components/ContextMenu.tsx +0 -138
- package/src/components/Provider.tsx +0 -116
- package/src/components/Tools.tsx +0 -68
- package/src/components/Viewer.tsx +0 -75
- package/src/components/context.ts +0 -43
- package/src/constants/index.ts +0 -22
- package/src/graph/layout.worker.ts +0 -42
- package/src/hooks/sigmaDragSelect.ts +0 -219
- package/src/hooks/sigmaHilighter.ts +0 -107
- package/src/hooks/sigmaMouseActions.ts +0 -153
- package/src/hooks/useGraphology.ts +0 -31
- package/src/hooks/useSigma.ts +0 -118
- package/src/i18n/index.ts +0 -0
- package/src/programs/arrow-head/frag.glsl.ts +0 -18
- package/src/programs/arrow-head/index.ts +0 -156
- package/src/programs/arrow-head/vert.glsl.ts +0 -75
- package/src/programs/edge-curve/drawLabel.ts +0 -166
- package/src/programs/edge-curve/frag.glsl.ts +0 -86
- package/src/programs/edge-curve/index.ts +0 -156
- package/src/programs/edge-curve/vert.glsl.ts +0 -110
- package/src/programs/edge-line/drawLabel.ts +0 -113
- package/src/programs/edge-line/frag.glsl.ts +0 -34
- package/src/programs/edge-line/index.ts +0 -163
- package/src/programs/edge-line/vert.glsl.ts +0 -104
- package/src/programs/node-badge/factory.ts +0 -325
- package/src/programs/node-badge/frag.glsl.ts +0 -79
- package/src/programs/node-badge/index.ts +0 -35
- package/src/programs/node-badge/texture.ts +0 -425
- package/src/programs/node-badge/vert.glsl.ts +0 -99
- package/src/programs/node-circle/base/drawHover.ts +0 -80
- package/src/programs/node-circle/base/drawLabel.ts +0 -145
- package/src/programs/node-circle/base/frag.glsl.ts +0 -72
- package/src/programs/node-circle/base/index.ts +0 -100
- package/src/programs/node-circle/base/vert.glsl.ts +0 -83
- package/src/programs/node-circle/index.ts +0 -19
- package/src/programs/node-image/factory.ts +0 -299
- package/src/programs/node-image/frag.glsl.ts +0 -97
- package/src/programs/node-image/index.ts +0 -7
- package/src/programs/node-image/texture.ts +0 -435
- package/src/programs/node-image/vert.glsl.ts +0 -60
- package/src/programs/node-rect/base/drawHover.ts +0 -77
- package/src/programs/node-rect/base/drawLabel.ts +0 -149
- package/src/programs/node-rect/base/frag.glsl.ts +0 -67
- package/src/programs/node-rect/base/index.ts +0 -107
- package/src/programs/node-rect/base/vert.glsl.ts +0 -87
- package/src/programs/node-rect/index.ts +0 -19
|
@@ -1,435 +0,0 @@
|
|
|
1
|
-
import { isSvgPath } from "@react-fabric/utilities";
|
|
2
|
-
import { EventEmitter } from "events";
|
|
3
|
-
import { type Coordinates } from "sigma/types";
|
|
4
|
-
|
|
5
|
-
/* istanbul ignore file */
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Useful types:
|
|
9
|
-
* *************
|
|
10
|
-
*/
|
|
11
|
-
export interface ImageLoading {
|
|
12
|
-
status: "loading";
|
|
13
|
-
}
|
|
14
|
-
export interface ImageError {
|
|
15
|
-
status: "error";
|
|
16
|
-
}
|
|
17
|
-
export interface ImageReady {
|
|
18
|
-
status: "ready";
|
|
19
|
-
image: HTMLImageElement;
|
|
20
|
-
sourceX: number;
|
|
21
|
-
sourceY: number;
|
|
22
|
-
sourceSize: number;
|
|
23
|
-
destinationSize: number;
|
|
24
|
-
}
|
|
25
|
-
export type ImageType = ImageLoading | ImageError | ImageReady;
|
|
26
|
-
|
|
27
|
-
export type Atlas = Record<string, Coordinates & { size: number }>;
|
|
28
|
-
|
|
29
|
-
export interface TextureManagerOptions {
|
|
30
|
-
// - If mode "auto", will always display images with their given size.
|
|
31
|
-
// - If mode "force", will always scale images to the given value.
|
|
32
|
-
// - If mode "max", will downscale images larger than the given value.
|
|
33
|
-
size:
|
|
34
|
-
| { mode: "auto" }
|
|
35
|
-
| { mode: "max"; value: number }
|
|
36
|
-
| { mode: "force"; value: number };
|
|
37
|
-
// Tries to mimic the related CSS property.
|
|
38
|
-
objectFit: "contain" | "cover" | "fill";
|
|
39
|
-
// If true, the image is centered on its alpha barycenter.
|
|
40
|
-
correctCentering: boolean;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export const DEFAULT_TEXTURE_MANAGER_OPTIONS: TextureManagerOptions = {
|
|
44
|
-
size: { mode: "max", value: 512 },
|
|
45
|
-
objectFit: "cover",
|
|
46
|
-
correctCentering: false,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
export const DEBOUNCE_TIMEOUT = 100;
|
|
50
|
-
|
|
51
|
-
// This margin helps avoiding images collisions in the texture:
|
|
52
|
-
export const MARGIN_IN_TEXTURE = 1;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Helpers:
|
|
56
|
-
* ********
|
|
57
|
-
*/
|
|
58
|
-
/**
|
|
59
|
-
* This helper loads an image at a given URL, and returns an HTMLImageElement
|
|
60
|
-
* with it displayed once it's properly loaded, within a promise.
|
|
61
|
-
*/
|
|
62
|
-
export async function loadRasterImage(
|
|
63
|
-
imageSource: string,
|
|
64
|
-
): Promise<HTMLImageElement> {
|
|
65
|
-
return await new Promise((resolve, reject) => {
|
|
66
|
-
const image = new Image();
|
|
67
|
-
|
|
68
|
-
image.addEventListener(
|
|
69
|
-
"load",
|
|
70
|
-
() => {
|
|
71
|
-
resolve(image);
|
|
72
|
-
},
|
|
73
|
-
{ once: true },
|
|
74
|
-
);
|
|
75
|
-
image.addEventListener(
|
|
76
|
-
"error",
|
|
77
|
-
(e) => {
|
|
78
|
-
reject(e.error);
|
|
79
|
-
},
|
|
80
|
-
{ once: true },
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// Load image:
|
|
84
|
-
image.setAttribute("crossOrigin", "");
|
|
85
|
-
image.src = imageSource;
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export const makeSvg = (path: string = "") => {
|
|
90
|
-
return `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="-1 -1 26 26" width="128px" height="128px"><path fill="#000" d="${path}"></path></svg>`;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* This helper loads an SVG image at a given URL, adjusts its size to a given
|
|
95
|
-
* size, and returns an HTMLImageElement with it displayed once it's properly
|
|
96
|
-
* loaded, within a promise.
|
|
97
|
-
*/
|
|
98
|
-
export async function loadSVGImage(
|
|
99
|
-
imageSource: string,
|
|
100
|
-
{ size }: { size?: number } = {},
|
|
101
|
-
): Promise<HTMLImageElement> {
|
|
102
|
-
const svg = new DOMParser().parseFromString(
|
|
103
|
-
makeSvg(imageSource),
|
|
104
|
-
"image/svg+xml",
|
|
105
|
-
);
|
|
106
|
-
const root = svg.documentElement;
|
|
107
|
-
|
|
108
|
-
const originalWidth = root.getAttribute("width");
|
|
109
|
-
const originalHeight = root.getAttribute("height");
|
|
110
|
-
|
|
111
|
-
if (!originalWidth || !originalHeight)
|
|
112
|
-
throw new Error(
|
|
113
|
-
"loadSVGImage: cannot use `size` if target SVG has no definite dimensions.",
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
if (typeof size === "number") {
|
|
117
|
-
root.setAttribute("width", "" + size);
|
|
118
|
-
root.setAttribute("height", "" + size);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// NOTE: since Google Material last changes to their icon viewBox, this
|
|
122
|
-
// code is no longer necessary (hopefully it does not break something else...)
|
|
123
|
-
// root.setAttribute("viewBox", `0 0 ${originalWidth} ${originalHeight}`);
|
|
124
|
-
|
|
125
|
-
const correctedSvgString = new XMLSerializer().serializeToString(svg);
|
|
126
|
-
|
|
127
|
-
const blob = new Blob([correctedSvgString], { type: "image/svg+xml" });
|
|
128
|
-
const url = URL.createObjectURL(blob);
|
|
129
|
-
|
|
130
|
-
const res = loadRasterImage(url);
|
|
131
|
-
void res.finally(() => URL.revokeObjectURL(url));
|
|
132
|
-
return await res;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* This helper loads an image using the proper function.
|
|
137
|
-
*/
|
|
138
|
-
export async function loadImage(
|
|
139
|
-
imageSource: string,
|
|
140
|
-
{ size }: { size?: number } = {},
|
|
141
|
-
): Promise<HTMLImageElement> {
|
|
142
|
-
const isSVG = isSvgPath(imageSource);
|
|
143
|
-
|
|
144
|
-
let image: HTMLImageElement;
|
|
145
|
-
if (isSVG) {
|
|
146
|
-
image = await loadSVGImage(imageSource, { size: 128 });
|
|
147
|
-
} else {
|
|
148
|
-
image = await loadRasterImage(imageSource);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return image;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* This helper computes exact coordinates to draw an image onto a texture.
|
|
156
|
-
*/
|
|
157
|
-
export function refineImage(
|
|
158
|
-
image: HTMLImageElement,
|
|
159
|
-
corrector: PictogramCenteringCorrector,
|
|
160
|
-
{ objectFit, size, correctCentering }: TextureManagerOptions,
|
|
161
|
-
): Omit<ImageReady, "status" | "image"> {
|
|
162
|
-
const sourceSize =
|
|
163
|
-
objectFit === "contain"
|
|
164
|
-
? Math.max(image.width, image.height)
|
|
165
|
-
: Math.min(image.width, image.height);
|
|
166
|
-
const destinationSize =
|
|
167
|
-
size.mode === "auto"
|
|
168
|
-
? sourceSize
|
|
169
|
-
: size.mode === "force"
|
|
170
|
-
? size.value
|
|
171
|
-
: Math.min(size.value, sourceSize);
|
|
172
|
-
let sourceX = (image.width - sourceSize) / 2;
|
|
173
|
-
let sourceY = (image.height - sourceSize) / 2;
|
|
174
|
-
|
|
175
|
-
if (correctCentering) {
|
|
176
|
-
const correction = corrector.getCorrectionOffset(image, sourceSize);
|
|
177
|
-
sourceX = correction.x;
|
|
178
|
-
sourceY = correction.y;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return {
|
|
182
|
-
sourceX,
|
|
183
|
-
sourceY,
|
|
184
|
-
sourceSize,
|
|
185
|
-
destinationSize,
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* This helper takes a collection of image states and a context, draw all the
|
|
191
|
-
* images in the context, and returns an atlas to get where each image is drawn
|
|
192
|
-
* on the texture.
|
|
193
|
-
*/
|
|
194
|
-
export function drawTexture(
|
|
195
|
-
ctx: CanvasRenderingContext2D,
|
|
196
|
-
images: Record<string, ImageType>,
|
|
197
|
-
): Atlas {
|
|
198
|
-
const MAX_CANVAS_WIDTH = 3072;
|
|
199
|
-
const TARGET_FILL_PERCENTAGE = 0.6;
|
|
200
|
-
|
|
201
|
-
// 1. Sort images by height, decreasingly:
|
|
202
|
-
const imagesArray: Array<{
|
|
203
|
-
key: string;
|
|
204
|
-
image: HTMLImageElement;
|
|
205
|
-
sourceX: number;
|
|
206
|
-
sourceY: number;
|
|
207
|
-
sourceSize: number;
|
|
208
|
-
destinationSize: number;
|
|
209
|
-
}> = [];
|
|
210
|
-
let totalArea = 0;
|
|
211
|
-
let maxItemWidth = 0;
|
|
212
|
-
for (const key in images) {
|
|
213
|
-
const imageState = images[key];
|
|
214
|
-
if (imageState.status !== "ready") continue;
|
|
215
|
-
|
|
216
|
-
maxItemWidth = Math.max(maxItemWidth, imageState.destinationSize);
|
|
217
|
-
totalArea += imageState.destinationSize ** 2;
|
|
218
|
-
imagesArray.push({
|
|
219
|
-
key,
|
|
220
|
-
...imageState,
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
imagesArray.sort((a, b) => (a.destinationSize > b.destinationSize ? -1 : 1));
|
|
224
|
-
|
|
225
|
-
// 2. Predict canvas width:
|
|
226
|
-
const predictedTotalArea = totalArea / TARGET_FILL_PERCENTAGE;
|
|
227
|
-
const predictedWidth = Math.min(
|
|
228
|
-
Math.max(Math.sqrt(predictedTotalArea), maxItemWidth),
|
|
229
|
-
MAX_CANVAS_WIDTH,
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
// 3. Refine images coordinates:
|
|
233
|
-
const refinedImagesArray: Array<
|
|
234
|
-
(typeof imagesArray)[number] & {
|
|
235
|
-
destinationX: number;
|
|
236
|
-
destinationY: number;
|
|
237
|
-
}
|
|
238
|
-
> = [];
|
|
239
|
-
let x = 0;
|
|
240
|
-
let y = 0;
|
|
241
|
-
let currentRowHeight = 0;
|
|
242
|
-
let maxRowWidth = 0;
|
|
243
|
-
const atlas: Atlas = {};
|
|
244
|
-
for (let i = 0, l = imagesArray.length; i < l; i++) {
|
|
245
|
-
const { key, image, sourceSize, sourceX, sourceY, destinationSize } =
|
|
246
|
-
imagesArray[i];
|
|
247
|
-
const destinationSizeWithMargin = destinationSize + MARGIN_IN_TEXTURE;
|
|
248
|
-
if (x + destinationSizeWithMargin > predictedWidth) {
|
|
249
|
-
maxRowWidth = Math.max(maxRowWidth, x);
|
|
250
|
-
x = 0;
|
|
251
|
-
y += currentRowHeight;
|
|
252
|
-
currentRowHeight = destinationSizeWithMargin;
|
|
253
|
-
}
|
|
254
|
-
refinedImagesArray.push({
|
|
255
|
-
key,
|
|
256
|
-
image,
|
|
257
|
-
sourceX,
|
|
258
|
-
sourceY,
|
|
259
|
-
sourceSize,
|
|
260
|
-
destinationX: x,
|
|
261
|
-
destinationY: y,
|
|
262
|
-
destinationSize,
|
|
263
|
-
});
|
|
264
|
-
atlas[key] = {
|
|
265
|
-
x,
|
|
266
|
-
y,
|
|
267
|
-
size: destinationSize,
|
|
268
|
-
};
|
|
269
|
-
x += destinationSizeWithMargin;
|
|
270
|
-
currentRowHeight = Math.max(currentRowHeight, destinationSizeWithMargin);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// 4. Crop texture to final best dimensions:
|
|
274
|
-
maxRowWidth = Math.max(maxRowWidth, x);
|
|
275
|
-
const canvas = ctx.canvas;
|
|
276
|
-
canvas.width = maxRowWidth;
|
|
277
|
-
canvas.height = y + currentRowHeight;
|
|
278
|
-
|
|
279
|
-
// 5. Fill texture:
|
|
280
|
-
for (let i = 0, l = refinedImagesArray.length; i < l; i++) {
|
|
281
|
-
const {
|
|
282
|
-
image,
|
|
283
|
-
sourceSize,
|
|
284
|
-
sourceX,
|
|
285
|
-
sourceY,
|
|
286
|
-
destinationSize,
|
|
287
|
-
destinationX,
|
|
288
|
-
destinationY,
|
|
289
|
-
} = refinedImagesArray[i];
|
|
290
|
-
|
|
291
|
-
ctx.drawImage(
|
|
292
|
-
image,
|
|
293
|
-
sourceX,
|
|
294
|
-
sourceY,
|
|
295
|
-
sourceSize,
|
|
296
|
-
sourceSize,
|
|
297
|
-
destinationX,
|
|
298
|
-
destinationY,
|
|
299
|
-
destinationSize,
|
|
300
|
-
destinationSize,
|
|
301
|
-
);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return atlas;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* This class helps to "correct" the centering of an SVG pictogram by finding
|
|
309
|
-
* the "true" visually correct center through the barycenter of the pictogram's
|
|
310
|
-
* alpha layer in x and y dimension.
|
|
311
|
-
*/
|
|
312
|
-
export class PictogramCenteringCorrector {
|
|
313
|
-
canvas: HTMLCanvasElement;
|
|
314
|
-
context: CanvasRenderingContext2D;
|
|
315
|
-
|
|
316
|
-
constructor() {
|
|
317
|
-
this.canvas = document.createElement("canvas");
|
|
318
|
-
this.context = this.canvas.getContext("2d", {
|
|
319
|
-
willReadFrequently: true,
|
|
320
|
-
}) as AnyObject;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
getCorrectionOffset(image: HTMLImageElement, size: number): Coordinates {
|
|
324
|
-
this.canvas.width = size;
|
|
325
|
-
this.canvas.height = size;
|
|
326
|
-
this.context.clearRect(0, 0, size, size);
|
|
327
|
-
this.context.drawImage(image, 0, 0, size, size);
|
|
328
|
-
const data = this.context.getImageData(0, 0, size, size).data;
|
|
329
|
-
|
|
330
|
-
const alpha = new Uint8ClampedArray(data.length / 4);
|
|
331
|
-
|
|
332
|
-
for (let i = 0; i < data.length; i++) {
|
|
333
|
-
alpha[i] = data[i * 4 + 3];
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
let sumX = 0;
|
|
337
|
-
let sumY = 0;
|
|
338
|
-
let total = 0;
|
|
339
|
-
|
|
340
|
-
for (let y = 0; y < size; y++) {
|
|
341
|
-
for (let x = 0; x < size; x++) {
|
|
342
|
-
const a = alpha[y * size + x];
|
|
343
|
-
|
|
344
|
-
total += a;
|
|
345
|
-
sumX += a * x;
|
|
346
|
-
sumY += a * y;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const barycenterX = sumX / total;
|
|
351
|
-
const barycenterY = sumY / total;
|
|
352
|
-
|
|
353
|
-
return {
|
|
354
|
-
x: barycenterX - size / 2,
|
|
355
|
-
y: barycenterY - size / 2,
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
export class TextureManager extends EventEmitter {
|
|
361
|
-
static NEW_TEXTURE_EVENT = "newTexture";
|
|
362
|
-
|
|
363
|
-
private readonly options: TextureManagerOptions;
|
|
364
|
-
private readonly canvas: HTMLCanvasElement = document.createElement("canvas");
|
|
365
|
-
private readonly ctx = this.canvas.getContext("2d", {
|
|
366
|
-
willReadFrequently: true,
|
|
367
|
-
}) as AnyObject;
|
|
368
|
-
|
|
369
|
-
private frameId?: number;
|
|
370
|
-
private readonly corrector = new PictogramCenteringCorrector();
|
|
371
|
-
|
|
372
|
-
private imageStates: Record<string, ImageType> = {};
|
|
373
|
-
private texture: ImageData = this.ctx.getImageData(0, 0, 1, 1);
|
|
374
|
-
private atlas: Atlas = {};
|
|
375
|
-
|
|
376
|
-
constructor(options: Partial<TextureManagerOptions> = {}) {
|
|
377
|
-
super();
|
|
378
|
-
this.options = { ...DEFAULT_TEXTURE_MANAGER_OPTIONS, ...options };
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
private scheduleGenerateTexture() {
|
|
382
|
-
if (typeof this.frameId === "number") return;
|
|
383
|
-
|
|
384
|
-
this.frameId = window.setTimeout(() => {
|
|
385
|
-
this.generateTexture();
|
|
386
|
-
this.frameId = undefined;
|
|
387
|
-
}, DEBOUNCE_TIMEOUT);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
private generateTexture() {
|
|
391
|
-
this.atlas = drawTexture(this.ctx, this.imageStates);
|
|
392
|
-
this.texture = this.ctx.getImageData(
|
|
393
|
-
0,
|
|
394
|
-
0,
|
|
395
|
-
this.canvas.width,
|
|
396
|
-
this.canvas.height,
|
|
397
|
-
);
|
|
398
|
-
this.emit(TextureManager.NEW_TEXTURE_EVENT, {
|
|
399
|
-
atlas: this.atlas,
|
|
400
|
-
texture: this.texture,
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// PUBLIC API:
|
|
405
|
-
async registerImage(source: string) {
|
|
406
|
-
if (this.imageStates[source]) return;
|
|
407
|
-
|
|
408
|
-
this.imageStates[source] = { status: "loading" };
|
|
409
|
-
|
|
410
|
-
try {
|
|
411
|
-
const { size } = this.options;
|
|
412
|
-
const image = await loadImage(source, {
|
|
413
|
-
size: size.mode === "force" ? size.value : undefined,
|
|
414
|
-
});
|
|
415
|
-
this.imageStates[source] = {
|
|
416
|
-
status: "ready",
|
|
417
|
-
image,
|
|
418
|
-
...refineImage(image, this.corrector, this.options),
|
|
419
|
-
};
|
|
420
|
-
this.scheduleGenerateTexture();
|
|
421
|
-
} catch (e) {
|
|
422
|
-
this.imageStates[source] = {
|
|
423
|
-
status: "error",
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
getAtlas(): Atlas {
|
|
429
|
-
return this.atlas;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
getTexture(): ImageData {
|
|
433
|
-
return this.texture;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/* istanbul ignore file */
|
|
2
|
-
|
|
3
|
-
// language=GLSL
|
|
4
|
-
const VERTEX_SHADER_SOURCE = /* glsl */ `
|
|
5
|
-
attribute vec4 a_id;
|
|
6
|
-
attribute vec4 a_fill;
|
|
7
|
-
attribute vec4 a_color;
|
|
8
|
-
attribute vec2 a_position;
|
|
9
|
-
attribute float a_size;
|
|
10
|
-
attribute float a_angle;
|
|
11
|
-
attribute float a_colorMode;
|
|
12
|
-
attribute float a_opacity;
|
|
13
|
-
attribute vec4 a_texture;
|
|
14
|
-
|
|
15
|
-
uniform mat3 u_matrix;
|
|
16
|
-
uniform float u_sizeRatio;
|
|
17
|
-
uniform float u_correctionRatio;
|
|
18
|
-
|
|
19
|
-
varying vec4 v_fill;
|
|
20
|
-
varying vec4 v_color;
|
|
21
|
-
varying vec2 v_diffVector;
|
|
22
|
-
varying float v_radius;
|
|
23
|
-
varying float v_opacity;
|
|
24
|
-
varying vec4 v_texture;
|
|
25
|
-
varying float v_colorMode;
|
|
26
|
-
|
|
27
|
-
const float bias = 255.0 / 254.0;
|
|
28
|
-
const float marginRatio = 1.05;
|
|
29
|
-
|
|
30
|
-
void main() {
|
|
31
|
-
float size = a_size * u_correctionRatio / u_sizeRatio * 4.0;
|
|
32
|
-
vec2 diffVector = size * vec2(cos(a_angle), sin(a_angle));
|
|
33
|
-
vec2 position = a_position + diffVector * marginRatio;
|
|
34
|
-
gl_Position = vec4(
|
|
35
|
-
(u_matrix * vec3(position, 1)).xy,
|
|
36
|
-
0,
|
|
37
|
-
1
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
v_diffVector = diffVector;
|
|
41
|
-
v_radius = size / 2.0 / marginRatio;
|
|
42
|
-
|
|
43
|
-
#ifdef PICKING_MODE
|
|
44
|
-
// For picking mode, we use the ID as the color:
|
|
45
|
-
v_color = a_id;
|
|
46
|
-
#else
|
|
47
|
-
// For normal mode, we use the color:
|
|
48
|
-
v_fill = vec4(0.0, 0.0, 0.0, 0.0);
|
|
49
|
-
v_color = vec4(a_color.rgb, a_opacity * bias);
|
|
50
|
-
v_opacity = a_opacity;
|
|
51
|
-
v_colorMode = a_colorMode;
|
|
52
|
-
// Pass the texture coordinates:
|
|
53
|
-
v_texture = a_texture;
|
|
54
|
-
#endif
|
|
55
|
-
|
|
56
|
-
v_color.a *= bias;
|
|
57
|
-
}
|
|
58
|
-
`;
|
|
59
|
-
|
|
60
|
-
export default VERTEX_SHADER_SOURCE;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { type Settings } from "sigma/settings";
|
|
2
|
-
import { type EdgeAttributes, type NodeAttributes } from "../../../types";
|
|
3
|
-
import { drawNodeLabel } from "./drawLabel";
|
|
4
|
-
|
|
5
|
-
/* istanbul ignore file */
|
|
6
|
-
|
|
7
|
-
export function drawNodeHover(
|
|
8
|
-
context: CanvasRenderingContext2D,
|
|
9
|
-
data: NodeAttributes & {
|
|
10
|
-
opacity: number;
|
|
11
|
-
x: number;
|
|
12
|
-
y: number;
|
|
13
|
-
size: number;
|
|
14
|
-
},
|
|
15
|
-
settings: Settings<NodeAttributes, EdgeAttributes>,
|
|
16
|
-
): void {
|
|
17
|
-
const nodeSize = data.size;
|
|
18
|
-
const size = settings.labelSize;
|
|
19
|
-
const font = settings.labelFont;
|
|
20
|
-
const weight = settings.labelWeight;
|
|
21
|
-
// use node color or default node color
|
|
22
|
-
const bg = settings.defaultNodeColor || "#fff";
|
|
23
|
-
// use label color or default label color
|
|
24
|
-
const color = data.labelColor ?? settings.labelColor.color ?? "#000";
|
|
25
|
-
|
|
26
|
-
context.font = `${weight} ${size}px ${font}`;
|
|
27
|
-
|
|
28
|
-
// Then we draw the label background
|
|
29
|
-
context.fillStyle = bg;
|
|
30
|
-
context.strokeStyle = color;
|
|
31
|
-
context.lineWidth = 0.25;
|
|
32
|
-
|
|
33
|
-
const PADDING = data.selected ? 4 : 2;
|
|
34
|
-
|
|
35
|
-
// if (typeof data.label === "string") {
|
|
36
|
-
// const textWidth = context.measureText(data.label).width;
|
|
37
|
-
// const boxWidth = Math.round(textWidth + 5);
|
|
38
|
-
// const boxHeight = Math.round(size + 2 * PADDING);
|
|
39
|
-
// const radius = Math.max(nodeSize, size / 2) + PADDING;
|
|
40
|
-
|
|
41
|
-
// context.beginPath();
|
|
42
|
-
// context.moveTo(data.x + radius, data.y + boxHeight / 2);
|
|
43
|
-
// context.lineTo(data.x + radius + boxWidth, data.y + boxHeight / 2);
|
|
44
|
-
// context.lineTo(data.x + radius + boxWidth, data.y - boxHeight / 2);
|
|
45
|
-
// context.lineTo(data.x + radius, data.y - boxHeight / 2);
|
|
46
|
-
// context.lineTo(data.x + radius, data.y - radius);
|
|
47
|
-
// context.lineTo(data.x - radius, data.y - radius);
|
|
48
|
-
// context.lineTo(data.x - radius, data.y + radius);
|
|
49
|
-
// context.lineTo(data.x + radius, data.y + radius);
|
|
50
|
-
// context.lineTo(data.x + radius, data.y + boxHeight / 2);
|
|
51
|
-
// context.closePath();
|
|
52
|
-
// context.fill();
|
|
53
|
-
|
|
54
|
-
// if (data.selected) {
|
|
55
|
-
// context.strokeStyle = "#F00";
|
|
56
|
-
// context.lineWidth = 2;
|
|
57
|
-
// }
|
|
58
|
-
// context.stroke();
|
|
59
|
-
// } else {
|
|
60
|
-
const radius = nodeSize + PADDING;
|
|
61
|
-
// context.fillRect(data.x - radius, data.y - radius, radius * 2, radius * 2);
|
|
62
|
-
context.lineWidth = 1;
|
|
63
|
-
context.strokeStyle = "#F00";
|
|
64
|
-
if (data.selected) {
|
|
65
|
-
context.lineWidth = 3;
|
|
66
|
-
}
|
|
67
|
-
context.strokeRect(data.x - radius, data.y - radius, radius * 2, radius * 2);
|
|
68
|
-
// }
|
|
69
|
-
|
|
70
|
-
context.shadowOffsetX = 0;
|
|
71
|
-
context.shadowOffsetY = 0;
|
|
72
|
-
context.shadowBlur = 0;
|
|
73
|
-
context.lineWidth = 0;
|
|
74
|
-
context.strokeStyle = "";
|
|
75
|
-
|
|
76
|
-
drawNodeLabel(context, data, settings);
|
|
77
|
-
}
|