@cosmos.gl/graph 2.6.0 → 2.6.2-rc.0
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/config.d.ts +3 -0
- package/dist/index.d.ts +48 -6
- package/dist/index.js +1346 -1289
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +15 -15
- package/dist/index.min.js.map +1 -1
- package/package.json +5 -1
- package/.eslintrc +0 -147
- package/.github/SECURITY.md +0 -19
- package/.github/dco.yml +0 -4
- package/.github/workflows/github_pages.yml +0 -54
- package/.storybook/main.ts +0 -26
- package/.storybook/manager-head.html +0 -1
- package/.storybook/manager.ts +0 -14
- package/.storybook/preview.ts +0 -29
- package/.storybook/style.css +0 -3
- package/CHARTER.md +0 -69
- package/CODE_OF_CONDUCT.md +0 -178
- package/CONTRIBUTING.md +0 -22
- package/GOVERNANCE.md +0 -21
- package/cosmos-2-0-migration-notes.md +0 -98
- package/cosmos_awesome.md +0 -96
- package/dist/stories/beginners/basic-set-up/data-gen.d.ts +0 -4
- package/dist/stories/beginners/basic-set-up/index.d.ts +0 -5
- package/dist/stories/beginners/link-hovering/data-generator.d.ts +0 -19
- package/dist/stories/beginners/link-hovering/index.d.ts +0 -5
- package/dist/stories/beginners/pinned-points/data-gen.d.ts +0 -5
- package/dist/stories/beginners/pinned-points/index.d.ts +0 -5
- package/dist/stories/beginners/point-labels/data.d.ts +0 -13
- package/dist/stories/beginners/point-labels/index.d.ts +0 -9
- package/dist/stories/beginners/point-labels/labels.d.ts +0 -8
- package/dist/stories/beginners/quick-start.d.ts +0 -5
- package/dist/stories/beginners/remove-points/config.d.ts +0 -2
- package/dist/stories/beginners/remove-points/data-gen.d.ts +0 -4
- package/dist/stories/beginners/remove-points/index.d.ts +0 -5
- package/dist/stories/beginners.stories.d.ts +0 -11
- package/dist/stories/clusters/polygon-selection/index.d.ts +0 -6
- package/dist/stories/clusters/polygon-selection/polygon.d.ts +0 -20
- package/dist/stories/clusters/radial.d.ts +0 -5
- package/dist/stories/clusters/with-labels.d.ts +0 -6
- package/dist/stories/clusters/worm.d.ts +0 -5
- package/dist/stories/clusters.stories.d.ts +0 -9
- package/dist/stories/create-cluster-labels.d.ts +0 -4
- package/dist/stories/create-cosmos.d.ts +0 -16
- package/dist/stories/create-story.d.ts +0 -16
- package/dist/stories/experiments/full-mesh.d.ts +0 -5
- package/dist/stories/experiments/mesh-with-holes.d.ts +0 -5
- package/dist/stories/experiments.stories.d.ts +0 -7
- package/dist/stories/generate-mesh-data.d.ts +0 -12
- package/dist/stories/geospatial/moscow-metro-stations/index.d.ts +0 -15
- package/dist/stories/geospatial/moscow-metro-stations/moscow-metro-coords.d.ts +0 -1
- package/dist/stories/geospatial/moscow-metro-stations/point-colors.d.ts +0 -1
- package/dist/stories/geospatial.stories.d.ts +0 -6
- package/dist/stories/shapes/all-shapes/index.d.ts +0 -5
- package/dist/stories/shapes/image-example/index.d.ts +0 -5
- package/dist/stories/shapes.stories.d.ts +0 -7
- package/logo.svg +0 -3
- package/rollup.config.js +0 -70
- package/src/config.ts +0 -734
- package/src/declaration.d.ts +0 -12
- package/src/graph/utils/error-message.ts +0 -23
- package/src/helper.ts +0 -74
- package/src/index.ts +0 -1635
- package/src/modules/Clusters/calculate-centermass.frag +0 -9
- package/src/modules/Clusters/calculate-centermass.vert +0 -26
- package/src/modules/Clusters/force-cluster.frag +0 -39
- package/src/modules/Clusters/index.ts +0 -200
- package/src/modules/Drag/index.ts +0 -33
- package/src/modules/FPSMonitor/css.ts +0 -53
- package/src/modules/FPSMonitor/index.ts +0 -28
- package/src/modules/ForceCenter/calculate-centermass.frag +0 -9
- package/src/modules/ForceCenter/calculate-centermass.vert +0 -18
- package/src/modules/ForceCenter/force-center.frag +0 -27
- package/src/modules/ForceCenter/index.ts +0 -104
- package/src/modules/ForceGravity/force-gravity.frag +0 -27
- package/src/modules/ForceGravity/index.ts +0 -33
- package/src/modules/ForceLink/force-spring.ts +0 -73
- package/src/modules/ForceLink/index.ts +0 -149
- package/src/modules/ForceManyBody/calculate-level.frag +0 -9
- package/src/modules/ForceManyBody/calculate-level.vert +0 -25
- package/src/modules/ForceManyBody/force-centermass.frag +0 -52
- package/src/modules/ForceManyBody/force-level.frag +0 -121
- package/src/modules/ForceManyBody/index.ts +0 -223
- package/src/modules/ForceManyBody/quadtree-frag-shader.ts +0 -90
- package/src/modules/ForceManyBodyQuadtree/calculate-level.frag +0 -9
- package/src/modules/ForceManyBodyQuadtree/calculate-level.vert +0 -25
- package/src/modules/ForceManyBodyQuadtree/index.ts +0 -157
- package/src/modules/ForceManyBodyQuadtree/quadtree-frag-shader.ts +0 -93
- package/src/modules/ForceMouse/force-mouse.frag +0 -24
- package/src/modules/ForceMouse/index.ts +0 -32
- package/src/modules/GraphData/index.ts +0 -384
- package/src/modules/Lines/draw-curve-line.frag +0 -46
- package/src/modules/Lines/draw-curve-line.vert +0 -194
- package/src/modules/Lines/geometry.ts +0 -18
- package/src/modules/Lines/hovered-line-index.frag +0 -27
- package/src/modules/Lines/hovered-line-index.vert +0 -8
- package/src/modules/Lines/index.ts +0 -273
- package/src/modules/Points/atlas-utils.ts +0 -137
- package/src/modules/Points/drag-point.frag +0 -20
- package/src/modules/Points/draw-highlighted.frag +0 -16
- package/src/modules/Points/draw-highlighted.vert +0 -86
- package/src/modules/Points/draw-points.frag +0 -243
- package/src/modules/Points/draw-points.vert +0 -127
- package/src/modules/Points/fill-sampled-points.frag +0 -9
- package/src/modules/Points/fill-sampled-points.vert +0 -29
- package/src/modules/Points/find-hovered-point.frag +0 -9
- package/src/modules/Points/find-hovered-point.vert +0 -57
- package/src/modules/Points/find-points-on-area-selection.frag +0 -48
- package/src/modules/Points/find-points-on-polygon-selection.frag +0 -65
- package/src/modules/Points/index.ts +0 -968
- package/src/modules/Points/track-positions.frag +0 -18
- package/src/modules/Points/update-position.frag +0 -37
- package/src/modules/Shared/buffer.ts +0 -37
- package/src/modules/Shared/clear.frag +0 -7
- package/src/modules/Shared/quad.vert +0 -12
- package/src/modules/Store/index.ts +0 -173
- package/src/modules/Zoom/index.ts +0 -148
- package/src/modules/core-module.ts +0 -28
- package/src/stories/1. welcome.mdx +0 -81
- package/src/stories/2. configuration.mdx +0 -113
- package/src/stories/3. api-reference.mdx +0 -591
- package/src/stories/beginners/basic-set-up/data-gen.ts +0 -33
- package/src/stories/beginners/basic-set-up/index.ts +0 -163
- package/src/stories/beginners/basic-set-up/style.css +0 -35
- package/src/stories/beginners/link-hovering/data-generator.ts +0 -198
- package/src/stories/beginners/link-hovering/index.ts +0 -61
- package/src/stories/beginners/link-hovering/style.css +0 -73
- package/src/stories/beginners/pinned-points/data-gen.ts +0 -153
- package/src/stories/beginners/pinned-points/index.ts +0 -61
- package/src/stories/beginners/point-labels/data.ts +0 -73
- package/src/stories/beginners/point-labels/index.ts +0 -65
- package/src/stories/beginners/point-labels/labels.ts +0 -46
- package/src/stories/beginners/point-labels/style.css +0 -16
- package/src/stories/beginners/quick-start.ts +0 -50
- package/src/stories/beginners/remove-points/config.ts +0 -25
- package/src/stories/beginners/remove-points/data-gen.ts +0 -30
- package/src/stories/beginners/remove-points/index.ts +0 -92
- package/src/stories/beginners/remove-points/style.css +0 -31
- package/src/stories/beginners.stories.ts +0 -131
- package/src/stories/clusters/polygon-selection/index.ts +0 -51
- package/src/stories/clusters/polygon-selection/polygon.ts +0 -143
- package/src/stories/clusters/polygon-selection/style.css +0 -8
- package/src/stories/clusters/radial.ts +0 -24
- package/src/stories/clusters/with-labels.ts +0 -53
- package/src/stories/clusters/worm.ts +0 -40
- package/src/stories/clusters.stories.ts +0 -77
- package/src/stories/create-cluster-labels.ts +0 -50
- package/src/stories/create-cosmos.ts +0 -68
- package/src/stories/create-story.ts +0 -51
- package/src/stories/experiments/full-mesh.ts +0 -13
- package/src/stories/experiments/mesh-with-holes.ts +0 -13
- package/src/stories/experiments.stories.ts +0 -43
- package/src/stories/generate-mesh-data.ts +0 -125
- package/src/stories/geospatial/moscow-metro-stations/index.ts +0 -62
- package/src/stories/geospatial/moscow-metro-stations/moscow-metro-coords.ts +0 -1
- package/src/stories/geospatial/moscow-metro-stations/point-colors.ts +0 -46
- package/src/stories/geospatial/moscow-metro-stations/style.css +0 -30
- package/src/stories/geospatial.stories.ts +0 -30
- package/src/stories/shapes/all-shapes/index.ts +0 -69
- package/src/stories/shapes/image-example/icons/box.png +0 -0
- package/src/stories/shapes/image-example/icons/lego.png +0 -0
- package/src/stories/shapes/image-example/icons/s.png +0 -0
- package/src/stories/shapes/image-example/icons/swift.png +0 -0
- package/src/stories/shapes/image-example/icons/toolbox.png +0 -0
- package/src/stories/shapes/image-example/index.ts +0 -238
- package/src/stories/shapes.stories.ts +0 -37
- package/src/variables.ts +0 -68
- package/tsconfig.json +0 -41
- package/vite.config.ts +0 -54
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
import regl from 'regl'
|
|
2
|
-
import { CoreModule } from '@/graph/modules/core-module'
|
|
3
|
-
import drawLineFrag from '@/graph/modules/Lines/draw-curve-line.frag'
|
|
4
|
-
import drawLineVert from '@/graph/modules/Lines/draw-curve-line.vert'
|
|
5
|
-
import hoveredLineIndexFrag from '@/graph/modules/Lines/hovered-line-index.frag'
|
|
6
|
-
import hoveredLineIndexVert from '@/graph/modules/Lines/hovered-line-index.vert'
|
|
7
|
-
import { defaultConfigValues } from '@/graph/variables'
|
|
8
|
-
import { getCurveLineGeometry } from '@/graph/modules/Lines/geometry'
|
|
9
|
-
|
|
10
|
-
export class Lines extends CoreModule {
|
|
11
|
-
public linkIndexFbo: regl.Framebuffer2D | undefined
|
|
12
|
-
public hoveredLineIndexFbo: regl.Framebuffer2D | undefined
|
|
13
|
-
private drawCurveCommand: regl.DrawCommand | undefined
|
|
14
|
-
private hoveredLineIndexCommand: regl.DrawCommand | undefined
|
|
15
|
-
private pointsBuffer: regl.Buffer | undefined
|
|
16
|
-
private colorBuffer: regl.Buffer | undefined
|
|
17
|
-
private widthBuffer: regl.Buffer | undefined
|
|
18
|
-
private arrowBuffer: regl.Buffer | undefined
|
|
19
|
-
private curveLineGeometry: number[][] | undefined
|
|
20
|
-
private curveLineBuffer: regl.Buffer | undefined
|
|
21
|
-
private linkIndexBuffer: regl.Buffer | undefined
|
|
22
|
-
private quadBuffer: regl.Buffer | undefined
|
|
23
|
-
|
|
24
|
-
public initPrograms (): void {
|
|
25
|
-
const { reglInstance, config, store } = this
|
|
26
|
-
|
|
27
|
-
this.updateLinkIndexFbo()
|
|
28
|
-
|
|
29
|
-
// Initialize the hovered line index FBO
|
|
30
|
-
if (!this.hoveredLineIndexFbo) {
|
|
31
|
-
this.hoveredLineIndexFbo = reglInstance.framebuffer({
|
|
32
|
-
color: reglInstance.texture({
|
|
33
|
-
width: 1,
|
|
34
|
-
height: 1,
|
|
35
|
-
format: 'rgba',
|
|
36
|
-
type: 'float',
|
|
37
|
-
}),
|
|
38
|
-
depth: false,
|
|
39
|
-
stencil: false,
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (!this.drawCurveCommand) {
|
|
44
|
-
this.drawCurveCommand = reglInstance({
|
|
45
|
-
vert: drawLineVert,
|
|
46
|
-
frag: drawLineFrag,
|
|
47
|
-
|
|
48
|
-
attributes: {
|
|
49
|
-
position: {
|
|
50
|
-
buffer: () => this.curveLineBuffer,
|
|
51
|
-
divisor: 0,
|
|
52
|
-
},
|
|
53
|
-
pointA: {
|
|
54
|
-
buffer: () => this.pointsBuffer,
|
|
55
|
-
divisor: 1,
|
|
56
|
-
offset: Float32Array.BYTES_PER_ELEMENT * 0,
|
|
57
|
-
stride: Float32Array.BYTES_PER_ELEMENT * 4,
|
|
58
|
-
},
|
|
59
|
-
pointB: {
|
|
60
|
-
buffer: () => this.pointsBuffer,
|
|
61
|
-
divisor: 1,
|
|
62
|
-
offset: Float32Array.BYTES_PER_ELEMENT * 2,
|
|
63
|
-
stride: Float32Array.BYTES_PER_ELEMENT * 4,
|
|
64
|
-
},
|
|
65
|
-
color: {
|
|
66
|
-
buffer: () => this.colorBuffer,
|
|
67
|
-
divisor: 1,
|
|
68
|
-
offset: Float32Array.BYTES_PER_ELEMENT * 0,
|
|
69
|
-
stride: Float32Array.BYTES_PER_ELEMENT * 4,
|
|
70
|
-
},
|
|
71
|
-
width: {
|
|
72
|
-
buffer: () => this.widthBuffer,
|
|
73
|
-
divisor: 1,
|
|
74
|
-
offset: Float32Array.BYTES_PER_ELEMENT * 0,
|
|
75
|
-
stride: Float32Array.BYTES_PER_ELEMENT * 1,
|
|
76
|
-
},
|
|
77
|
-
arrow: {
|
|
78
|
-
buffer: () => this.arrowBuffer,
|
|
79
|
-
divisor: 1,
|
|
80
|
-
offset: Float32Array.BYTES_PER_ELEMENT * 0,
|
|
81
|
-
stride: Float32Array.BYTES_PER_ELEMENT * 1,
|
|
82
|
-
},
|
|
83
|
-
linkIndices: {
|
|
84
|
-
buffer: () => this.linkIndexBuffer,
|
|
85
|
-
divisor: 1,
|
|
86
|
-
offset: Float32Array.BYTES_PER_ELEMENT * 0,
|
|
87
|
-
stride: Float32Array.BYTES_PER_ELEMENT * 1,
|
|
88
|
-
},
|
|
89
|
-
},
|
|
90
|
-
uniforms: {
|
|
91
|
-
positionsTexture: () => this.points?.currentPositionFbo,
|
|
92
|
-
pointGreyoutStatus: () => this.points?.greyoutStatusFbo,
|
|
93
|
-
transformationMatrix: () => store.transform,
|
|
94
|
-
pointsTextureSize: () => store.pointsTextureSize,
|
|
95
|
-
widthScale: () => config.linkWidthScale,
|
|
96
|
-
linkArrowsSizeScale: () => config.linkArrowsSizeScale,
|
|
97
|
-
spaceSize: () => store.adjustedSpaceSize,
|
|
98
|
-
screenSize: () => store.screenSize,
|
|
99
|
-
linkVisibilityDistanceRange: () => config.linkVisibilityDistanceRange,
|
|
100
|
-
linkVisibilityMinTransparency: () => config.linkVisibilityMinTransparency,
|
|
101
|
-
linkOpacity: () => config.linkOpacity,
|
|
102
|
-
greyoutOpacity: () => config.linkGreyoutOpacity,
|
|
103
|
-
scaleLinksOnZoom: () => config.scaleLinksOnZoom,
|
|
104
|
-
maxPointSize: () => store.maxPointSize,
|
|
105
|
-
curvedWeight: () => config.curvedLinkWeight,
|
|
106
|
-
curvedLinkControlPointDistance: () => config.curvedLinkControlPointDistance,
|
|
107
|
-
curvedLinkSegments: () => config.curvedLinks ? config.curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1,
|
|
108
|
-
hoveredLinkIndex: () => store.hoveredLinkIndex ?? -1,
|
|
109
|
-
hoveredLinkColor: () => store.hoveredLinkColor,
|
|
110
|
-
hoveredLinkWidthIncrease: () => config.hoveredLinkWidthIncrease,
|
|
111
|
-
renderMode: reglInstance.prop<{ renderMode: number }, 'renderMode'>('renderMode'),
|
|
112
|
-
},
|
|
113
|
-
cull: {
|
|
114
|
-
enable: true,
|
|
115
|
-
face: 'back',
|
|
116
|
-
},
|
|
117
|
-
/**
|
|
118
|
-
* Blending behavior for link index rendering (renderMode: 1.0 - hover detection):
|
|
119
|
-
*
|
|
120
|
-
* When rendering link indices to the framebuffer, we use full opacity (1.0).
|
|
121
|
-
* This means:
|
|
122
|
-
* - The source color completely overwrites the destination
|
|
123
|
-
* - No blending occurs - it's like drawing with a permanent marker
|
|
124
|
-
* - This preserves the exact index values we need for picking/selection
|
|
125
|
-
*/
|
|
126
|
-
blend: {
|
|
127
|
-
enable: true,
|
|
128
|
-
func: {
|
|
129
|
-
dstRGB: 'one minus src alpha',
|
|
130
|
-
srcRGB: 'src alpha',
|
|
131
|
-
dstAlpha: 'one minus src alpha',
|
|
132
|
-
srcAlpha: 'one',
|
|
133
|
-
},
|
|
134
|
-
equation: {
|
|
135
|
-
rgb: 'add',
|
|
136
|
-
alpha: 'add',
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
depth: {
|
|
140
|
-
enable: false,
|
|
141
|
-
mask: false,
|
|
142
|
-
},
|
|
143
|
-
framebuffer: reglInstance.prop<{ framebuffer: regl.Framebuffer2D }, 'framebuffer'>('framebuffer'),
|
|
144
|
-
count: () => this.curveLineGeometry?.length ?? 0,
|
|
145
|
-
instances: () => this.data.linksNumber ?? 0,
|
|
146
|
-
primitive: 'triangle strip',
|
|
147
|
-
})
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (!this.hoveredLineIndexCommand) {
|
|
151
|
-
this.hoveredLineIndexCommand = reglInstance({
|
|
152
|
-
vert: hoveredLineIndexVert,
|
|
153
|
-
frag: hoveredLineIndexFrag,
|
|
154
|
-
attributes: {
|
|
155
|
-
position: {
|
|
156
|
-
buffer: () => this.quadBuffer,
|
|
157
|
-
},
|
|
158
|
-
},
|
|
159
|
-
uniforms: {
|
|
160
|
-
linkIndexTexture: () => this.linkIndexFbo,
|
|
161
|
-
mousePosition: () => store.screenMousePosition,
|
|
162
|
-
screenSize: () => store.screenSize,
|
|
163
|
-
},
|
|
164
|
-
framebuffer: this.hoveredLineIndexFbo,
|
|
165
|
-
count: 4,
|
|
166
|
-
primitive: 'triangle strip',
|
|
167
|
-
})
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Initialize quad buffer for full-screen rendering
|
|
171
|
-
if (!this.quadBuffer) {
|
|
172
|
-
this.quadBuffer = reglInstance.buffer([-1, -1, 1, -1, -1, 1, 1, 1])
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
public draw (): void {
|
|
177
|
-
if (!this.pointsBuffer) return
|
|
178
|
-
if (!this.colorBuffer) this.updateColor()
|
|
179
|
-
if (!this.widthBuffer) this.updateWidth()
|
|
180
|
-
if (!this.arrowBuffer) this.updateArrow()
|
|
181
|
-
if (!this.curveLineGeometry) this.updateCurveLineGeometry()
|
|
182
|
-
|
|
183
|
-
// Render normal links (renderMode: 0.0 = normal rendering)
|
|
184
|
-
this.drawCurveCommand?.({ framebuffer: null, renderMode: 0.0 })
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
public updateLinkIndexFbo (): void {
|
|
188
|
-
const { reglInstance, store } = this
|
|
189
|
-
|
|
190
|
-
// Only create and update the link index FBO if link hovering is enabled
|
|
191
|
-
if (!this.store.isLinkHoveringEnabled) return
|
|
192
|
-
|
|
193
|
-
if (!this.linkIndexFbo) this.linkIndexFbo = reglInstance.framebuffer()
|
|
194
|
-
this.linkIndexFbo({
|
|
195
|
-
color: reglInstance.texture({
|
|
196
|
-
width: store.screenSize[0],
|
|
197
|
-
height: store.screenSize[1],
|
|
198
|
-
format: 'rgba',
|
|
199
|
-
type: 'float',
|
|
200
|
-
}),
|
|
201
|
-
depth: false,
|
|
202
|
-
stencil: false,
|
|
203
|
-
})
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
public updatePointsBuffer (): void {
|
|
207
|
-
const { reglInstance, data, store } = this
|
|
208
|
-
if (data.linksNumber === undefined || data.links === undefined) return
|
|
209
|
-
const instancePoints = new Float32Array(data.linksNumber * 4)
|
|
210
|
-
for (let i = 0; i < data.linksNumber; i++) {
|
|
211
|
-
const fromIndex = data.links[i * 2] as number
|
|
212
|
-
const toIndex = data.links[i * 2 + 1] as number
|
|
213
|
-
const fromX = fromIndex % store.pointsTextureSize
|
|
214
|
-
const fromY = Math.floor(fromIndex / store.pointsTextureSize)
|
|
215
|
-
const toX = toIndex % store.pointsTextureSize
|
|
216
|
-
const toY = Math.floor(toIndex / store.pointsTextureSize)
|
|
217
|
-
const offset = i * 4
|
|
218
|
-
instancePoints[offset] = fromX
|
|
219
|
-
instancePoints[offset + 1] = fromY
|
|
220
|
-
instancePoints[offset + 2] = toX
|
|
221
|
-
instancePoints[offset + 3] = toY
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (!this.pointsBuffer) this.pointsBuffer = reglInstance.buffer(0)
|
|
225
|
-
this.pointsBuffer(instancePoints)
|
|
226
|
-
|
|
227
|
-
const linkIndices = new Float32Array(data.linksNumber)
|
|
228
|
-
for (let i = 0; i < data.linksNumber; i++) {
|
|
229
|
-
linkIndices[i] = i
|
|
230
|
-
}
|
|
231
|
-
if (!this.linkIndexBuffer) this.linkIndexBuffer = reglInstance.buffer(0)
|
|
232
|
-
this.linkIndexBuffer(linkIndices)
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
public updateColor (): void {
|
|
236
|
-
const { reglInstance, data } = this
|
|
237
|
-
if (!this.colorBuffer) this.colorBuffer = reglInstance.buffer(0)
|
|
238
|
-
this.colorBuffer(data.linkColors ?? new Float32Array())
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
public updateWidth (): void {
|
|
242
|
-
const { reglInstance, data } = this
|
|
243
|
-
if (!this.widthBuffer) this.widthBuffer = reglInstance.buffer(0)
|
|
244
|
-
this.widthBuffer(data.linkWidths ?? new Float32Array())
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
public updateArrow (): void {
|
|
248
|
-
const { reglInstance, data } = this
|
|
249
|
-
if (!this.arrowBuffer) this.arrowBuffer = reglInstance.buffer(0)
|
|
250
|
-
this.arrowBuffer(data.linkArrows ?? new Float32Array())
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
public updateCurveLineGeometry (): void {
|
|
254
|
-
const { reglInstance, config: { curvedLinks, curvedLinkSegments } } = this
|
|
255
|
-
this.curveLineGeometry = getCurveLineGeometry(curvedLinks ? curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1)
|
|
256
|
-
if (!this.curveLineBuffer) this.curveLineBuffer = reglInstance.buffer(0)
|
|
257
|
-
this.curveLineBuffer(this.curveLineGeometry)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
public findHoveredLine (): void {
|
|
261
|
-
if (!this.data.linksNumber || !this.store.isLinkHoveringEnabled) return
|
|
262
|
-
if (!this.linkIndexFbo) this.updateLinkIndexFbo()
|
|
263
|
-
this.reglInstance.clear({
|
|
264
|
-
framebuffer: this.linkIndexFbo as regl.Framebuffer2D,
|
|
265
|
-
color: [0, 0, 0, 0],
|
|
266
|
-
})
|
|
267
|
-
// Render to index buffer for picking/hover detection (renderMode: 1.0 = index rendering)
|
|
268
|
-
this.drawCurveCommand?.({ framebuffer: this.linkIndexFbo, renderMode: 1.0 })
|
|
269
|
-
|
|
270
|
-
// Execute the command to read the link index at mouse position
|
|
271
|
-
this.hoveredLineIndexCommand?.()
|
|
272
|
-
}
|
|
273
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates a texture atlas from an array of ImageData objects.
|
|
3
|
-
*
|
|
4
|
-
* A texture atlas is a single large texture that contains multiple smaller images.
|
|
5
|
-
* This allows efficient rendering by reducing the number of texture bindings needed.
|
|
6
|
-
*
|
|
7
|
-
* The atlas uses a grid layout where each image gets a square region sized to
|
|
8
|
-
* accommodate the largest image dimension. Images are placed left-to-right, top-to-bottom.
|
|
9
|
-
*
|
|
10
|
-
* @param imageDataArray - Array of ImageData objects to pack into the atlas
|
|
11
|
-
* @param webglMaxTextureSize - WebGL maximum texture size limit (default: 16384)
|
|
12
|
-
* @returns Atlas data object containing:
|
|
13
|
-
* - atlasData: RGBA pixel data as Uint8Array
|
|
14
|
-
* - atlasSize: Total atlas texture size in pixels
|
|
15
|
-
* - atlasCoords: UV coordinates for each image as Float32Array
|
|
16
|
-
* - atlasCoordsSize: Grid size (number of rows/columns)
|
|
17
|
-
* Returns null if creation fails or no valid images provided
|
|
18
|
-
*/
|
|
19
|
-
export function createAtlasDataFromImageData (
|
|
20
|
-
imageDataArray: ImageData[],
|
|
21
|
-
webglMaxTextureSize = 16384
|
|
22
|
-
): {
|
|
23
|
-
atlasData: Uint8Array;
|
|
24
|
-
atlasSize: number;
|
|
25
|
-
atlasCoords: Float32Array;
|
|
26
|
-
atlasCoordsSize: number;
|
|
27
|
-
} | null {
|
|
28
|
-
// Step 1: Validate input - ensure we have images to process
|
|
29
|
-
if (!imageDataArray?.length) {
|
|
30
|
-
return null
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Step 2: Find the maximum dimension across all images
|
|
34
|
-
// The max dimension determines the size of each grid cell in the atlas
|
|
35
|
-
let maxDimension = 0
|
|
36
|
-
for (const imageData of imageDataArray) {
|
|
37
|
-
const dimension = Math.max(imageData.width, imageData.height)
|
|
38
|
-
if (dimension > maxDimension) {
|
|
39
|
-
maxDimension = dimension
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Step 3: Validate that we found valid image dimensions
|
|
44
|
-
if (maxDimension === 0) {
|
|
45
|
-
console.warn('Invalid image dimensions: all images have zero width or height')
|
|
46
|
-
return null
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const originalMaxDimension = maxDimension
|
|
50
|
-
|
|
51
|
-
// Step 4: Calculate optimal atlas grid size
|
|
52
|
-
const atlasCoordsSize = Math.ceil(Math.sqrt(imageDataArray.length))
|
|
53
|
-
let atlasSize = atlasCoordsSize * maxDimension
|
|
54
|
-
|
|
55
|
-
// Step 5: Apply WebGL size limit scaling if necessary
|
|
56
|
-
let scalingFactor = 1.0
|
|
57
|
-
|
|
58
|
-
if (atlasSize > webglMaxTextureSize) {
|
|
59
|
-
// Calculate required scale to fit within WebGL limits
|
|
60
|
-
scalingFactor = webglMaxTextureSize / atlasSize
|
|
61
|
-
|
|
62
|
-
// Apply scaling to both the individual image dimensions and atlas size
|
|
63
|
-
maxDimension = Math.max(1, Math.floor(maxDimension * scalingFactor))
|
|
64
|
-
atlasSize = Math.max(1, Math.floor(atlasSize * scalingFactor))
|
|
65
|
-
|
|
66
|
-
console.warn(
|
|
67
|
-
'🖼️ Atlas scaling required: Original size ' +
|
|
68
|
-
`${(originalMaxDimension * atlasCoordsSize).toLocaleString()}px exceeds WebGL limit ` +
|
|
69
|
-
`${webglMaxTextureSize.toLocaleString()}px. Scaling down to ${atlasSize.toLocaleString()}px ` +
|
|
70
|
-
`(${Math.round(scalingFactor * 100)}% of original quality)`
|
|
71
|
-
)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Step 6: Create buffers for atlas data
|
|
75
|
-
const atlasData = new Uint8Array(atlasSize * atlasSize * 4).fill(0)
|
|
76
|
-
const atlasCoords = new Float32Array(atlasCoordsSize * atlasCoordsSize * 4).fill(-1)
|
|
77
|
-
|
|
78
|
-
// Step 7: Pack each image into the atlas grid
|
|
79
|
-
for (const [index, imageData] of imageDataArray.entries()) {
|
|
80
|
-
const originalWidth = imageData.width
|
|
81
|
-
const originalHeight = imageData.height
|
|
82
|
-
if (originalWidth === 0 || originalHeight === 0) {
|
|
83
|
-
// leave coords at -1 for this index and continue
|
|
84
|
-
continue
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Calculate individual scale for this image based on maxDimension
|
|
88
|
-
// This ensures each image fits optimally within its grid cell
|
|
89
|
-
const individualScale = Math.min(1.0, maxDimension / Math.max(originalWidth, originalHeight))
|
|
90
|
-
|
|
91
|
-
const scaledWidth = Math.floor(originalWidth * individualScale)
|
|
92
|
-
const scaledHeight = Math.floor(originalHeight * individualScale)
|
|
93
|
-
|
|
94
|
-
// Calculate grid position (row, column) for this image
|
|
95
|
-
const row = Math.floor(index / atlasCoordsSize)
|
|
96
|
-
const col = index % atlasCoordsSize
|
|
97
|
-
|
|
98
|
-
// Calculate pixel position in the atlas texture
|
|
99
|
-
const atlasX = col * maxDimension
|
|
100
|
-
const atlasY = row * maxDimension
|
|
101
|
-
|
|
102
|
-
// Calculate and store UV coordinates for this image
|
|
103
|
-
atlasCoords[index * 4] = atlasX / atlasSize // minU
|
|
104
|
-
atlasCoords[index * 4 + 1] = atlasY / atlasSize // minV
|
|
105
|
-
atlasCoords[index * 4 + 2] = (atlasX + scaledWidth) / atlasSize // maxU
|
|
106
|
-
atlasCoords[index * 4 + 3] = (atlasY + scaledHeight) / atlasSize // maxV
|
|
107
|
-
|
|
108
|
-
// Copy image pixel data into the atlas texture
|
|
109
|
-
for (let y = 0; y < scaledHeight; y++) {
|
|
110
|
-
for (let x = 0; x < scaledWidth; x++) {
|
|
111
|
-
// Calculate source pixel coordinates (with scaling)
|
|
112
|
-
const srcX = Math.floor(x * (originalWidth / scaledWidth))
|
|
113
|
-
const srcY = Math.floor(y * (originalHeight / scaledHeight))
|
|
114
|
-
|
|
115
|
-
// Calculate source pixel index in the original image
|
|
116
|
-
const srcIndex = (srcY * originalWidth + srcX) * 4
|
|
117
|
-
|
|
118
|
-
// Calculate target pixel index in the atlas texture
|
|
119
|
-
const atlasIndex = ((atlasY + y) * atlasSize + (atlasX + x)) * 4
|
|
120
|
-
|
|
121
|
-
// Copy RGBA values from source to atlas
|
|
122
|
-
atlasData[atlasIndex] = imageData.data[srcIndex] ?? 0 // Red channel
|
|
123
|
-
atlasData[atlasIndex + 1] = imageData.data[srcIndex + 1] ?? 0 // Green channel
|
|
124
|
-
atlasData[atlasIndex + 2] = imageData.data[srcIndex + 2] ?? 0 // Blue channel
|
|
125
|
-
atlasData[atlasIndex + 3] = imageData.data[srcIndex + 3] ?? 255 // Alpha channel
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Return the complete atlas data
|
|
131
|
-
return {
|
|
132
|
-
atlasData,
|
|
133
|
-
atlasSize,
|
|
134
|
-
atlasCoords,
|
|
135
|
-
atlasCoordsSize,
|
|
136
|
-
}
|
|
137
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
#ifdef GL_ES
|
|
2
|
-
precision highp float;
|
|
3
|
-
#endif
|
|
4
|
-
|
|
5
|
-
uniform sampler2D positionsTexture;
|
|
6
|
-
uniform vec2 mousePos;
|
|
7
|
-
uniform float index;
|
|
8
|
-
|
|
9
|
-
varying vec2 textureCoords;
|
|
10
|
-
|
|
11
|
-
void main() {
|
|
12
|
-
vec4 pointPosition = texture2D(positionsTexture, textureCoords);
|
|
13
|
-
|
|
14
|
-
// Check if a point is being dragged
|
|
15
|
-
if (index >= 0.0 && index == pointPosition.b) {
|
|
16
|
-
pointPosition.rg = mousePos.rg;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
gl_FragColor = pointPosition;
|
|
20
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
precision mediump float;
|
|
2
|
-
|
|
3
|
-
uniform float width;
|
|
4
|
-
|
|
5
|
-
varying vec2 vertexPosition;
|
|
6
|
-
varying float pointOpacity;
|
|
7
|
-
varying vec3 rgbColor;
|
|
8
|
-
|
|
9
|
-
const float smoothing = 1.05;
|
|
10
|
-
|
|
11
|
-
void main () {
|
|
12
|
-
float r = dot(vertexPosition, vertexPosition);
|
|
13
|
-
float opacity = smoothstep(r, r * smoothing, 1.0);
|
|
14
|
-
float stroke = smoothstep(width, width * smoothing, r);
|
|
15
|
-
gl_FragColor = vec4(rgbColor, opacity * stroke * pointOpacity);
|
|
16
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
precision mediump float;
|
|
2
|
-
|
|
3
|
-
attribute vec2 vertexCoord;
|
|
4
|
-
|
|
5
|
-
uniform sampler2D positionsTexture;
|
|
6
|
-
uniform sampler2D pointGreyoutStatusTexture;
|
|
7
|
-
uniform float size;
|
|
8
|
-
uniform mat3 transformationMatrix;
|
|
9
|
-
uniform float pointsTextureSize;
|
|
10
|
-
uniform float sizeScale;
|
|
11
|
-
uniform float spaceSize;
|
|
12
|
-
uniform vec2 screenSize;
|
|
13
|
-
uniform bool scalePointsOnZoom;
|
|
14
|
-
uniform float pointIndex;
|
|
15
|
-
uniform float maxPointSize;
|
|
16
|
-
uniform vec4 color;
|
|
17
|
-
uniform float universalPointOpacity;
|
|
18
|
-
uniform float greyoutOpacity;
|
|
19
|
-
uniform bool isDarkenGreyout;
|
|
20
|
-
uniform vec4 backgroundColor;
|
|
21
|
-
uniform vec4 greyoutColor;
|
|
22
|
-
varying vec2 vertexPosition;
|
|
23
|
-
varying float pointOpacity;
|
|
24
|
-
varying vec3 rgbColor;
|
|
25
|
-
|
|
26
|
-
float calculatePointSize(float size) {
|
|
27
|
-
float pSize;
|
|
28
|
-
if (scalePointsOnZoom) {
|
|
29
|
-
pSize = size * transformationMatrix[0][0];
|
|
30
|
-
} else {
|
|
31
|
-
pSize = size * min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));
|
|
32
|
-
}
|
|
33
|
-
return min(pSize, maxPointSize);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const float relativeRingRadius = 1.3;
|
|
37
|
-
|
|
38
|
-
void main () {
|
|
39
|
-
vertexPosition = vertexCoord;
|
|
40
|
-
|
|
41
|
-
vec2 textureCoordinates = vec2(mod(pointIndex, pointsTextureSize), floor(pointIndex / pointsTextureSize)) + 0.5;
|
|
42
|
-
vec4 pointPosition = texture2D(positionsTexture, textureCoordinates / pointsTextureSize);
|
|
43
|
-
|
|
44
|
-
rgbColor = color.rgb;
|
|
45
|
-
pointOpacity = color.a * universalPointOpacity;
|
|
46
|
-
vec4 greyoutStatus = texture2D(pointGreyoutStatusTexture, textureCoordinates / pointsTextureSize);
|
|
47
|
-
if (greyoutStatus.r > 0.0) {
|
|
48
|
-
if (greyoutColor[0] != -1.0) {
|
|
49
|
-
rgbColor = greyoutColor.rgb;
|
|
50
|
-
pointOpacity = greyoutColor.a;
|
|
51
|
-
} else {
|
|
52
|
-
// If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout
|
|
53
|
-
float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color)
|
|
54
|
-
|
|
55
|
-
if (isDarkenGreyout) {
|
|
56
|
-
// Darken the color
|
|
57
|
-
rgbColor = mix(rgbColor, vec3(0.2), blendFactor);
|
|
58
|
-
} else {
|
|
59
|
-
// Lighten the color
|
|
60
|
-
rgbColor = mix(rgbColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (greyoutOpacity != -1.0) {
|
|
65
|
-
pointOpacity *= greyoutOpacity;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Calculate point radius
|
|
70
|
-
float pointSize = (calculatePointSize(size * sizeScale) * relativeRingRadius) / transformationMatrix[0][0];
|
|
71
|
-
float radius = pointSize * 0.5;
|
|
72
|
-
|
|
73
|
-
// Calculate point position in screen space
|
|
74
|
-
vec2 a = pointPosition.xy;
|
|
75
|
-
vec2 b = pointPosition.xy + vec2(0.0, radius);
|
|
76
|
-
vec2 xBasis = b - a;
|
|
77
|
-
vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));
|
|
78
|
-
vec2 pointPositionInScreenSpace = a + xBasis * vertexCoord.x + yBasis * radius * vertexCoord.y;
|
|
79
|
-
|
|
80
|
-
// Transform point position to normalized device coordinates
|
|
81
|
-
vec2 p = 2.0 * pointPositionInScreenSpace / spaceSize - 1.0;
|
|
82
|
-
p *= spaceSize / screenSize;
|
|
83
|
-
vec3 final = transformationMatrix * vec3(p, 1);
|
|
84
|
-
|
|
85
|
-
gl_Position = vec4(final.rg, 0, 1);
|
|
86
|
-
}
|