@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,143 +0,0 @@
|
|
|
1
|
-
import './style.css'
|
|
2
|
-
|
|
3
|
-
export class PolygonSelection {
|
|
4
|
-
private canvas: HTMLCanvasElement
|
|
5
|
-
private ctx: CanvasRenderingContext2D
|
|
6
|
-
private isDrawing = false
|
|
7
|
-
private points: Array<{ x: number; y: number }> = []
|
|
8
|
-
private graphDiv: HTMLElement
|
|
9
|
-
private onPolygonComplete?: (points: [number, number][]) => void
|
|
10
|
-
private boundStartDrawing: (e: MouseEvent) => void
|
|
11
|
-
private boundDraw: (e: MouseEvent) => void
|
|
12
|
-
private boundStopDrawing: () => void
|
|
13
|
-
private resizeObserver: ResizeObserver
|
|
14
|
-
|
|
15
|
-
public constructor (graphDiv: HTMLElement, onPolygonComplete?: (points: [number, number][]) => void) {
|
|
16
|
-
this.graphDiv = graphDiv
|
|
17
|
-
this.onPolygonComplete = onPolygonComplete
|
|
18
|
-
|
|
19
|
-
// Bind event handlers
|
|
20
|
-
this.boundStartDrawing = this.startDrawing.bind(this)
|
|
21
|
-
this.boundDraw = this.draw.bind(this)
|
|
22
|
-
this.boundStopDrawing = this.stopDrawing.bind(this)
|
|
23
|
-
|
|
24
|
-
// Create canvas
|
|
25
|
-
this.canvas = document.createElement('canvas')
|
|
26
|
-
this.canvas.className = 'polygon-canvas'
|
|
27
|
-
|
|
28
|
-
const ctx = this.canvas.getContext('2d')
|
|
29
|
-
if (!ctx) throw new Error('Could not get canvas context')
|
|
30
|
-
this.ctx = ctx
|
|
31
|
-
|
|
32
|
-
this.graphDiv.appendChild(this.canvas)
|
|
33
|
-
|
|
34
|
-
this.resizeObserver = new ResizeObserver(() => {
|
|
35
|
-
this.resizeCanvas()
|
|
36
|
-
})
|
|
37
|
-
this.resizeObserver.observe(this.graphDiv)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
public enablePolygonMode (): void {
|
|
41
|
-
this.canvas.style.pointerEvents = 'auto'
|
|
42
|
-
this.canvas.style.cursor = 'crosshair'
|
|
43
|
-
|
|
44
|
-
// Add event listeners
|
|
45
|
-
this.canvas.addEventListener('mousedown', this.boundStartDrawing)
|
|
46
|
-
this.canvas.addEventListener('mousemove', this.boundDraw)
|
|
47
|
-
this.canvas.addEventListener('mouseup', this.boundStopDrawing)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
public disablePolygonMode (): void {
|
|
51
|
-
this.canvas.style.pointerEvents = 'none'
|
|
52
|
-
this.canvas.style.cursor = 'default'
|
|
53
|
-
|
|
54
|
-
// Remove event listeners
|
|
55
|
-
this.canvas.removeEventListener('mousedown', this.boundStartDrawing)
|
|
56
|
-
this.canvas.removeEventListener('mousemove', this.boundDraw)
|
|
57
|
-
this.canvas.removeEventListener('mouseup', this.boundStopDrawing)
|
|
58
|
-
|
|
59
|
-
// Clear canvas
|
|
60
|
-
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public destroy (): void {
|
|
64
|
-
this.disablePolygonMode()
|
|
65
|
-
this.resizeObserver.disconnect()
|
|
66
|
-
if (this.canvas.parentNode) {
|
|
67
|
-
this.canvas.parentNode.removeChild(this.canvas)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private resizeCanvas (): void {
|
|
72
|
-
const rect = this.graphDiv.getBoundingClientRect()
|
|
73
|
-
|
|
74
|
-
// Apply pixel ratio for crisp rendering
|
|
75
|
-
const pixelRatio = window.devicePixelRatio || 1
|
|
76
|
-
this.canvas.width = rect.width * pixelRatio
|
|
77
|
-
this.canvas.height = rect.height * pixelRatio
|
|
78
|
-
|
|
79
|
-
// Reset transform and scale the context to match the pixel ratio
|
|
80
|
-
this.ctx.resetTransform()
|
|
81
|
-
this.ctx.scale(pixelRatio, pixelRatio)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private startDrawing (e: MouseEvent): void {
|
|
85
|
-
this.isDrawing = true
|
|
86
|
-
this.points = []
|
|
87
|
-
const rect = this.canvas.getBoundingClientRect()
|
|
88
|
-
this.points.push({ x: e.clientX - rect.left, y: e.clientY - rect.top })
|
|
89
|
-
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private draw (e: MouseEvent): void {
|
|
93
|
-
if (!this.isDrawing) return
|
|
94
|
-
|
|
95
|
-
const rect = this.canvas.getBoundingClientRect()
|
|
96
|
-
this.points.push({ x: e.clientX - rect.left, y: e.clientY - rect.top })
|
|
97
|
-
|
|
98
|
-
// Clear the entire canvas accounting for pixel ratio
|
|
99
|
-
const pixelRatio = window.devicePixelRatio || 1
|
|
100
|
-
this.ctx.clearRect(0, 0, this.canvas.width / pixelRatio, this.canvas.height / pixelRatio)
|
|
101
|
-
|
|
102
|
-
this.ctx.beginPath()
|
|
103
|
-
if (this.points.length > 0 && this.points[0]) {
|
|
104
|
-
this.ctx.moveTo(this.points[0].x, this.points[0].y)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
for (let i = 1; i < this.points.length; i++) {
|
|
108
|
-
const point = this.points[i]
|
|
109
|
-
if (point) {
|
|
110
|
-
this.ctx.lineTo(point.x, point.y)
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
this.ctx.strokeStyle = '#ffffff'
|
|
115
|
-
this.ctx.lineWidth = 2
|
|
116
|
-
this.ctx.stroke()
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
private stopDrawing (): void {
|
|
120
|
-
if (!this.isDrawing) return
|
|
121
|
-
this.isDrawing = false
|
|
122
|
-
|
|
123
|
-
if (this.points.length > 2) {
|
|
124
|
-
this.ctx.closePath()
|
|
125
|
-
this.ctx.stroke()
|
|
126
|
-
|
|
127
|
-
const polygonPoints: [number, number][] = this.points.map(p => [p.x, p.y])
|
|
128
|
-
const firstPolygonPoint = polygonPoints[0]
|
|
129
|
-
const lastPolygonPoint = polygonPoints[polygonPoints.length - 1]
|
|
130
|
-
if (firstPolygonPoint && lastPolygonPoint && (firstPolygonPoint[0] !== lastPolygonPoint[0] || firstPolygonPoint[1] !== lastPolygonPoint[1])) {
|
|
131
|
-
polygonPoints.push(firstPolygonPoint)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (this.onPolygonComplete) {
|
|
135
|
-
this.onPolygonComplete(polygonPoints)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const pixelRatio = window.devicePixelRatio || 1
|
|
140
|
-
this.ctx.clearRect(0, 0, this.canvas.width / pixelRatio, this.canvas.height / pixelRatio)
|
|
141
|
-
this.disablePolygonMode()
|
|
142
|
-
}
|
|
143
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
3
|
-
import { createCosmos } from '../create-cosmos'
|
|
4
|
-
import { generateMeshData } from '../generate-mesh-data'
|
|
5
|
-
|
|
6
|
-
export const radial = (): { graph: Graph; div: HTMLDivElement} => {
|
|
7
|
-
const {
|
|
8
|
-
pointPositions, pointColors, pointSizes,
|
|
9
|
-
links, linkColors, linkWidths,
|
|
10
|
-
pointClusters, clusterPositions, clusterStrength,
|
|
11
|
-
} = generateMeshData(100, 100, 100, 1.0)
|
|
12
|
-
|
|
13
|
-
return createCosmos({
|
|
14
|
-
pointPositions,
|
|
15
|
-
pointColors,
|
|
16
|
-
pointSizes,
|
|
17
|
-
pointClusters,
|
|
18
|
-
links,
|
|
19
|
-
linkColors,
|
|
20
|
-
linkWidths,
|
|
21
|
-
clusterPositions,
|
|
22
|
-
clusterStrength,
|
|
23
|
-
})
|
|
24
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
import { createClusterLabels } from '../create-cluster-labels'
|
|
3
|
-
import { createCosmos } from '../create-cosmos'
|
|
4
|
-
import { generateMeshData } from '../generate-mesh-data'
|
|
5
|
-
|
|
6
|
-
export const withLabels = (): {div: HTMLDivElement; graph: Graph; destroy: () => void } => {
|
|
7
|
-
let nClusters = 2
|
|
8
|
-
const { pointPositions, pointColors, pointClusters } = generateMeshData(100, 100, nClusters, 1.0)
|
|
9
|
-
|
|
10
|
-
const { div, graph } = createCosmos({
|
|
11
|
-
pointPositions,
|
|
12
|
-
pointColors,
|
|
13
|
-
pointClusters,
|
|
14
|
-
simulationGravity: 2,
|
|
15
|
-
simulationCluster: 0.25,
|
|
16
|
-
simulationRepulsion: 10,
|
|
17
|
-
pointSize: 10,
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
const updateClusterLabels = createClusterLabels({ div })
|
|
21
|
-
graph.setZoomLevel(0.3)
|
|
22
|
-
|
|
23
|
-
graph.setConfig({
|
|
24
|
-
onZoom: updateClusterLabels.bind(this, graph),
|
|
25
|
-
onSimulationTick: updateClusterLabels.bind(this, graph),
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
let increasing = true
|
|
29
|
-
const interval = setInterval(() => {
|
|
30
|
-
if (increasing) {
|
|
31
|
-
nClusters += 5
|
|
32
|
-
if (nClusters >= 15) {
|
|
33
|
-
increasing = false
|
|
34
|
-
}
|
|
35
|
-
} else {
|
|
36
|
-
nClusters -= 5
|
|
37
|
-
if (nClusters <= 2) {
|
|
38
|
-
increasing = true
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const nextData = generateMeshData(100, 100, nClusters, 1.0)
|
|
43
|
-
graph.setPointClusters(nextData.pointClusters)
|
|
44
|
-
graph.setPointColors(nextData.pointColors)
|
|
45
|
-
graph.render(1)
|
|
46
|
-
}, 1500)
|
|
47
|
-
|
|
48
|
-
const destroy = (): void => {
|
|
49
|
-
clearInterval(interval)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return { div, graph, destroy }
|
|
53
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
3
|
-
import { createCosmos } from '../create-cosmos'
|
|
4
|
-
import { generateMeshData } from '../generate-mesh-data'
|
|
5
|
-
|
|
6
|
-
export const worm = (): {graph: Graph; div: HTMLDivElement} => {
|
|
7
|
-
const { pointPositions, pointColors, links, linkColors, pointClusters } = generateMeshData(100, 100, 1000, 1.0)
|
|
8
|
-
|
|
9
|
-
const { div, graph } = createCosmos({
|
|
10
|
-
simulationGravity: 0.5,
|
|
11
|
-
simulationRepulsion: 1,
|
|
12
|
-
simulationLinkSpring: 1,
|
|
13
|
-
pointPositions,
|
|
14
|
-
pointColors,
|
|
15
|
-
pointClusters,
|
|
16
|
-
links,
|
|
17
|
-
linkColors,
|
|
18
|
-
onSimulationTick: () => {
|
|
19
|
-
const currentPointColors = graph.getPointColors()
|
|
20
|
-
const newPointColors = new Float32Array(currentPointColors.length)
|
|
21
|
-
for (let i = 0; i < currentPointColors.length / 4; i++) {
|
|
22
|
-
if (i === 0) {
|
|
23
|
-
newPointColors[i * 4] = currentPointColors[currentPointColors.length - 4] as number
|
|
24
|
-
newPointColors[i * 4 + 1] = currentPointColors[currentPointColors.length - 3] as number
|
|
25
|
-
newPointColors[i * 4 + 2] = currentPointColors[currentPointColors.length - 2] as number
|
|
26
|
-
newPointColors[i * 4 + 3] = currentPointColors[currentPointColors.length - 1] as number
|
|
27
|
-
} else {
|
|
28
|
-
newPointColors[i * 4] = currentPointColors[(i - 1) * 4] as number
|
|
29
|
-
newPointColors[i * 4 + 1] = currentPointColors[(i - 1) * 4 + 1] as number
|
|
30
|
-
newPointColors[i * 4 + 2] = currentPointColors[(i - 1) * 4 + 2] as number
|
|
31
|
-
newPointColors[i * 4 + 3] = currentPointColors[(i - 1) * 4 + 3] as number
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
graph.setPointColors(newPointColors)
|
|
35
|
-
graph.render()
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
return { div, graph }
|
|
40
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import type { Meta } from '@storybook/html'
|
|
2
|
-
import { CosmosStoryProps } from '@/graph/stories/create-cosmos'
|
|
3
|
-
import { createStory, Story } from '@/graph/stories/create-story'
|
|
4
|
-
import { withLabels } from './clusters/with-labels'
|
|
5
|
-
import { worm } from './clusters/worm'
|
|
6
|
-
import { radial } from './clusters/radial'
|
|
7
|
-
import { polygonSelection } from './clusters/polygon-selection'
|
|
8
|
-
|
|
9
|
-
import createCosmosRaw from './create-cosmos?raw'
|
|
10
|
-
import generateMeshDataRaw from './generate-mesh-data?raw'
|
|
11
|
-
import withLabelsStoryRaw from './clusters/with-labels?raw'
|
|
12
|
-
import createClusterLabelsRaw from './create-cluster-labels?raw'
|
|
13
|
-
import wormStory from './clusters/worm?raw'
|
|
14
|
-
import radialStory from './clusters/radial?raw'
|
|
15
|
-
import polygonSelectionStory from './clusters/polygon-selection?raw'
|
|
16
|
-
import polygonSelectionStyleRaw from './clusters/polygon-selection/style.css?raw'
|
|
17
|
-
import polygonSelectionPolygonRaw from './clusters/polygon-selection/polygon.ts?raw'
|
|
18
|
-
|
|
19
|
-
const meta: Meta<CosmosStoryProps> = {
|
|
20
|
-
title: 'Examples/Clusters',
|
|
21
|
-
parameters: {
|
|
22
|
-
controls: {
|
|
23
|
-
disable: true,
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const sourceCodeAddonParams = [
|
|
29
|
-
{ name: 'create-cosmos', code: createCosmosRaw },
|
|
30
|
-
{ name: 'generate-mesh-data', code: generateMeshDataRaw },
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
export const Worm: Story = {
|
|
34
|
-
...createStory(worm),
|
|
35
|
-
parameters: {
|
|
36
|
-
sourceCode: [
|
|
37
|
-
{ name: 'Story', code: wormStory },
|
|
38
|
-
...sourceCodeAddonParams,
|
|
39
|
-
],
|
|
40
|
-
},
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export const Radial: Story = {
|
|
44
|
-
...createStory(radial),
|
|
45
|
-
parameters: {
|
|
46
|
-
sourceCode: [
|
|
47
|
-
{ name: 'Story', code: radialStory },
|
|
48
|
-
...sourceCodeAddonParams,
|
|
49
|
-
],
|
|
50
|
-
},
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export const WithLabels: Story = {
|
|
54
|
-
...createStory(withLabels),
|
|
55
|
-
parameters: {
|
|
56
|
-
sourceCode: [
|
|
57
|
-
{ name: 'Story', code: withLabelsStoryRaw },
|
|
58
|
-
{ name: 'create-cluster-labels', code: createClusterLabelsRaw },
|
|
59
|
-
...sourceCodeAddonParams,
|
|
60
|
-
],
|
|
61
|
-
},
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export const PolygonSelection: Story = {
|
|
65
|
-
...createStory(polygonSelection),
|
|
66
|
-
parameters: {
|
|
67
|
-
sourceCode: [
|
|
68
|
-
{ name: 'Story', code: polygonSelectionStory },
|
|
69
|
-
{ name: 'polygon.ts', code: polygonSelectionPolygonRaw },
|
|
70
|
-
...sourceCodeAddonParams,
|
|
71
|
-
{ name: 'style.css', code: polygonSelectionStyleRaw },
|
|
72
|
-
],
|
|
73
|
-
},
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// eslint-disable-next-line import/no-default-export
|
|
77
|
-
export default meta
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
|
|
3
|
-
export const createClusterLabels = (props: { div: HTMLDivElement }): (graph: Graph) => void => {
|
|
4
|
-
const clusterLabelDivs: HTMLDivElement[] = []
|
|
5
|
-
return function updateClusterLabels (graph: Graph): void {
|
|
6
|
-
const clusterPositions = graph.getClusterPositions()
|
|
7
|
-
const nClusters = clusterPositions.length / 2
|
|
8
|
-
if (nClusters === 0) return
|
|
9
|
-
if (clusterLabelDivs.length !== nClusters) {
|
|
10
|
-
clusterLabelDivs.forEach((div) => div.remove())
|
|
11
|
-
for (let i = 0; i < nClusters; i++) {
|
|
12
|
-
const clusterLabelDiv = document.createElement('div')
|
|
13
|
-
const contentLabel = document.createElement('p')
|
|
14
|
-
clusterLabelDiv.appendChild(contentLabel)
|
|
15
|
-
clusterLabelDiv.style.position = 'absolute'
|
|
16
|
-
clusterLabelDiv.style.pointerEvents = 'none'
|
|
17
|
-
|
|
18
|
-
contentLabel.style.fontFamily = [
|
|
19
|
-
'"Nunito Sans"',
|
|
20
|
-
'-apple-system',
|
|
21
|
-
'".SFNSText-Regular"',
|
|
22
|
-
'"San Francisco"',
|
|
23
|
-
'BlinkMacSystemFont',
|
|
24
|
-
'"Segoe UI"',
|
|
25
|
-
'"Helvetica Neue"',
|
|
26
|
-
'Helvetica',
|
|
27
|
-
'Arial',
|
|
28
|
-
'sans-serif',
|
|
29
|
-
].join(', ')
|
|
30
|
-
contentLabel.style.fontWeight = 'bold'
|
|
31
|
-
contentLabel.style.color = 'white'
|
|
32
|
-
contentLabel.style.transform = 'translate(-50%, -100%)'
|
|
33
|
-
contentLabel.innerText = `Cluster ${i + 1}`
|
|
34
|
-
|
|
35
|
-
props.div.appendChild(clusterLabelDiv)
|
|
36
|
-
clusterLabelDivs[i] = clusterLabelDiv
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
for (let i = 0; i < nClusters; i++) {
|
|
41
|
-
const clusterPosition = clusterPositions.slice(i * 2, i * 2 + 2)
|
|
42
|
-
const x = clusterPosition[0]
|
|
43
|
-
const y = clusterPosition[1]
|
|
44
|
-
const clusterLabelDiv = clusterLabelDivs[i] as HTMLDivElement
|
|
45
|
-
const screenXY = graph.spaceToScreenPosition([x ?? 0, y ?? 0])
|
|
46
|
-
clusterLabelDiv.style.top = `${screenXY[1]}px`
|
|
47
|
-
clusterLabelDiv.style.left = `${screenXY[0]}px`
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { Graph, GraphConfigInterface } from '@cosmos.gl/graph'
|
|
2
|
-
|
|
3
|
-
export type CosmosStoryProps = GraphConfigInterface & {
|
|
4
|
-
pointPositions: Float32Array;
|
|
5
|
-
pointColors?: Float32Array;
|
|
6
|
-
pointSizes?: Float32Array;
|
|
7
|
-
|
|
8
|
-
links?: Float32Array;
|
|
9
|
-
linkColors?: Float32Array;
|
|
10
|
-
linkWidths?: Float32Array;
|
|
11
|
-
// linkStrength?: Float32Array;
|
|
12
|
-
|
|
13
|
-
pointClusters?: number[];
|
|
14
|
-
clusterPositions?: number[];
|
|
15
|
-
clusterStrength?: Float32Array;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const createCosmos = (props: CosmosStoryProps): { div: HTMLDivElement; graph: Graph} => {
|
|
19
|
-
const div = document.createElement('div')
|
|
20
|
-
div.style.height = '100vh'
|
|
21
|
-
div.style.width = '100%'
|
|
22
|
-
|
|
23
|
-
const config: GraphConfigInterface = {
|
|
24
|
-
backgroundColor: '#2d313a',
|
|
25
|
-
pointSize: 3,
|
|
26
|
-
pointDefaultColor: '#4B5BBF',
|
|
27
|
-
pointGreyoutOpacity: 0.1,
|
|
28
|
-
scalePointsOnZoom: true,
|
|
29
|
-
linkWidth: 0.8,
|
|
30
|
-
linkColor: '#5F74C2',
|
|
31
|
-
linkArrows: false,
|
|
32
|
-
linkGreyoutOpacity: 0,
|
|
33
|
-
curvedLinks: true,
|
|
34
|
-
renderLinks: true,
|
|
35
|
-
renderHoveredPointRing: true,
|
|
36
|
-
fitViewOnInit: false,
|
|
37
|
-
hoveredPointRingColor: '#4B5BBF',
|
|
38
|
-
enableDrag: true,
|
|
39
|
-
simulationLinkDistance: 1,
|
|
40
|
-
simulationLinkSpring: 2,
|
|
41
|
-
simulationRepulsion: 0.5,
|
|
42
|
-
simulationGravity: 0.02,
|
|
43
|
-
simulationFriction: 0.7,
|
|
44
|
-
simulationDecay: 10000000,
|
|
45
|
-
attribution: 'visualized with <a href="https://cosmograph.app/" style="color: var(--cosmosgl-attribution-color);" target="_blank">Cosmograph</a>',
|
|
46
|
-
...props,
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const graph = new Graph(div, config)
|
|
50
|
-
|
|
51
|
-
graph.setPointPositions(props.pointPositions)
|
|
52
|
-
if (props.pointColors) graph.setPointColors(props.pointColors)
|
|
53
|
-
if (props.pointSizes) graph.setPointSizes(props.pointSizes)
|
|
54
|
-
|
|
55
|
-
if (props.links) graph.setLinks(props.links)
|
|
56
|
-
if (props.linkColors) graph.setLinkColors(props.linkColors)
|
|
57
|
-
if (props.linkWidths) graph.setLinkWidths(props.linkWidths)
|
|
58
|
-
// if (props.linkStrength) graph.setLinkStrength(props.linkStrength)
|
|
59
|
-
|
|
60
|
-
if (props.pointClusters) graph.setPointClusters(props.pointClusters)
|
|
61
|
-
if (props.clusterPositions) graph.setClusterPositions(props.clusterPositions)
|
|
62
|
-
if (props.clusterStrength) graph.setPointClusterStrength(props.clusterStrength)
|
|
63
|
-
|
|
64
|
-
graph.zoom(0.9)
|
|
65
|
-
graph.render()
|
|
66
|
-
|
|
67
|
-
return { div, graph }
|
|
68
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
import type { StoryObj } from '@storybook/html'
|
|
3
|
-
import { CosmosStoryProps } from '@/graph/stories/create-cosmos'
|
|
4
|
-
|
|
5
|
-
export type Story = StoryObj<CosmosStoryProps & { graph: Graph; destroy?: () => void }>;
|
|
6
|
-
|
|
7
|
-
export const createStory: (storyFunction: () => {
|
|
8
|
-
graph: Graph;
|
|
9
|
-
div: HTMLDivElement;
|
|
10
|
-
destroy?: () => void;
|
|
11
|
-
} | Promise<{
|
|
12
|
-
graph: Graph;
|
|
13
|
-
div: HTMLDivElement;
|
|
14
|
-
destroy?: () => void;
|
|
15
|
-
}>) => Story = (storyFunction) => ({
|
|
16
|
-
async beforeEach (d): Promise<() => void> {
|
|
17
|
-
return (): void => {
|
|
18
|
-
d.args.destroy?.()
|
|
19
|
-
d.args.graph?.destroy()
|
|
20
|
-
}
|
|
21
|
-
},
|
|
22
|
-
render: (args): HTMLDivElement => {
|
|
23
|
-
const result = storyFunction()
|
|
24
|
-
|
|
25
|
-
if (result instanceof Promise) {
|
|
26
|
-
// For async story functions, create a simple div and update it when ready
|
|
27
|
-
const div = document.createElement('div')
|
|
28
|
-
div.style.height = '100vh'
|
|
29
|
-
div.style.width = '100%'
|
|
30
|
-
div.innerHTML = '<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: #666;">Loading story...</div>'
|
|
31
|
-
|
|
32
|
-
result.then((story) => {
|
|
33
|
-
args.graph = story.graph
|
|
34
|
-
args.destroy = story.destroy
|
|
35
|
-
// Replace the content with the actual story div
|
|
36
|
-
div.innerHTML = ''
|
|
37
|
-
div.appendChild(story.div)
|
|
38
|
-
}).catch((error) => {
|
|
39
|
-
console.error('Failed to load story:', error)
|
|
40
|
-
div.innerHTML = '<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: #ff0000;">Failed to load story</div>'
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
return div
|
|
44
|
-
} else {
|
|
45
|
-
// Synchronous story function
|
|
46
|
-
args.graph = result.graph
|
|
47
|
-
args.destroy = result.destroy
|
|
48
|
-
return result.div
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
})
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
import { createCosmos } from '../create-cosmos'
|
|
3
|
-
import { generateMeshData } from '../generate-mesh-data'
|
|
4
|
-
|
|
5
|
-
export const fullMesh = (): { graph: Graph; div: HTMLDivElement} => {
|
|
6
|
-
const { pointPositions, links, pointColors } = generateMeshData(40, 30, 15, 1.0)
|
|
7
|
-
|
|
8
|
-
return createCosmos({
|
|
9
|
-
pointPositions,
|
|
10
|
-
links,
|
|
11
|
-
pointColors,
|
|
12
|
-
})
|
|
13
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
import { createCosmos } from '../create-cosmos'
|
|
3
|
-
import { generateMeshData } from '../generate-mesh-data'
|
|
4
|
-
|
|
5
|
-
export const meshWithHoles = (): { graph: Graph; div: HTMLDivElement} => {
|
|
6
|
-
const { pointPositions, links, pointColors } = generateMeshData(40, 80, 15, 0.8)
|
|
7
|
-
|
|
8
|
-
return createCosmos({
|
|
9
|
-
pointPositions,
|
|
10
|
-
links,
|
|
11
|
-
pointColors,
|
|
12
|
-
})
|
|
13
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import type { Meta } from '@storybook/html'
|
|
2
|
-
|
|
3
|
-
import { createStory, Story } from '@/graph/stories/create-story'
|
|
4
|
-
import { CosmosStoryProps } from './create-cosmos'
|
|
5
|
-
import { meshWithHoles } from './experiments/mesh-with-holes'
|
|
6
|
-
import { fullMesh } from './experiments/full-mesh'
|
|
7
|
-
|
|
8
|
-
import createCosmosRaw from './create-cosmos?raw'
|
|
9
|
-
import generateMeshDataRaw from './generate-mesh-data?raw'
|
|
10
|
-
import meshWithHolesRaw from './experiments/mesh-with-holes?raw'
|
|
11
|
-
import fullMeshRaw from './experiments/full-mesh?raw'
|
|
12
|
-
|
|
13
|
-
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
|
|
14
|
-
const meta: Meta<CosmosStoryProps> = {
|
|
15
|
-
title: 'Examples/Experiments',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const sourceCodeAddonParams = [
|
|
19
|
-
{ name: 'create-cosmos', code: createCosmosRaw },
|
|
20
|
-
{ name: 'generate-mesh-data', code: generateMeshDataRaw },
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
export const FullMesh: Story = {
|
|
24
|
-
...createStory(fullMesh),
|
|
25
|
-
parameters: {
|
|
26
|
-
sourceCode: [
|
|
27
|
-
{ name: 'Story', code: fullMeshRaw },
|
|
28
|
-
...sourceCodeAddonParams,
|
|
29
|
-
],
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
export const MeshWithHoles: Story = {
|
|
33
|
-
...createStory(meshWithHoles),
|
|
34
|
-
parameters: {
|
|
35
|
-
sourceCode: [
|
|
36
|
-
{ name: 'Story', code: meshWithHolesRaw },
|
|
37
|
-
...sourceCodeAddonParams,
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// eslint-disable-next-line import/no-default-export
|
|
43
|
-
export default meta
|