@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.
Files changed (169) hide show
  1. package/dist/config.d.ts +3 -0
  2. package/dist/index.d.ts +48 -6
  3. package/dist/index.js +1346 -1289
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.min.js +15 -15
  6. package/dist/index.min.js.map +1 -1
  7. package/package.json +5 -1
  8. package/.eslintrc +0 -147
  9. package/.github/SECURITY.md +0 -19
  10. package/.github/dco.yml +0 -4
  11. package/.github/workflows/github_pages.yml +0 -54
  12. package/.storybook/main.ts +0 -26
  13. package/.storybook/manager-head.html +0 -1
  14. package/.storybook/manager.ts +0 -14
  15. package/.storybook/preview.ts +0 -29
  16. package/.storybook/style.css +0 -3
  17. package/CHARTER.md +0 -69
  18. package/CODE_OF_CONDUCT.md +0 -178
  19. package/CONTRIBUTING.md +0 -22
  20. package/GOVERNANCE.md +0 -21
  21. package/cosmos-2-0-migration-notes.md +0 -98
  22. package/cosmos_awesome.md +0 -96
  23. package/dist/stories/beginners/basic-set-up/data-gen.d.ts +0 -4
  24. package/dist/stories/beginners/basic-set-up/index.d.ts +0 -5
  25. package/dist/stories/beginners/link-hovering/data-generator.d.ts +0 -19
  26. package/dist/stories/beginners/link-hovering/index.d.ts +0 -5
  27. package/dist/stories/beginners/pinned-points/data-gen.d.ts +0 -5
  28. package/dist/stories/beginners/pinned-points/index.d.ts +0 -5
  29. package/dist/stories/beginners/point-labels/data.d.ts +0 -13
  30. package/dist/stories/beginners/point-labels/index.d.ts +0 -9
  31. package/dist/stories/beginners/point-labels/labels.d.ts +0 -8
  32. package/dist/stories/beginners/quick-start.d.ts +0 -5
  33. package/dist/stories/beginners/remove-points/config.d.ts +0 -2
  34. package/dist/stories/beginners/remove-points/data-gen.d.ts +0 -4
  35. package/dist/stories/beginners/remove-points/index.d.ts +0 -5
  36. package/dist/stories/beginners.stories.d.ts +0 -11
  37. package/dist/stories/clusters/polygon-selection/index.d.ts +0 -6
  38. package/dist/stories/clusters/polygon-selection/polygon.d.ts +0 -20
  39. package/dist/stories/clusters/radial.d.ts +0 -5
  40. package/dist/stories/clusters/with-labels.d.ts +0 -6
  41. package/dist/stories/clusters/worm.d.ts +0 -5
  42. package/dist/stories/clusters.stories.d.ts +0 -9
  43. package/dist/stories/create-cluster-labels.d.ts +0 -4
  44. package/dist/stories/create-cosmos.d.ts +0 -16
  45. package/dist/stories/create-story.d.ts +0 -16
  46. package/dist/stories/experiments/full-mesh.d.ts +0 -5
  47. package/dist/stories/experiments/mesh-with-holes.d.ts +0 -5
  48. package/dist/stories/experiments.stories.d.ts +0 -7
  49. package/dist/stories/generate-mesh-data.d.ts +0 -12
  50. package/dist/stories/geospatial/moscow-metro-stations/index.d.ts +0 -15
  51. package/dist/stories/geospatial/moscow-metro-stations/moscow-metro-coords.d.ts +0 -1
  52. package/dist/stories/geospatial/moscow-metro-stations/point-colors.d.ts +0 -1
  53. package/dist/stories/geospatial.stories.d.ts +0 -6
  54. package/dist/stories/shapes/all-shapes/index.d.ts +0 -5
  55. package/dist/stories/shapes/image-example/index.d.ts +0 -5
  56. package/dist/stories/shapes.stories.d.ts +0 -7
  57. package/logo.svg +0 -3
  58. package/rollup.config.js +0 -70
  59. package/src/config.ts +0 -734
  60. package/src/declaration.d.ts +0 -12
  61. package/src/graph/utils/error-message.ts +0 -23
  62. package/src/helper.ts +0 -74
  63. package/src/index.ts +0 -1635
  64. package/src/modules/Clusters/calculate-centermass.frag +0 -9
  65. package/src/modules/Clusters/calculate-centermass.vert +0 -26
  66. package/src/modules/Clusters/force-cluster.frag +0 -39
  67. package/src/modules/Clusters/index.ts +0 -200
  68. package/src/modules/Drag/index.ts +0 -33
  69. package/src/modules/FPSMonitor/css.ts +0 -53
  70. package/src/modules/FPSMonitor/index.ts +0 -28
  71. package/src/modules/ForceCenter/calculate-centermass.frag +0 -9
  72. package/src/modules/ForceCenter/calculate-centermass.vert +0 -18
  73. package/src/modules/ForceCenter/force-center.frag +0 -27
  74. package/src/modules/ForceCenter/index.ts +0 -104
  75. package/src/modules/ForceGravity/force-gravity.frag +0 -27
  76. package/src/modules/ForceGravity/index.ts +0 -33
  77. package/src/modules/ForceLink/force-spring.ts +0 -73
  78. package/src/modules/ForceLink/index.ts +0 -149
  79. package/src/modules/ForceManyBody/calculate-level.frag +0 -9
  80. package/src/modules/ForceManyBody/calculate-level.vert +0 -25
  81. package/src/modules/ForceManyBody/force-centermass.frag +0 -52
  82. package/src/modules/ForceManyBody/force-level.frag +0 -121
  83. package/src/modules/ForceManyBody/index.ts +0 -223
  84. package/src/modules/ForceManyBody/quadtree-frag-shader.ts +0 -90
  85. package/src/modules/ForceManyBodyQuadtree/calculate-level.frag +0 -9
  86. package/src/modules/ForceManyBodyQuadtree/calculate-level.vert +0 -25
  87. package/src/modules/ForceManyBodyQuadtree/index.ts +0 -157
  88. package/src/modules/ForceManyBodyQuadtree/quadtree-frag-shader.ts +0 -93
  89. package/src/modules/ForceMouse/force-mouse.frag +0 -24
  90. package/src/modules/ForceMouse/index.ts +0 -32
  91. package/src/modules/GraphData/index.ts +0 -384
  92. package/src/modules/Lines/draw-curve-line.frag +0 -46
  93. package/src/modules/Lines/draw-curve-line.vert +0 -194
  94. package/src/modules/Lines/geometry.ts +0 -18
  95. package/src/modules/Lines/hovered-line-index.frag +0 -27
  96. package/src/modules/Lines/hovered-line-index.vert +0 -8
  97. package/src/modules/Lines/index.ts +0 -273
  98. package/src/modules/Points/atlas-utils.ts +0 -137
  99. package/src/modules/Points/drag-point.frag +0 -20
  100. package/src/modules/Points/draw-highlighted.frag +0 -16
  101. package/src/modules/Points/draw-highlighted.vert +0 -86
  102. package/src/modules/Points/draw-points.frag +0 -243
  103. package/src/modules/Points/draw-points.vert +0 -127
  104. package/src/modules/Points/fill-sampled-points.frag +0 -9
  105. package/src/modules/Points/fill-sampled-points.vert +0 -29
  106. package/src/modules/Points/find-hovered-point.frag +0 -9
  107. package/src/modules/Points/find-hovered-point.vert +0 -57
  108. package/src/modules/Points/find-points-on-area-selection.frag +0 -48
  109. package/src/modules/Points/find-points-on-polygon-selection.frag +0 -65
  110. package/src/modules/Points/index.ts +0 -968
  111. package/src/modules/Points/track-positions.frag +0 -18
  112. package/src/modules/Points/update-position.frag +0 -37
  113. package/src/modules/Shared/buffer.ts +0 -37
  114. package/src/modules/Shared/clear.frag +0 -7
  115. package/src/modules/Shared/quad.vert +0 -12
  116. package/src/modules/Store/index.ts +0 -173
  117. package/src/modules/Zoom/index.ts +0 -148
  118. package/src/modules/core-module.ts +0 -28
  119. package/src/stories/1. welcome.mdx +0 -81
  120. package/src/stories/2. configuration.mdx +0 -113
  121. package/src/stories/3. api-reference.mdx +0 -591
  122. package/src/stories/beginners/basic-set-up/data-gen.ts +0 -33
  123. package/src/stories/beginners/basic-set-up/index.ts +0 -163
  124. package/src/stories/beginners/basic-set-up/style.css +0 -35
  125. package/src/stories/beginners/link-hovering/data-generator.ts +0 -198
  126. package/src/stories/beginners/link-hovering/index.ts +0 -61
  127. package/src/stories/beginners/link-hovering/style.css +0 -73
  128. package/src/stories/beginners/pinned-points/data-gen.ts +0 -153
  129. package/src/stories/beginners/pinned-points/index.ts +0 -61
  130. package/src/stories/beginners/point-labels/data.ts +0 -73
  131. package/src/stories/beginners/point-labels/index.ts +0 -65
  132. package/src/stories/beginners/point-labels/labels.ts +0 -46
  133. package/src/stories/beginners/point-labels/style.css +0 -16
  134. package/src/stories/beginners/quick-start.ts +0 -50
  135. package/src/stories/beginners/remove-points/config.ts +0 -25
  136. package/src/stories/beginners/remove-points/data-gen.ts +0 -30
  137. package/src/stories/beginners/remove-points/index.ts +0 -92
  138. package/src/stories/beginners/remove-points/style.css +0 -31
  139. package/src/stories/beginners.stories.ts +0 -131
  140. package/src/stories/clusters/polygon-selection/index.ts +0 -51
  141. package/src/stories/clusters/polygon-selection/polygon.ts +0 -143
  142. package/src/stories/clusters/polygon-selection/style.css +0 -8
  143. package/src/stories/clusters/radial.ts +0 -24
  144. package/src/stories/clusters/with-labels.ts +0 -53
  145. package/src/stories/clusters/worm.ts +0 -40
  146. package/src/stories/clusters.stories.ts +0 -77
  147. package/src/stories/create-cluster-labels.ts +0 -50
  148. package/src/stories/create-cosmos.ts +0 -68
  149. package/src/stories/create-story.ts +0 -51
  150. package/src/stories/experiments/full-mesh.ts +0 -13
  151. package/src/stories/experiments/mesh-with-holes.ts +0 -13
  152. package/src/stories/experiments.stories.ts +0 -43
  153. package/src/stories/generate-mesh-data.ts +0 -125
  154. package/src/stories/geospatial/moscow-metro-stations/index.ts +0 -62
  155. package/src/stories/geospatial/moscow-metro-stations/moscow-metro-coords.ts +0 -1
  156. package/src/stories/geospatial/moscow-metro-stations/point-colors.ts +0 -46
  157. package/src/stories/geospatial/moscow-metro-stations/style.css +0 -30
  158. package/src/stories/geospatial.stories.ts +0 -30
  159. package/src/stories/shapes/all-shapes/index.ts +0 -69
  160. package/src/stories/shapes/image-example/icons/box.png +0 -0
  161. package/src/stories/shapes/image-example/icons/lego.png +0 -0
  162. package/src/stories/shapes/image-example/icons/s.png +0 -0
  163. package/src/stories/shapes/image-example/icons/swift.png +0 -0
  164. package/src/stories/shapes/image-example/icons/toolbox.png +0 -0
  165. package/src/stories/shapes/image-example/index.ts +0 -238
  166. package/src/stories/shapes.stories.ts +0 -37
  167. package/src/variables.ts +0 -68
  168. package/tsconfig.json +0 -41
  169. package/vite.config.ts +0 -54
@@ -1,18 +0,0 @@
1
- #ifdef GL_ES
2
- precision highp float;
3
- #endif
4
-
5
- uniform sampler2D positionsTexture;
6
- uniform sampler2D trackedIndices;
7
- uniform float pointsTextureSize;
8
-
9
- varying vec2 textureCoords;
10
-
11
- void main() {
12
- vec4 trackedPointIndices = texture2D(trackedIndices, textureCoords);
13
- if (trackedPointIndices.r < 0.0) discard;
14
- vec4 pointPosition = texture2D(positionsTexture, (trackedPointIndices.rg + 0.5) / pointsTextureSize);
15
-
16
- gl_FragColor = vec4(pointPosition.rg, 1.0, 1.0);
17
- }
18
-
@@ -1,37 +0,0 @@
1
- #ifdef GL_ES
2
- precision highp float;
3
- #endif
4
-
5
- uniform sampler2D positionsTexture;
6
- uniform sampler2D velocity;
7
- uniform sampler2D pinnedStatusTexture;
8
- uniform float friction;
9
- uniform float spaceSize;
10
-
11
- varying vec2 textureCoords;
12
-
13
- void main() {
14
- vec4 pointPosition = texture2D(positionsTexture, textureCoords);
15
- vec4 pointVelocity = texture2D(velocity, textureCoords);
16
-
17
- // Check if point is pinned
18
- // pinnedStatusTexture has the same size and layout as positionsTexture
19
- // Each pixel corresponds to a point: red channel > 0.5 means the point is pinned
20
- vec4 pinnedStatus = texture2D(pinnedStatusTexture, textureCoords);
21
-
22
- // If pinned, don't update position
23
- if (pinnedStatus.r > 0.5) {
24
- gl_FragColor = pointPosition;
25
- return;
26
- }
27
-
28
- // Friction
29
- pointVelocity.rg *= friction;
30
-
31
- pointPosition.rg += pointVelocity.rg;
32
-
33
- pointPosition.r = clamp(pointPosition.r, 0.0, spaceSize);
34
- pointPosition.g = clamp(pointPosition.g, 0.0, spaceSize);
35
-
36
- gl_FragColor = pointPosition;
37
- }
@@ -1,37 +0,0 @@
1
- import regl from 'regl'
2
-
3
- export function createQuadBuffer (reglInstance: regl.Regl): { buffer: regl.Buffer; size: number } {
4
- const quadBuffer = reglInstance.buffer(new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]))
5
- return {
6
- buffer: quadBuffer,
7
- size: 2,
8
- }
9
- }
10
-
11
- export function createIndexesForBuffer (textureSize: number): Float32Array {
12
- const indexes = new Float32Array(textureSize * textureSize * 2)
13
- for (let y = 0; y < textureSize; y++) {
14
- for (let x = 0; x < textureSize; x++) {
15
- const i = y * textureSize * 2 + x * 2
16
- indexes[i + 0] = x
17
- indexes[i + 1] = y
18
- }
19
- }
20
- return indexes
21
- }
22
-
23
- export function destroyFramebuffer (fbo?: regl.Framebuffer2D): void {
24
- if (!fbo) return
25
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
- if ((fbo as any)?._framebuffer?.framebuffer) {
27
- fbo.destroy()
28
- }
29
- }
30
-
31
- export function destroyBuffer (fbo?: regl.Buffer): void {
32
- if (!fbo) return
33
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
- if ((fbo as any)?._buffer?.buffer) {
35
- fbo.destroy()
36
- }
37
- }
@@ -1,7 +0,0 @@
1
- #ifdef GL_ES
2
- precision highp float;
3
- #endif
4
-
5
- void main() {
6
- gl_FragColor = vec4(0.0);
7
- }
@@ -1,12 +0,0 @@
1
- #ifdef GL_ES
2
- precision highp float;
3
- #endif
4
-
5
- attribute vec2 vertexCoord; // Vertex coordinates in normalized device coordinates
6
- varying vec2 textureCoords; // Texture coordinates to pass to the fragment shader
7
-
8
- void main() {
9
- // Convert vertex coordinates from [-1, 1] range to [0, 1] range for texture sampling
10
- textureCoords = (vertexCoord + 1.0) / 2.0;
11
- gl_Position = vec4(vertexCoord, 0, 1);
12
- }
@@ -1,173 +0,0 @@
1
- import { scaleLinear } from 'd3-scale'
2
- import { mat3 } from 'gl-matrix'
3
- import { Random } from 'random'
4
- import { getRgbaColor, rgbToBrightness } from '@/graph/helper'
5
- import { hoveredPointRingOpacity, focusedPointRingOpacity, defaultConfigValues } from '@/graph/variables'
6
- import type { GraphConfigInterface } from '@/graph/config'
7
-
8
- export const ALPHA_MIN = 0.001
9
- export const MAX_POINT_SIZE = 64
10
-
11
- /**
12
- * Maximum number of executions to delay before performing hover detection.
13
- * This threshold prevents excessive hover detection calls for performance optimization.
14
- * The `findHoveredItem` method will skip actual detection until this count is reached.
15
- */
16
- export const MAX_HOVER_DETECTION_DELAY = 4
17
-
18
- export type Hovered = { index: number; position: [ number, number ] }
19
- type Focused = { index: number }
20
-
21
- export class Store {
22
- public pointsTextureSize = 0
23
- public linksTextureSize = 0
24
- public alpha = 1
25
- public transform = mat3.create()
26
- public screenSize: [number, number] = [0, 0]
27
- public mousePosition = [0, 0]
28
- public screenMousePosition = [0, 0]
29
- public selectedArea = [[0, 0], [0, 0]]
30
- public isSimulationRunning = false
31
- public simulationProgress = 0
32
- public selectedIndices: Float32Array | null = null
33
- public maxPointSize = MAX_POINT_SIZE
34
- public hoveredPoint: Hovered | undefined = undefined
35
- public focusedPoint: Focused | undefined = undefined
36
- public draggingPointIndex: number | undefined = undefined
37
- public hoveredLinkIndex: number | undefined = undefined
38
- public adjustedSpaceSize = defaultConfigValues.spaceSize
39
- public isSpaceKeyPressed = false
40
- public div: HTMLDivElement | undefined
41
- public webglMaxTextureSize = 16384 // Default fallback value
42
-
43
- public hoveredPointRingColor = [1, 1, 1, hoveredPointRingOpacity]
44
- public focusedPointRingColor = [1, 1, 1, focusedPointRingOpacity]
45
- public hoveredLinkColor = [-1, -1, -1, -1]
46
- // -1 means that the color is not set
47
- public greyoutPointColor = [-1, -1, -1, -1]
48
- // If backgroundColor is dark, isDarkenGreyout is true
49
- public isDarkenGreyout = false
50
- // Whether link hovering is enabled based on configured event handlers
51
- public isLinkHoveringEnabled = false
52
- private alphaTarget = 0
53
- private scalePointX = scaleLinear()
54
- private scalePointY = scaleLinear()
55
- private random = new Random()
56
- private _backgroundColor: [number, number, number, number] = [0, 0, 0, 0]
57
-
58
- public get backgroundColor (): [number, number, number, number] {
59
- return this._backgroundColor
60
- }
61
-
62
- public set backgroundColor (color: [number, number, number, number]) {
63
- this._backgroundColor = color
64
- const brightness = rgbToBrightness(color[0], color[1], color[2])
65
- document.documentElement.style.setProperty('--cosmosgl-attribution-color', brightness > 0.65 ? 'black' : 'white')
66
- document.documentElement.style.setProperty('--cosmosgl-error-message-color', brightness > 0.65 ? 'black' : 'white')
67
- if (this.div) this.div.style.backgroundColor = `rgba(${color[0] * 255}, ${color[1] * 255}, ${color[2] * 255}, ${color[3]})`
68
-
69
- this.isDarkenGreyout = brightness < 0.65
70
- }
71
-
72
- public addRandomSeed (seed: number | string): void {
73
- this.random = this.random.clone(seed)
74
- }
75
-
76
- public getRandomFloat (min: number, max: number): number {
77
- return this.random.float(min, max)
78
- }
79
-
80
- /**
81
- * If the config parameter `spaceSize` exceeds the limits of WebGL,
82
- * it reduces the space size without changing the config parameter.
83
- */
84
- public adjustSpaceSize (configSpaceSize: number, webglMaxTextureSize: number): void {
85
- if (configSpaceSize >= webglMaxTextureSize) {
86
- this.adjustedSpaceSize = webglMaxTextureSize / 2
87
- console.warn(`The \`spaceSize\` has been reduced to ${this.adjustedSpaceSize} due to WebGL limits`)
88
- } else this.adjustedSpaceSize = configSpaceSize
89
- }
90
-
91
- /**
92
- * Sets the WebGL texture size limit for use in atlas creation and other texture operations.
93
- */
94
- public setWebGLMaxTextureSize (webglMaxTextureSize: number): void {
95
- this.webglMaxTextureSize = webglMaxTextureSize
96
- }
97
-
98
- public updateScreenSize (width: number, height: number): void {
99
- const { adjustedSpaceSize } = this
100
- this.screenSize = [width, height]
101
- this.scalePointX
102
- .domain([0, adjustedSpaceSize])
103
- .range([(width - adjustedSpaceSize) / 2, (width + adjustedSpaceSize) / 2])
104
- this.scalePointY
105
- .domain([adjustedSpaceSize, 0])
106
- .range([(height - adjustedSpaceSize) / 2, (height + adjustedSpaceSize) / 2])
107
- }
108
-
109
- public scaleX (x: number): number {
110
- return this.scalePointX(x)
111
- }
112
-
113
- public scaleY (y: number): number {
114
- return this.scalePointY(y)
115
- }
116
-
117
- public setHoveredPointRingColor (color: string | [number, number, number, number]): void {
118
- const convertedRgba = getRgbaColor(color)
119
- this.hoveredPointRingColor[0] = convertedRgba[0]
120
- this.hoveredPointRingColor[1] = convertedRgba[1]
121
- this.hoveredPointRingColor[2] = convertedRgba[2]
122
- }
123
-
124
- public setFocusedPointRingColor (color: string | [number, number, number, number]): void {
125
- const convertedRgba = getRgbaColor(color)
126
- this.focusedPointRingColor[0] = convertedRgba[0]
127
- this.focusedPointRingColor[1] = convertedRgba[1]
128
- this.focusedPointRingColor[2] = convertedRgba[2]
129
- }
130
-
131
- public setGreyoutPointColor (color: string | [number, number, number, number] | undefined): void {
132
- if (color === undefined) {
133
- this.greyoutPointColor = [-1, -1, -1, -1]
134
- return
135
- }
136
- const convertedRgba = getRgbaColor(color)
137
- this.greyoutPointColor[0] = convertedRgba[0]
138
- this.greyoutPointColor[1] = convertedRgba[1]
139
- this.greyoutPointColor[2] = convertedRgba[2]
140
- this.greyoutPointColor[3] = convertedRgba[3]
141
- }
142
-
143
- public updateLinkHoveringEnabled (config: Pick<GraphConfigInterface, 'onLinkClick' | 'onLinkMouseOver' | 'onLinkMouseOut'>): void {
144
- this.isLinkHoveringEnabled = !!(config.onLinkClick || config.onLinkMouseOver || config.onLinkMouseOut)
145
- if (!this.isLinkHoveringEnabled) {
146
- this.hoveredLinkIndex = undefined
147
- }
148
- }
149
-
150
- public setHoveredLinkColor (color?: string | [number, number, number, number]): void {
151
- if (color === undefined) {
152
- this.hoveredLinkColor = [-1, -1, -1, -1]
153
- return
154
- }
155
- const convertedRgba = getRgbaColor(color)
156
- this.hoveredLinkColor[0] = convertedRgba[0]
157
- this.hoveredLinkColor[1] = convertedRgba[1]
158
- this.hoveredLinkColor[2] = convertedRgba[2]
159
- this.hoveredLinkColor[3] = convertedRgba[3]
160
- }
161
-
162
- public setFocusedPoint (index?: number): void {
163
- if (index !== undefined) {
164
- this.focusedPoint = { index }
165
- } else this.focusedPoint = undefined
166
- }
167
-
168
- public addAlpha (decay: number): number {
169
- return (this.alphaTarget - this.alpha) * this.alphaDecay(decay)
170
- }
171
-
172
- private alphaDecay = (decay: number): number => 1 - Math.pow(ALPHA_MIN, 1 / decay)
173
- }
@@ -1,148 +0,0 @@
1
- import { zoom, ZoomTransform, zoomIdentity, D3ZoomEvent } from 'd3-zoom'
2
- import { extent } from 'd3-array'
3
- import { mat3 } from 'gl-matrix'
4
- import { Store } from '@/graph/modules/Store'
5
- import { GraphConfigInterface } from '@/graph/config'
6
- import { clamp } from '@/graph/helper'
7
-
8
- export class Zoom {
9
- public readonly store: Store
10
- public readonly config: GraphConfigInterface
11
- public eventTransform = zoomIdentity
12
- public behavior = zoom<HTMLCanvasElement, undefined>()
13
- .scaleExtent([0.001, Infinity])
14
- .on('start', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {
15
- this.isRunning = true
16
- const userDriven = !!e.sourceEvent
17
- this.config?.onZoomStart?.(e, userDriven)
18
- })
19
- .on('zoom', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {
20
- this.eventTransform = e.transform
21
- const { eventTransform: { x, y, k }, store: { transform, screenSize } } = this
22
- const w = screenSize[0]
23
- const h = screenSize[1]
24
- if (!w || !h) return
25
- mat3.projection(transform, w, h)
26
- mat3.translate(transform, transform, [x, y])
27
- mat3.scale(transform, transform, [k, k])
28
- mat3.translate(transform, transform, [w / 2, h / 2])
29
- mat3.scale(transform, transform, [w / 2, h / 2])
30
- mat3.scale(transform, transform, [1, -1])
31
-
32
- const userDriven = !!e.sourceEvent
33
- this.config?.onZoom?.(e, userDriven)
34
- })
35
- .on('end', (e: D3ZoomEvent<HTMLCanvasElement, undefined>) => {
36
- this.isRunning = false
37
-
38
- const userDriven = !!e.sourceEvent
39
- this.config?.onZoomEnd?.(e, userDriven)
40
- })
41
-
42
- public isRunning = false
43
-
44
- public constructor (store: Store, config: GraphConfigInterface) {
45
- this.store = store
46
- this.config = config
47
- }
48
-
49
- /**
50
- * Get the zoom transform that will fit the given point positions into the viewport
51
- *
52
- * @param positions An array of point positions in the form `[x, y]`
53
- * @param scale An optional scale factor to apply to the transform
54
- * @param padding Padding around the viewport in percentage
55
- */
56
- public getTransform (positions: [number, number][], scale?: number, padding = 0.1): ZoomTransform {
57
- if (positions.length === 0) return this.eventTransform
58
- const { store: { screenSize } } = this
59
- const width = screenSize[0]
60
- const height = screenSize[1]
61
- const xExtent = extent(positions.map(d => d[0])) as [number, number]
62
- const yExtent = extent(positions.map(d => d[1])) as [number, number]
63
- xExtent[0] = this.store.scaleX(xExtent[0])
64
- xExtent[1] = this.store.scaleX(xExtent[1])
65
- yExtent[0] = this.store.scaleY(yExtent[0])
66
- yExtent[1] = this.store.scaleY(yExtent[1])
67
- // Adjust extent with one screen pixel if one point coordinate is set
68
- if (xExtent[0] === xExtent[1]) {
69
- xExtent[0] -= 0.5
70
- xExtent[1] += 0.5
71
- }
72
- if (yExtent[0] === yExtent[1]) {
73
- yExtent[0] += 0.5
74
- yExtent[1] -= 0.5
75
- }
76
-
77
- const xScale = (width * (1 - padding * 2)) / (xExtent[1] - xExtent[0])
78
- const yScale = (height * (1 - padding * 2)) / (yExtent[0] - yExtent[1])
79
- const clampedScale = clamp(scale ?? Math.min(xScale, yScale), ...this.behavior.scaleExtent())
80
- const xCenter = (xExtent[1] + xExtent[0]) / 2
81
- const yCenter = (yExtent[1] + yExtent[0]) / 2
82
- const translateX = width / 2 - xCenter * clampedScale
83
- const translateY = height / 2 - yCenter * clampedScale
84
-
85
- const transform = zoomIdentity
86
- .translate(translateX, translateY)
87
- .scale(clampedScale)
88
-
89
- return transform
90
- }
91
-
92
- public getDistanceToPoint (position: [number, number]): number {
93
- const { x, y, k } = this.eventTransform
94
- const point = this.getTransform([position], k)
95
- const dx = x - point.x
96
- const dy = y - point.y
97
- return Math.sqrt(dx * dx + dy * dy)
98
- }
99
-
100
- public getMiddlePointTransform (position: [number, number]): ZoomTransform {
101
- const { store: { screenSize }, eventTransform: { x, y, k } } = this
102
- const width = screenSize[0]
103
- const height = screenSize[1]
104
- const currX = (width / 2 - x) / k
105
- const currY = (height / 2 - y) / k
106
- const pointX = this.store.scaleX(position[0])
107
- const pointY = this.store.scaleY(position[1])
108
- const centerX = (currX + pointX) / 2
109
- const centerY = (currY + pointY) / 2
110
-
111
- const scale = 1
112
- const translateX = width / 2 - centerX * scale
113
- const translateY = height / 2 - centerY * scale
114
-
115
- return zoomIdentity
116
- .translate(translateX, translateY)
117
- .scale(scale)
118
- }
119
-
120
- public convertScreenToSpacePosition (screenPosition: [number, number]): [number, number] {
121
- const { eventTransform: { x, y, k }, store: { screenSize } } = this
122
- const w = screenSize[0]
123
- const h = screenSize[1]
124
- const invertedX = (screenPosition[0] - x) / k
125
- const invertedY = (screenPosition[1] - y) / k
126
- const spacePosition = [invertedX, (h - invertedY)] as [number, number]
127
- spacePosition[0] -= (w - this.store.adjustedSpaceSize) / 2
128
- spacePosition[1] -= (h - this.store.adjustedSpaceSize) / 2
129
- return spacePosition
130
- }
131
-
132
- public convertSpaceToScreenPosition (spacePosition: [number, number]): [number, number] {
133
- const screenPointX = this.eventTransform.applyX(this.store.scaleX(spacePosition[0]))
134
- const screenPointY = this.eventTransform.applyY(this.store.scaleY(spacePosition[1]))
135
- return [screenPointX, screenPointY]
136
- }
137
-
138
- public convertSpaceToScreenRadius (spaceRadius: number): number {
139
- const { config: { scalePointsOnZoom }, store: { maxPointSize }, eventTransform: { k } } = this
140
- let size = spaceRadius * 2
141
- if (scalePointsOnZoom) {
142
- size *= k
143
- } else {
144
- size *= Math.min(5.0, Math.max(1.0, k * 0.01))
145
- }
146
- return Math.min(size, maxPointSize) / 2
147
- }
148
- }
@@ -1,28 +0,0 @@
1
- import regl from 'regl'
2
- import { GraphConfigInterface } from '@/graph/config'
3
- import { GraphData } from '@/graph/modules/GraphData'
4
- import { Points } from '@/graph/modules/Points'
5
- import { Store } from '@/graph/modules/Store'
6
-
7
- export class CoreModule {
8
- public readonly reglInstance: regl.Regl
9
- public readonly config: GraphConfigInterface
10
- public readonly store: Store
11
- public readonly data: GraphData
12
- public readonly points: Points | undefined
13
- public _debugRandomNumber = Math.floor(Math.random() * 1000)
14
-
15
- public constructor (
16
- reglInstance: regl.Regl,
17
- config: GraphConfigInterface,
18
- store: Store,
19
- data: GraphData,
20
- points?: Points
21
- ) {
22
- this.reglInstance = reglInstance
23
- this.config = config
24
- this.store = store
25
- this.data = data
26
- if (points) this.points = points
27
- }
28
- }
@@ -1,81 +0,0 @@
1
- import { Meta } from "@storybook/blocks";
2
-
3
- <Meta title="Welcome to cosmos.gl" />
4
-
5
- <div style={{ fontSize: '1.0rem', float: 'right' }}>
6
- <a href="https://github.com/cosmosgl/graph" target="_blank" rel="noopener noreferrer" style={{ display: 'inline-flex', alignItems: 'center', gap: '0.5rem', color: '#fff' }}>
7
- <svg height="30" viewBox="0 0 16 16" width="30" aria-hidden="true">
8
- <path fill="currentColor" d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
9
- </svg>
10
- </a>
11
- </div>
12
-
13
- <p style={{ fontSize: '1.75rem', lineHeight: '1.25em', marginTop: 0 }}>Welcome to <b>cosmos.gl</b> – a high-performance WebGL library for visualizing network graphs and machine learning embeddings.</p>
14
-
15
- <video style={{ width: '100%' }} src="https://user-images.githubusercontent.com/755708/173392407-9b05cbb6-d39e-4c2c-ab41-50900cfda823.mp4" loop autoPlay muted playsInline>
16
- </video>
17
-
18
- ---
19
-
20
- ### Quick Start
21
-
22
- Install the package:
23
-
24
- ```bash
25
- npm install @cosmos.gl/graph
26
- ```
27
-
28
-
29
- Get the data, [configure](../?path=/docs/configuration--docs) the graph and run the simulation:
30
- ```javascript
31
- import { Graph } from '@cosmos.gl/graph'
32
-
33
- const div = document.querySelector('div')
34
- const config = {
35
- spaceSize: 4096,
36
- simulationFriction: 0.1, // keeps the graph inert
37
- simulationGravity: 0, // disables gravity
38
- simulationRepulsion: 0.5, // increases repulsion between points
39
- curvedLinks: true, // curved links
40
- fitViewDelay: 1000, // wait 1 second before fitting the view
41
- fitViewPadding: 0.3, // centers the graph width padding of ~30% of screen
42
- rescalePositions: true, // rescale positions
43
- enableDrag: true, // enable dragging points
44
- onPointClick: pointIndex => { console.log('Clicked point index: ', pointIndex) },
45
- onBackgroundClick: () => { console.log('Clicked background') },
46
- /* ... */
47
- }
48
-
49
- const graph = new Graph(div, config)
50
-
51
- // Points: [x1, y1, x2, y2, x3, y3]
52
- const pointPositions = new Float32Array([
53
- 0.0, 0.0, // Point 1 at (0,0)
54
- 1.0, 0.0, // Point 2 at (1,0)
55
- 0.5, 1.0, // Point 3 at (0.5,1)
56
- ]);
57
-
58
- graph.setPointPositions(pointPositions)
59
-
60
- // Links: [sourceIndex1, targetIndex1, sourceIndex2, targetIndex2]
61
- const links = new Float32Array([
62
- 0, 1, // Link from point 0 to point 1
63
- 1, 2, // Link from point 1 to point 2
64
- 2, 0, // Link from point 2 to point 0
65
- ]);
66
-
67
- graph.setLinks(links)
68
-
69
- graph.render()
70
- ```
71
-
72
- Try the [Quick Start](../?path=/story/examples-beginners--quick-start) example.
73
-
74
- ### Examples
75
- - [Basic Set-Up](../?path=/story/examples-beginners--basic-set-up)
76
- - [Adding Point Labels](../?path=/story/examples-beginners--point-labels) (via [`@interacta/css-labels`](https://www.npmjs.com/package/@interacta/css-labels))
77
-
78
-
79
- ---
80
- Copyright [OpenJS Foundation](https://openjsf.org) and cosmos.gl contributors. All rights reserved. The [OpenJS Foundation](https://openjsf.org) has registered trademarks and uses trademarks. For a list of trademarks of the [OpenJS Foundation](https://openjsf.org), please see our [Trademark Policy](https://trademark-policy.openjsf.org/) and [Trademark List](https://trademark-list.openjsf.org/). Trademarks and logos not indicated on the [list of OpenJS Foundation trademarks](https://trademark-list.openjsf.org) are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
81
- [The OpenJS Foundation](https://openjsf.org/) | [Terms of Use](https://terms-of-use.openjsf.org/) | [Privacy Policy](https://privacy-policy.openjsf.org/) | [Bylaws](https://bylaws.openjsf.org/) | [Code of Conduct](https://code-of-conduct.openjsf.org) | [Trademark Policy](https://trademark-policy.openjsf.org/) | [Trademark List](https://trademark-list.openjsf.org/) | [Cookie Policy](https://www.linuxfoundation.org/cookies/)
@@ -1,113 +0,0 @@
1
- import { Meta } from "@storybook/blocks";
2
-
3
- <Meta title="Configuration" />
4
-
5
- # cosmos.gl configuration properties
6
-
7
- | Property | Description | Default |
8
- |---|---|---|
9
- | enableSimulation | If set to `false`, the simulation will not run. This property will be applied only on component initialization and it can't be changed using the `setConfig` method | `true` |
10
- | backgroundColor | Canvas background color | `#222222` |
11
- | spaceSize | Simulation space size (max 8192) | `8192` |
12
- | pointDefaultColor | The default color to use for points when no point colors are provided, or if the color value in the array is `undefined` or `null`. This can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255 | `#b3b3b3` |
13
- | pointColor | **[DEPRECATED]** Use `pointDefaultColor` instead. The default color to use for points when no point colors are provided... | `#b3b3b3` |
14
- | pointGreyoutOpacity | Greyed out point opacity value when the selection is active | `undefined` |
15
- | pointGreyoutColor | The color to use for points when they are greyed out (when selection is active). This can be either a hex color string (e.g., '#b3b3b3') or an array of RGBA values in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255. If not provided, the color will be the same as the point's original color, but darkened or lightened depending on the background color. If `pointGreyoutOpacity` is also defined, it will override the alpha/opacity component of this color. | `undefined` |
16
- | pointSize | The default size value to use for points when no point sizes are provided or if the size value in the array is `undefined` or `null` | `4` |
17
- | pointOpacity | Universal opacity value applied to all points. This value multiplies with individual point alpha values (if set via setPointColors). Useful for dynamically controlling opacity of all points without updating individual RGBA arrays. | `1.0` |
18
- | pointSizeScale | Scale factor for the point size | `1` |
19
- | hoveredPointCursor | Cursor style to use when hovering over a point | `auto` |
20
- | hoveredLinkCursor | Cursor style to use when hovering over a link | `auto` |
21
- | renderHoveredPointRing | Turns ring rendering around a point on hover on / off | `false` |
22
- | hoveredPointRingColor | Hovered point ring color hex value or an array of RGBA values | `white` |
23
- | focusedPointRingColor | Focused point ring color hex value or an array of RGBA values | `white` |
24
- | focusedPointIndex | Set focus on a point by index. A ring will be highlighted around the focused point. When set to `undefined`, no point is focused. | `undefined` |
25
- | renderLinks | Turns link rendering on / off | `true` |
26
- | linkColor | The default color to use for links when no link colors are provided, or if the color value in the array is `undefined` or `null`. This can be either a hex color string (e.g., '#666666') or an array of RGBA values in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255 | `#666666` |
27
- | linkOpacity | Universal opacity value applied to all links. This value multiplies with individual link alpha values (if set via setLinkColors). Useful for dynamically controlling opacity of all links without updating individual RGBA arrays. | `1.0` |
28
- | linkGreyoutOpacity | Greyed out link opacity value when the selection is active | `0.1` |
29
- | linkWidth | The default width value to use for links when no link widths are provided or if the width value in the array is `undefined` or `null` | `1` |
30
- | linkWidthScale | Scale factor for the link width | `1` |
31
- | hoveredLinkColor | The color to use for links when they are hovered. This can be either a hex color string (e.g., '#ff3333') or an array of RGBA values in the format `[red, green, blue, alpha]` where each value is a number between 0 and 255 | `undefined` |
32
- | hoveredLinkWidthIncrease | Number of pixels to add to the link width when hovered | `5` |
33
- | scaleLinksOnZoom | Increase/decrease link width when zooming | `false` |
34
- | curvedLinks | If set to true, links are rendered as curved lines. Otherwise as straight lines | `false` |
35
- | curvedLinkSegments | Number of segments in a curved line | `19` |
36
- | curvedLinkWeight | Weight affects the shape of the curve | `0.8` |
37
- | curvedLinkControlPointDistance | Defines the position of the control point of the curve on the normal from the centre of the line. If set to 1 then the control point is at a distance equal to the length of the line | `0.5` |
38
- | linkArrows | The default link arrow value that controls whether or not to display link arrows | `false` |
39
- | linkArrowsSizeScale | Scale factor for the link arrows size | `1` |
40
- | linkVisibilityDistanceRange | The range defines the minimum and maximum link visibility distance in pixels.<br /><br />The link will be fully opaque when its length is less than the first number in the array, and will have `linkVisibilityMinTransparency` transparency when its length is greater than the second number in the array.<br /><br />This distance is defined in screen space coordinates and will change as you zoom in and out (e.g. links become longer when you zoom in, and shorter when you zoom out). | `[50, 150]` |
41
- | linkVisibilityMinTransparency | The transparency value that the link will have when its length reaches the maximum link distance value from `linkVisibilityDistanceRange`. | `0.25` |
42
- | useClassicQuadtree | Use the classic [quadtree algorithm](https://en.wikipedia.org/wiki/Barnes%E2%80%93Hut_simulation) for the Many-Body force. This property will be applied only on component initialization and it can't be changed using the `setConfig` method.<br /><br /> ⚠ The algorithm might not work on some GPUs (e.g. Nvidia) and on Windows (unless you disable ANGLE in the browser settings). | `false` |
43
- | showFPSMonitor | Show WebGL performance monitor | `false` |
44
- | pixelRatio | Canvas pixel ratio | `2` |
45
- | scalePointsOnZoom | Increase/decrease point size when zooming | `false` |
46
- | initialZoomLevel | Initial zoom level (set once during initialization) | `undefined` |
47
- | enableZoom | Enables zooming interactions | `true` |
48
- | enableSimulationDuringZoom | Keep simulation running during zoom operations | `false` |
49
- | enableDrag | Enable/disable point dragging | `false` |
50
- | fitViewOnInit | Auto-zoom to fit all points on initialization | `true` |
51
- | fitViewDelay | Delay before fitting view when enabled in milliseconds | `250` |
52
- | fitViewPadding | Extra space around points when fitting view | `0.1` |
53
- | fitViewDuration | Animation duration for fit view operation in milliseconds | `250` |
54
- | fitViewByPointsInRect | When `fitViewOnInit` is set to `true`, fits the view to show the points within a rectangle defined by its two corner coordinates `[[left, bottom], [right, top]]` in the scene space | `undefined` |
55
- | fitViewByPointIndices | When `fitViewOnInit` is set to `true`, fits the view to show only the specified points by their indices. Takes precedence over `fitViewByPointsInRect` when both are provided. | `undefined` |
56
- | randomSeed | Providing a value allows control over layout randomness for consistency across simulations. Applied only on initialization | `undefined` |
57
- | pointSamplingDistance | Sampling density for point position methods (used in `getSampledPointPositionsMap`) in pixels | `150` |
58
- | attribution | Controls the text shown in the bottom right corner. Provide HTML content as a string for custom attribution. Empty string hides attribution | `''` |
59
- | rescalePositions | Control automatic point position adjustment. When undefined: auto-rescale if simulation disabled | `undefined` |
60
-
61
- **Notes:**
62
- - The attribution text color can be customized using CSS variable `--cosmosgl-attribution-color`.
63
- - Error message text color can be customized using CSS variable `--cosmosgl-error-message-color`.
64
-
65
- ## Simulation configuration
66
-
67
- cosmos.gl layout algorithm was inspired by the [d3-force](https://github.com/d3/d3-force#forces) simulation forces: Link, Many-Body, Gravitation, and Centering. It provides several simulation settings to adjust the layout. Each of them can be changed in real time, while the simulation is in progress.
68
-
69
- | Property | Description | Recommended range | Default |
70
- |---|---|---|---|
71
- | simulationDecay | Force simulation decay coefficient. <br /><br />Use smaller values if you want the simulation to "cool down" slower.| 100 – 10 000| `5000` |
72
- | simulationGravity | Gravity force coefficient | 0.0 – 1.0 | `0.25` |
73
- | simulationCenter | Centering force coefficient | 0.0 – 1.0 | `0.0` |
74
- | simulationRepulsion | Repulsion force coefficient | 0.0 – 2.0 | `1.0` |
75
- | simulationRepulsionTheta | Decreases / increases the detalization of the Many-Body force calculations. <br /><br /> When `useClassicQuadtree` is set to `true`, this property corresponds to the Barnes–Hut approximation criterion. | 0.3 – 2.0 | `1.15` |
76
- | simulationRepulsionQuadtreeLevels | Barnes–Hut approximation depth. <br /><br />Can only be used when `useClassicQuadtree` is set `true`. | 5 – 12 | `12` |
77
- | simulationLinkSpring | Link spring force coefficient | 0.0 – 2.0 | `1.0` |
78
- | simulationLinkDistance | Minimum link distance | 1 – 20 | `10` |
79
- | simulationLinkDistRandomVariationRange | Link distance randomness multiplier range | [0.8 – 1.2,<br/> 1.2 – 2.0] | `[1.0, 1.2]` |
80
- | simulationRepulsionFromMouse | Repulsion from the mouse pointer force coefficient. The repulsion force is activated by pressing the right mouse button. | 0.0 – 5.0 | `2.0`
81
- | enableRightClickRepulsion | Enable or disable the repulsion force from mouse when right-clicking. When set to `true`, holding the right mouse button will activate the mouse repulsion force. When set to `false`, right-clicking will not trigger any repulsion force. | - | `false` |
82
- | simulationFriction | Friction coefficient. Values range from `0` (high friction, stops quickly) to `1` (no friction, keeps moving). | 0.0 – 1.0 | `0.85` |
83
- | simulationCluster | Cluster coefficient | 0.0 – 1.0 | `0.1` |
84
-
85
- ## Event Callbacks
86
-
87
- | Callback | Description |
88
- |---|---|
89
- | onSimulationStart | Called when simulation starts |
90
- | onSimulationTick | Called on every simulation tick, with the current alpha value and hover information |
91
- | onSimulationEnd | Called when simulation stops |
92
- | onSimulationPause | Called when simulation pauses |
93
- | onSimulationUnpause | Called when simulation unpauses |
94
- | onSimulationRestart | **[DEPRECATED]** Called when simulation restarts. Use `onSimulationUnpause` instead |
95
- | onClick | Called on canvas click with point index and position |
96
- | onPointClick | Called when a point is clicked |
97
- | onLinkClick | Called when a link is clicked |
98
- | onBackgroundClick | Called when the background (empty space) is clicked |
99
- | onMouseMove | Called on mouse movement with hover info |
100
- | onPointMouseOver | Called when pointer enters a point |
101
- | onPointMouseOut | Called when pointer leaves a point |
102
- | onLinkMouseOver | Called when pointer enters a link |
103
- | onLinkMouseOut | Called when pointer leaves a link |
104
- | onZoomStart | Called when zoom/pan starts |
105
- | onZoom | Called during zoom/pan |
106
- | onZoomEnd | Called when zoom/pan ends |
107
- | onDragStart | Called when dragging starts |
108
- | onDrag | Called during dragging |
109
- | onDragEnd | Called when dragging ends |
110
-
111
- ---
112
- Copyright [OpenJS Foundation](https://openjsf.org) and cosmos.gl contributors. All rights reserved. The [OpenJS Foundation](https://openjsf.org) has registered trademarks and uses trademarks. For a list of trademarks of the [OpenJS Foundation](https://openjsf.org), please see our [Trademark Policy](https://trademark-policy.openjsf.org/) and [Trademark List](https://trademark-list.openjsf.org/). Trademarks and logos not indicated on the [list of OpenJS Foundation trademarks](https://trademark-list.openjsf.org) are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
113
- [The OpenJS Foundation](https://openjsf.org/) | [Terms of Use](https://terms-of-use.openjsf.org/) | [Privacy Policy](https://privacy-policy.openjsf.org/) | [Bylaws](https://bylaws.openjsf.org/) | [Code of Conduct](https://code-of-conduct.openjsf.org) | [Trademark Policy](https://trademark-policy.openjsf.org/) | [Trademark List](https://trademark-list.openjsf.org/) | [Cookie Policy](https://www.linuxfoundation.org/cookies/)