@fusion.dev/helix-graph 0.214.0 → 0.215.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ The elements themselves are on the
13
13
 
14
14
  ```js
15
15
  import { connectGraph } from '@fusion.dev/helix-graph'
16
- import { sigmaDriver } from '@fusion.dev/helix-graph/sigma'
16
+ import { sigmaDriver, sigmaOptions } from '@fusion.dev/helix-graph/sigma'
17
17
  import Graph from 'graphology'
18
18
  import forceAtlas2 from 'graphology-layout-forceatlas2'
19
19
  import FA2Layout from 'graphology-layout-forceatlas2/worker'
@@ -25,7 +25,7 @@ frame.links = links // [{ source, target, label }]
25
25
 
26
26
  // The box the drawing goes in: a <div> inside the frame, sized by it.
27
27
  const box = frame.querySelector('div')
28
- const sigma = new Sigma(new Graph(), box)
28
+ const sigma = new Sigma(new Graph(), box, sigmaOptions())
29
29
  const connection = connectGraph(
30
30
  frame,
31
31
  sigmaDriver(sigma, {
@@ -408,7 +408,7 @@ connectGraph(frame, isometricDriver(frame.querySelector('div')))
408
408
  | Import | What |
409
409
  |---|---|
410
410
  | `@fusion.dev/helix-graph` | `communitiesOf`, `connectGraph`, `diffGraph`, `fitToStencil`, `graphColorsFrom`, `groupByCommunity`, `linkKey`, `seedPositions`, and the types `ConnectGraphOptions`, `DrawnLink`, `DrawnNode`, `GraphChanges`, `GraphColors`, `GraphConnection`, `GraphDriver`, `GraphGroup`, `GraphLooks`, `GraphPoint`, `GraphReach`, `GraphStencil`, `GraphTone`, `GroupByCommunityOptions`, `LinkLook`, `NodeLook`, `SeedLink`, `SeedNode`, `ShapeField` and `StencilFrame` |
411
- | `@fusion.dev/helix-graph/sigma` | `sigmaDriver(sigma, options)`, and the types `SigmaDriverOptions`, `SigmaGraph`, `SigmaLayout` and `SigmaRenderer` |
411
+ | `@fusion.dev/helix-graph/sigma` | `sigmaDriver(sigma, options)`, `sigmaOptions(overrides)`, the options to make the renderer with, and the types `HelixEdgeData`, `SigmaDriverOptions`, `SigmaGraph`, `SigmaLayout`, `SigmaOptionsOverrides` and `SigmaRenderer` |
412
412
  | `@fusion.dev/helix-graph/cosmos` | `cosmosDriver(graph, box, options)`, and the types `CosmosDriverOptions` and `CosmosGraph` |
413
413
  | `@fusion.dev/helix-graph/three` | `threeDriver(box, options)`, and the type `ThreeDriverOptions` |
414
414
  | `@fusion.dev/helix-graph/isometric` | `isometricDriver(box, options)`, `ISOMETRIC`, the camera it starts from, and the types `Camera`, `IsometricDriver` and `IsometricDriverOptions` |
@@ -420,8 +420,15 @@ connectGraph(frame, isometricDriver(frame.querySelector('div')))
420
420
  driver types its renderer by the calls it makes on it, so a page brings
421
421
  whichever version it has, and a spec holds those shapes to the real classes,
422
422
  so a renamed method fails a typecheck here before it reaches a page. `@fusion.dev/helix-graph/sigma` imports
423
- Sigma's rendering module for the program that draws the notes, which is why
424
- Sigma 3 is a peer dependency.
423
+ Sigma's rendering module for the line and arrowhead the links are drawn with,
424
+ which is why Sigma 4 is a peer dependency.
425
+
426
+ **Make the renderer with `sigmaOptions()`.** Sigma 4 takes the programs a
427
+ note and a link are drawn with, and the reducers that draw them as the frame
428
+ says, only when it is made, so `sigmaDriver` refuses a renderer made without
429
+ them. `sigmaOptions({ settings })` sets Sigma's own settings over Helix's.
430
+ Sigma draws no names: the driver names notes over the drawing, as it names
431
+ groups.
425
432
 
426
433
  | `connectGraph` option | Default | What else it takes |
427
434
  |---|---|---|
@@ -65,14 +65,16 @@ export declare const nameStart: (at: {
65
65
  /** A note to name over the drawing: its name, and whether it is the one the reader is on. */
66
66
  export interface Named {
67
67
  id: string;
68
+ /** Whether the name is drawn even where it covers another. The strong ones by default. */
69
+ must?: boolean | undefined;
68
70
  name: string;
69
71
  strong: boolean;
70
72
  }
71
73
  /**
72
74
  * **Names on a canvas of their own**, for a renderer that draws none: each
73
75
  * note given, beside it, ringed in the ground's color so it reads over the
74
- * links. The strong ones always, and the rest where there is room, in the
75
- * order given.
76
+ * links. The ones that must be named always, and the rest where there is
77
+ * room, in the order given.
76
78
  */
77
79
  export declare const namesOver: (container: HTMLElement, onScreen: OnScreen) => {
78
80
  /** The boxes the names last drawn take. */
@@ -315,7 +315,7 @@ export const namesOver = (container, onScreen) => {
315
315
  taken = chromeOver(container);
316
316
  const rightToLeft = isRtl(container);
317
317
  context.textAlign = 'left';
318
- for (const { id, name, strong } of named) {
318
+ for (const { id, must, name, strong } of named) {
319
319
  const at = onScreen(id);
320
320
  if (!at || looks.node(id).hidden) {
321
321
  continue;
@@ -331,7 +331,7 @@ export const namesOver = (container, onScreen) => {
331
331
  });
332
332
  const x = nameStart(at, width, boxAt, taken, container.clientWidth, rightToLeft);
333
333
  const box = boxAt(x);
334
- if (!clearOf(box, taken) && !strong) {
334
+ if (!clearOf(box, taken) && !(must ?? strong)) {
335
335
  continue;
336
336
  }
337
337
  taken.push(box);
@@ -1,87 +1,24 @@
1
- import { EdgeProgram, type EdgeProgramType } from 'sigma/rendering';
2
- import type { EdgeDisplayData, NodeDisplayData, RenderParams } from 'sigma/types';
3
- /** What the edge program reads off a link, beyond what Sigma gives every link. */
1
+ import type { EdgePrimitives } from 'sigma/primitives';
2
+ /** What the edge layer reads off a link, beyond what Sigma gives every link. */
4
3
  export interface HelixEdgeData {
5
4
  /** How strongly the link glows, from 0 to 1: a link on the selected note's path. */
6
5
  glow?: number;
7
6
  /** Whether the link is drawn heavy, with an arrowhead, as a link the selection lights is. */
8
7
  strong?: boolean;
9
8
  }
10
- declare const UNIFORMS: readonly ['u_matrix', 'u_zoomRatio', 'u_sizeRatio', 'u_correctionRatio', 'u_pixelRatio', 'u_feather', 'u_minEdgeThickness'];
11
9
  /**
12
- * Draws a link as a line that reads in its direction, faint where it leaves
13
- * a note and full where it arrives, with a glow where the selection lights
14
- * it: one quad a link, as Sigma's own rectangle is, widened where it glows.
10
+ * How far past the line's own width a glowing link is drawn, as a multiple of
11
+ * that width, which is the room its glow has. **Sigma draws nothing outside a
12
+ * link's width**, so a glowing link is given the width of its glow and the
13
+ * layer draws the line in its middle.
15
14
  */
16
- export declare class HelixEdgeLineProgram extends EdgeProgram<(typeof UNIFORMS)[number]> {
17
- getDefinition(): {
18
- ATTRIBUTES: ({
19
- name: string;
20
- size: number;
21
- type: 5126;
22
- normalized?: never;
23
- } | {
24
- name: string;
25
- normalized: boolean;
26
- size: number;
27
- type: 5121;
28
- })[];
29
- CONSTANT_ATTRIBUTES: {
30
- name: string;
31
- size: number;
32
- type: 5126;
33
- }[];
34
- CONSTANT_DATA: number[][];
35
- FRAGMENT_SHADER_SOURCE: string;
36
- METHOD: 4;
37
- UNIFORMS: readonly ["u_matrix", "u_zoomRatio", "u_sizeRatio", "u_correctionRatio", "u_pixelRatio", "u_feather", "u_minEdgeThickness"];
38
- VERTEX_SHADER_SOURCE: string;
39
- VERTICES: number;
40
- };
41
- processVisibleItem(edgeIndex: number, startIndex: number, sourceData: NodeDisplayData, targetData: NodeDisplayData, data: EdgeDisplayData & HelixEdgeData): void;
42
- setUniforms(params: RenderParams, { gl, uniformLocations, }: {
43
- gl: WebGLRenderingContext;
44
- uniformLocations: Record<string, WebGLUniformLocation>;
45
- }): void;
46
- }
47
- declare const HEAD_UNIFORMS: readonly ['u_matrix', 'u_sizeRatio', 'u_correctionRatio', 'u_minEdgeThickness', 'u_lengthToThicknessRatio', 'u_widenessToThicknessRatio'];
15
+ export declare const REACH = 4;
16
+ /** How many times its line's width a link that glows fully is drawn: the line and its glow either side. */
17
+ export declare const SPREAD: number;
48
18
  /**
49
- * An arrowhead on a strong link only, at the note it arrives at: Sigma's own
50
- * head, one triangle a link, drawn transparent where the link is not strong.
51
- * Every link already reads in its direction by its gradient, and a head on
52
- * each of a graph's thousands of links is a field of chevrons.
19
+ * The links' primitives: a straight line drawn by Helix's layer, and a head
20
+ * on the strong ones only, at the note a link arrives at. Every link already
21
+ * reads in its direction by its gradient, and a head on each of a graph's
22
+ * thousands of links is a field of chevrons.
53
23
  */
54
- export declare class HelixArrowHeadProgram extends EdgeProgram<(typeof HEAD_UNIFORMS)[number]> {
55
- getDefinition(): {
56
- ATTRIBUTES: ({
57
- normalized?: never;
58
- name: string;
59
- size: number;
60
- type: 5126;
61
- } | {
62
- name: string;
63
- normalized: boolean;
64
- size: number;
65
- type: 5121;
66
- })[];
67
- CONSTANT_ATTRIBUTES: {
68
- name: string;
69
- size: number;
70
- type: 5126;
71
- }[];
72
- CONSTANT_DATA: number[][];
73
- FRAGMENT_SHADER_SOURCE: string;
74
- METHOD: 4;
75
- UNIFORMS: readonly ["u_matrix", "u_sizeRatio", "u_correctionRatio", "u_minEdgeThickness", "u_lengthToThicknessRatio", "u_widenessToThicknessRatio"];
76
- VERTEX_SHADER_SOURCE: string;
77
- VERTICES: number;
78
- };
79
- processVisibleItem(edgeIndex: number, startIndex: number, sourceData: NodeDisplayData, targetData: NodeDisplayData, data: EdgeDisplayData & HelixEdgeData): void;
80
- setUniforms(params: RenderParams, { gl, uniformLocations, }: {
81
- gl: WebGLRenderingContext;
82
- uniformLocations: Record<string, WebGLUniformLocation>;
83
- }): void;
84
- }
85
- /** The line and its head, as one program a link is drawn with. */
86
- export declare const HelixEdgeProgram: EdgeProgramType;
87
- export {};
24
+ export declare const edgePrimitives: () => EdgePrimitives;
@@ -1,316 +1,46 @@
1
- import { createEdgeCompoundProgram, EdgeProgram } from 'sigma/rendering';
2
- import { floatColor } from 'sigma/utils';
3
- const REACH = 4;
4
- const NONE = 'rgba(0, 0, 0, 0)';
5
- const VERTEX = `
6
- attribute vec4 a_id;
7
- attribute vec4 a_color;
8
- attribute vec2 a_normal;
9
- attribute float a_normalCoef;
10
- attribute vec2 a_positionStart;
11
- attribute vec2 a_positionEnd;
12
- attribute float a_positionCoef;
13
- attribute float a_glow;
14
-
15
- uniform mat3 u_matrix;
16
- uniform float u_sizeRatio;
17
- uniform float u_zoomRatio;
18
- uniform float u_pixelRatio;
19
- uniform float u_correctionRatio;
20
- uniform float u_minEdgeThickness;
21
- uniform float u_feather;
22
-
23
- varying vec4 v_color;
24
- varying vec2 v_normal;
25
- varying float v_thickness;
26
- varying float v_feather;
27
- varying float v_along;
28
- varying float v_glow;
29
- varying float v_spread;
30
-
31
- const float bias = 255.0 / 254.0;
32
-
33
- void main() {
34
- float minThickness = u_minEdgeThickness;
35
-
36
- vec2 normal = a_normal * a_normalCoef;
37
- vec2 position = a_positionStart * (1.0 - a_positionCoef) + a_positionEnd * a_positionCoef;
38
-
39
- float normalLength = length(normal);
40
- vec2 unitNormal = normal / normalLength;
41
-
42
- /* At least the minimum thickness on screen, in the WebGL referential, as
43
- Sigma's own rectangle does it. */
44
- float pixelsThickness = max(normalLength, minThickness * u_sizeRatio);
45
- float webGLThickness = pixelsThickness * u_correctionRatio / u_sizeRatio;
46
-
47
- /* The quad reaches past the line by the room its glow needs, and only
48
- where it glows: a resting link's quad is the line's own width. */
49
- float spread = 1.0 + a_glow * ${REACH.toFixed(1)};
50
- gl_Position = vec4((u_matrix * vec3(position + unitNormal * webGLThickness * spread, 1)).xy, 0, 1);
51
-
52
- v_thickness = webGLThickness / u_zoomRatio;
53
- v_normal = unitNormal;
54
- v_feather = u_feather * u_correctionRatio / u_zoomRatio / u_pixelRatio * 2.0;
55
- v_along = a_positionCoef;
56
- v_glow = a_glow;
57
- v_spread = spread;
58
-
59
- #ifdef PICKING_MODE
60
- v_color = a_id;
61
- #else
62
- v_color = a_color;
63
- #endif
64
-
65
- v_color.a *= bias;
66
- }
67
- `;
68
- const FRAGMENT = `
69
- precision mediump float;
70
-
71
- varying vec4 v_color;
72
- varying vec2 v_normal;
73
- varying float v_thickness;
74
- varying float v_feather;
75
- varying float v_along;
76
- varying float v_glow;
77
- varying float v_spread;
78
-
79
- void main(void) {
80
- #ifdef PICKING_MODE
81
- gl_FragColor = v_color;
82
- #else
83
- /* Across the quad, from the line's middle out: the normal interpolates
84
- through zero at the middle, so its length is the distance in half-widths
85
- of the quad, and the quad is the line widened by its spread. */
86
- float dist = length(v_normal) * v_spread * v_thickness;
87
- float line = 1.0 - smoothstep(v_thickness - v_feather, v_thickness, dist);
1
+ import { extremityArrow, pathLine } from 'sigma/rendering';
2
+ export const REACH = 4;
3
+ export const SPREAD = 1 + REACH;
4
+ const HEAD = { length: 2.5 / SPREAD, width: 2 / SPREAD };
5
+ const { FLOAT } = WebGL2RenderingContext;
6
+ const look = {
7
+ attributes: [{ name: 'helixGlow', size: 1, source: 'glow', type: FLOAT }],
8
+ glsl: `
9
+ vec4 layer_helix(EdgeContext ctx) {
10
+ /* Across the link, from its middle out, in the width it is drawn at: the
11
+ line's own width and, where it glows, the glow either side. */
12
+ float spread = 1.0 + v_helixGlow * ${REACH.toFixed(1)};
13
+ float halfWidth = ctx.thickness * 0.5 / spread;
14
+ float dist = ctx.sdf + ctx.thickness * 0.5;
15
+ float line = v_helixGlow > 0.0 ? 1.0 - smoothstep(halfWidth - ctx.aaWidth, halfWidth, dist) : 1.0;
88
16
 
89
17
  /* The glow, outside the line: a soft light falling away from its edge, in
90
18
  the link's own color, as a note's halo falls away from its rim. */
91
- float past = max(dist - v_thickness, 0.0) / max(v_thickness * ${REACH.toFixed(1)}, 0.0001);
92
- float halo = v_glow * (1.0 - line) * exp(-past * 3.2) * (1.0 - smoothstep(0.7, 1.0, past)) * 0.55;
19
+ float past = max(dist - halfWidth, 0.0) / max(halfWidth * ${REACH.toFixed(1)}, 0.0001);
20
+ float halo = v_helixGlow * (1.0 - line) * exp(-past * 3.2) * (1.0 - smoothstep(0.7, 1.0, past)) * 0.55;
93
21
 
94
22
  /* Faint where the link leaves and full where it arrives, so the direction
95
23
  reads along every link, and the one lit by the selection as a path. */
96
- float along = mix(0.4, 1.0, smoothstep(0.0, 1.0, v_along));
97
-
98
- float alpha = (line + halo) * along * v_color.a;
99
- /* Premultiplied, as Sigma blends. */
100
- gl_FragColor = vec4(v_color.rgb * alpha, alpha);
101
- #endif
102
- }
103
- `;
104
- const { FLOAT, UNSIGNED_BYTE } = WebGLRenderingContext;
105
- const UNIFORMS = [
106
- 'u_matrix',
107
- 'u_zoomRatio',
108
- 'u_sizeRatio',
109
- 'u_correctionRatio',
110
- 'u_pixelRatio',
111
- 'u_feather',
112
- 'u_minEdgeThickness',
113
- ];
114
- export class HelixEdgeLineProgram extends EdgeProgram {
115
- getDefinition() {
116
- return {
117
- ATTRIBUTES: [
118
- { name: 'a_positionStart', size: 2, type: FLOAT },
119
- { name: 'a_positionEnd', size: 2, type: FLOAT },
120
- { name: 'a_normal', size: 2, type: FLOAT },
121
- { name: 'a_color', normalized: true, size: 4, type: UNSIGNED_BYTE },
122
- { name: 'a_id', normalized: true, size: 4, type: UNSIGNED_BYTE },
123
- { name: 'a_glow', size: 1, type: FLOAT },
124
- ],
125
- CONSTANT_ATTRIBUTES: [
126
- { name: 'a_positionCoef', size: 1, type: FLOAT },
127
- { name: 'a_normalCoef', size: 1, type: FLOAT },
128
- ],
129
- CONSTANT_DATA: [
130
- [0, 1],
131
- [0, -1],
132
- [1, 1],
133
- [1, 1],
134
- [0, -1],
135
- [1, -1],
136
- ],
137
- FRAGMENT_SHADER_SOURCE: FRAGMENT,
138
- METHOD: WebGLRenderingContext.TRIANGLES,
139
- UNIFORMS,
140
- VERTEX_SHADER_SOURCE: VERTEX,
141
- VERTICES: 6,
142
- };
143
- }
144
- processVisibleItem(edgeIndex, startIndex, sourceData, targetData, data) {
145
- const thickness = data.size || 1;
146
- const dx = targetData.x - sourceData.x;
147
- const dy = targetData.y - sourceData.y;
148
- let len = dx * dx + dy * dy;
149
- let n1 = 0;
150
- let n2 = 0;
151
- if (len) {
152
- len = 1 / Math.sqrt(len);
153
- n1 = -dy * len * thickness;
154
- n2 = dx * len * thickness;
155
- }
156
- const array = this.array;
157
- let at = startIndex;
158
- array[at++] = sourceData.x;
159
- array[at++] = sourceData.y;
160
- array[at++] = targetData.x;
161
- array[at++] = targetData.y;
162
- array[at++] = n1;
163
- array[at++] = n2;
164
- array[at++] = floatColor(data.color);
165
- array[at++] = edgeIndex;
166
- array[at] = data.glow ?? 0;
167
- }
168
- setUniforms(params, { gl, uniformLocations, }) {
169
- gl.uniformMatrix3fv(uniformLocations.u_matrix, false, params.matrix);
170
- gl.uniform1f(uniformLocations.u_zoomRatio, params.zoomRatio);
171
- gl.uniform1f(uniformLocations.u_sizeRatio, params.sizeRatio);
172
- gl.uniform1f(uniformLocations.u_correctionRatio, params.correctionRatio);
173
- gl.uniform1f(uniformLocations.u_pixelRatio, params.pixelRatio);
174
- gl.uniform1f(uniformLocations.u_feather, params.antiAliasingFeather);
175
- gl.uniform1f(uniformLocations.u_minEdgeThickness, params.minEdgeThickness);
176
- }
177
- }
178
- const HEAD_VERTEX = `
179
- attribute vec2 a_position;
180
- attribute vec2 a_normal;
181
- attribute float a_radius;
182
- attribute vec3 a_barycentric;
183
- attribute vec4 a_id;
184
- attribute vec4 a_color;
185
-
186
- uniform mat3 u_matrix;
187
- uniform float u_sizeRatio;
188
- uniform float u_correctionRatio;
189
- uniform float u_minEdgeThickness;
190
- uniform float u_lengthToThicknessRatio;
191
- uniform float u_widenessToThicknessRatio;
192
-
193
- varying vec4 v_color;
194
-
195
- const float bias = 255.0 / 254.0;
196
-
197
- void main() {
198
- float minThickness = u_minEdgeThickness;
199
-
200
- float normalLength = length(a_normal);
201
- vec2 unitNormal = a_normal / normalLength;
202
-
203
- /* As Sigma's own arrowhead: the thickness on screen, the note's radius,
204
- and the head's length and width from the thickness. */
205
- float pixelsThickness = max(normalLength / u_sizeRatio, minThickness);
206
- float webGLThickness = pixelsThickness * u_correctionRatio;
207
- float webGLNodeRadius = a_radius * 2.0 * u_correctionRatio / u_sizeRatio;
208
- float webGLArrowHeadLength = webGLThickness * u_lengthToThicknessRatio * 2.0;
209
- float webGLArrowHeadThickness = webGLThickness * u_widenessToThicknessRatio;
24
+ float along = mix(0.4, 1.0, smoothstep(0.0, 1.0, ctx.t));
210
25
 
211
- float da = a_barycentric.x;
212
- float db = a_barycentric.y;
213
- float dc = a_barycentric.z;
26
+ float alpha = (line + halo) * along;
214
27
 
215
- vec2 delta = vec2(
216
- da * (webGLNodeRadius * unitNormal.y)
217
- + db * ((webGLNodeRadius + webGLArrowHeadLength) * unitNormal.y + webGLArrowHeadThickness * unitNormal.x)
218
- + dc * ((webGLNodeRadius + webGLArrowHeadLength) * unitNormal.y - webGLArrowHeadThickness * unitNormal.x),
28
+ /* The head, solid, narrowing from its base to its tip. Sigma's own cut
29
+ there is the line's whole width near the base, glow and all. */
30
+ if (v_zone > 1.5) {
31
+ float headHalf = ctx.thickness * v_headWidthRatio * 0.5 * (1.0 - v_zoneT);
32
+ alpha = max(alpha, 1.0 - smoothstep(headHalf - ctx.aaWidth, headHalf, dist));
33
+ }
219
34
 
220
- da * (-webGLNodeRadius * unitNormal.x)
221
- + db * (-(webGLNodeRadius + webGLArrowHeadLength) * unitNormal.x + webGLArrowHeadThickness * unitNormal.y)
222
- + dc * (-(webGLNodeRadius + webGLArrowHeadLength) * unitNormal.x - webGLArrowHeadThickness * unitNormal.y)
223
- );
224
-
225
- gl_Position = vec4((u_matrix * vec3(a_position + delta, 1)).xy, 0, 1);
226
-
227
- #ifdef PICKING_MODE
228
- v_color = a_id;
229
- #else
230
- v_color = a_color;
231
- #endif
232
-
233
- v_color.a *= bias;
234
- }
235
- `;
236
- const HEAD_FRAGMENT = `
237
- precision mediump float;
238
-
239
- varying vec4 v_color;
240
-
241
- void main(void) {
242
- #ifdef PICKING_MODE
243
- gl_FragColor = v_color;
244
- #else
245
- /* Premultiplied, as Sigma blends. */
246
- gl_FragColor = vec4(v_color.rgb * v_color.a, v_color.a);
247
- #endif
248
- }
249
- `;
250
- const HEAD_UNIFORMS = [
251
- 'u_matrix',
252
- 'u_sizeRatio',
253
- 'u_correctionRatio',
254
- 'u_minEdgeThickness',
255
- 'u_lengthToThicknessRatio',
256
- 'u_widenessToThicknessRatio',
257
- ];
258
- const HEAD = { length: 2.5, wideness: 2 };
259
- export class HelixArrowHeadProgram extends EdgeProgram {
260
- getDefinition() {
261
- return {
262
- ATTRIBUTES: [
263
- { name: 'a_position', size: 2, type: FLOAT },
264
- { name: 'a_normal', size: 2, type: FLOAT },
265
- { name: 'a_radius', size: 1, type: FLOAT },
266
- { name: 'a_color', normalized: true, size: 4, type: UNSIGNED_BYTE },
267
- { name: 'a_id', normalized: true, size: 4, type: UNSIGNED_BYTE },
268
- ],
269
- CONSTANT_ATTRIBUTES: [{ name: 'a_barycentric', size: 3, type: FLOAT }],
270
- CONSTANT_DATA: [
271
- [1, 0, 0],
272
- [0, 1, 0],
273
- [0, 0, 1],
274
- ],
275
- FRAGMENT_SHADER_SOURCE: HEAD_FRAGMENT,
276
- METHOD: WebGLRenderingContext.TRIANGLES,
277
- UNIFORMS: HEAD_UNIFORMS,
278
- VERTEX_SHADER_SOURCE: HEAD_VERTEX,
279
- VERTICES: 3,
280
- };
281
- }
282
- processVisibleItem(edgeIndex, startIndex, sourceData, targetData, data) {
283
- const thickness = data.size || 1;
284
- const dx = targetData.x - sourceData.x;
285
- const dy = targetData.y - sourceData.y;
286
- let len = dx * dx + dy * dy;
287
- let n1 = 0;
288
- let n2 = 0;
289
- if (len) {
290
- len = 1 / Math.sqrt(len);
291
- n1 = -dy * len * thickness;
292
- n2 = dx * len * thickness;
293
- }
294
- const array = this.array;
295
- let at = startIndex;
296
- array[at++] = targetData.x;
297
- array[at++] = targetData.y;
298
- array[at++] = -n1;
299
- array[at++] = -n2;
300
- array[at++] = targetData.size || 1;
301
- array[at++] = floatColor(data.strong ? data.color : NONE);
302
- array[at] = edgeIndex;
303
- }
304
- setUniforms(params, { gl, uniformLocations, }) {
305
- gl.uniformMatrix3fv(uniformLocations.u_matrix, false, params.matrix);
306
- gl.uniform1f(uniformLocations.u_sizeRatio, params.sizeRatio);
307
- gl.uniform1f(uniformLocations.u_correctionRatio, params.correctionRatio);
308
- gl.uniform1f(uniformLocations.u_minEdgeThickness, params.minEdgeThickness);
309
- gl.uniform1f(uniformLocations.u_lengthToThicknessRatio, HEAD.length);
310
- gl.uniform1f(uniformLocations.u_widenessToThicknessRatio, HEAD.wideness);
311
- }
35
+ return vec4(v_color.rgb, alpha * v_color.a);
312
36
  }
313
- export const HelixEdgeProgram = createEdgeCompoundProgram([
314
- HelixEdgeLineProgram,
315
- HelixArrowHeadProgram,
316
- ]);
37
+ `,
38
+ name: 'helix',
39
+ uniforms: [],
40
+ };
41
+ export const edgePrimitives = () => ({
42
+ defaultHead: 'none',
43
+ extremities: [extremityArrow({ lengthRatio: HEAD.length, widthRatio: HEAD.width })],
44
+ layers: [look],
45
+ paths: [pathLine()],
46
+ });
@@ -1,2 +1,3 @@
1
- export { type HelixEdgeData, HelixEdgeProgram } from './edge-program.js';
1
+ export type { HelixEdgeData } from './edge-program.js';
2
2
  export { type SigmaCamera, type SigmaDriverOptions, type SigmaGraph, type SigmaLayout, type SigmaRenderer, sigmaDriver, } from './sigma-driver.js';
3
+ export { type SigmaOptionsOverrides, sigmaOptions } from './sigma-options.js';
@@ -1,2 +1,2 @@
1
- export { HelixEdgeProgram } from './edge-program.js';
2
1
  export { sigmaDriver, } from './sigma-driver.js';
2
+ export { sigmaOptions } from './sigma-options.js';
@@ -1,11 +1,10 @@
1
- import { NodeProgram } from 'sigma/rendering';
2
- import type { NodeDisplayData, RenderParams } from 'sigma/types';
3
- /** The shapes a note is drawn in, numbered as the shader reads them. */
1
+ import type { NodePrimitives } from 'sigma/primitives';
2
+ /** The shapes a note is drawn in, by the name each is registered under. A ring is a circle drawn outlined. */
4
3
  export declare const SHAPES: {
5
- readonly circle: 0;
6
- readonly diamond: 2;
7
- readonly ring: 3;
8
- readonly square: 1;
4
+ readonly circle: 'helixCircle';
5
+ readonly diamond: 'helixDiamond';
6
+ readonly ring: 'helixCircle';
7
+ readonly square: 'helixSquare';
9
8
  };
10
9
  /** How heavily a note is drawn, numbered as the shader reads them. */
11
10
  export declare const EMPHASES: {
@@ -20,53 +19,24 @@ export declare const MATERIALS: {
20
19
  readonly glass: 1;
21
20
  readonly mark: 3;
22
21
  };
23
- /** What the node program reads off a note, beyond what Sigma gives every note. */
22
+ /**
23
+ * How much larger a diamond is drawn than its size says. **Sigma draws a note
24
+ * in a square as wide as the note**, and a diamond's tips are its widest
25
+ * points: one that reached past the square, as Helix's did at 1.22 radii, was
26
+ * cut off there. So the diamond is drawn to the square's edge and the note
27
+ * made larger by the reach it lost, and it covers what it covered before.
28
+ */
29
+ export declare const DIAMOND: number;
30
+ /** What the node layer reads off a note, beyond what Sigma gives every note. */
24
31
  export interface HelixNodeData {
25
32
  /** `EMPHASES`. */
26
33
  emphasisCode?: number;
27
- /** How strongly the note glows, from 0 to 1: the selected note's halo. */
28
- glow?: number;
29
34
  /** `MATERIALS`. */
30
35
  materialCode?: number;
31
- /** `SHAPES`. */
32
- shapeCode?: number;
33
36
  }
34
- declare const UNIFORMS: readonly ['u_sizeRatio', 'u_correctionRatio', 'u_matrix'];
35
37
  /**
36
- * Draws a note in its shape, its emphasis and its material, with a glow where
37
- * it is selected: one triangle a note, as Sigma's own circle is, cut to the
38
- * shape where it is drawn. Pressing reads the shape and not the glow, so a
39
- * press beside a note is not a press on it.
38
+ * The notes' primitives: Helix's shapes and the layer that draws a note's
39
+ * emphasis and material. Pressing reads the shape, so a press beside a note is
40
+ * not a press on it.
40
41
  */
41
- export declare class HelixNodeProgram extends NodeProgram<(typeof UNIFORMS)[number]> {
42
- getDefinition(): {
43
- ATTRIBUTES: ({
44
- name: string;
45
- size: number;
46
- type: 5126;
47
- normalized?: never;
48
- } | {
49
- name: string;
50
- normalized: boolean;
51
- size: number;
52
- type: 5121;
53
- })[];
54
- CONSTANT_ATTRIBUTES: {
55
- name: string;
56
- size: number;
57
- type: 5126;
58
- }[];
59
- CONSTANT_DATA: number[][];
60
- FRAGMENT_SHADER_SOURCE: string;
61
- METHOD: 4;
62
- UNIFORMS: readonly ["u_sizeRatio", "u_correctionRatio", "u_matrix"];
63
- VERTEX_SHADER_SOURCE: string;
64
- VERTICES: number;
65
- };
66
- processVisibleItem(nodeIndex: number, startIndex: number, data: NodeDisplayData & HelixNodeData): void;
67
- setUniforms(params: RenderParams, { gl, uniformLocations, }: {
68
- gl: WebGLRenderingContext;
69
- uniformLocations: Record<string, WebGLUniformLocation>;
70
- }): void;
71
- }
72
- export {};
42
+ export declare const nodePrimitives: () => NodePrimitives;