@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,61 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
import { generateData } from './data-gen'
|
|
3
|
-
|
|
4
|
-
export const pinnedPoints = (): { graph: Graph; div: HTMLDivElement} => {
|
|
5
|
-
const div = document.createElement('div')
|
|
6
|
-
div.style.height = '100vh'
|
|
7
|
-
div.style.width = '100%'
|
|
8
|
-
div.style.position = 'relative'
|
|
9
|
-
|
|
10
|
-
const infoPanel = document.createElement('div')
|
|
11
|
-
infoPanel.textContent = 'White points are pinned. Try to move them.'
|
|
12
|
-
Object.assign(infoPanel.style, {
|
|
13
|
-
position: 'absolute',
|
|
14
|
-
top: '20px',
|
|
15
|
-
left: '20px',
|
|
16
|
-
color: 'white',
|
|
17
|
-
fontSize: '14px',
|
|
18
|
-
})
|
|
19
|
-
div.appendChild(infoPanel)
|
|
20
|
-
|
|
21
|
-
const graph = new Graph(div, {
|
|
22
|
-
spaceSize: 4096,
|
|
23
|
-
backgroundColor: '#2d313a',
|
|
24
|
-
curvedLinks: true,
|
|
25
|
-
enableDrag: true,
|
|
26
|
-
simulationLinkSpring: 3.1,
|
|
27
|
-
simulationRepulsion: 150,
|
|
28
|
-
simulationGravity: 0.05,
|
|
29
|
-
simulationDecay: 10000000,
|
|
30
|
-
attribution: 'visualized with <a href="https://cosmograph.app/" style="color: var(--cosmosgl-attribution-color);" target="_blank">Cosmograph</a>',
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const { pointPositions, links, pointColors } = generateData(100)
|
|
34
|
-
|
|
35
|
-
const pinnedIndices = [0, 1, 2, 3, 4, 5]
|
|
36
|
-
const numPoints = pointPositions.length / 2
|
|
37
|
-
|
|
38
|
-
const colors = new Float32Array(pointColors)
|
|
39
|
-
for (const pinnedIndex of pinnedIndices) {
|
|
40
|
-
colors[pinnedIndex * 4] = 1.0
|
|
41
|
-
colors[pinnedIndex * 4 + 1] = 1.0
|
|
42
|
-
colors[pinnedIndex * 4 + 2] = 1.0
|
|
43
|
-
colors[pinnedIndex * 4 + 3] = 1.0
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const pointSizes = new Float32Array(numPoints).fill(12)
|
|
47
|
-
for (const pinnedIndex of pinnedIndices) {
|
|
48
|
-
pointSizes[pinnedIndex] = 30
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
graph.setPointPositions(pointPositions)
|
|
52
|
-
graph.setPointColors(colors)
|
|
53
|
-
graph.setPointSizes(pointSizes)
|
|
54
|
-
graph.setLinks(links)
|
|
55
|
-
graph.setPinnedPoints(pinnedIndices)
|
|
56
|
-
|
|
57
|
-
graph.zoom(0.8)
|
|
58
|
-
graph.render()
|
|
59
|
-
|
|
60
|
-
return { div, graph }
|
|
61
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
function getRandom (min: number, max: number): number {
|
|
2
|
-
return Math.random() * (max - min) + min
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const pointsToShowLabelsFor = [
|
|
6
|
-
'Drury Lane Theatre',
|
|
7
|
-
"King's Theatre",
|
|
8
|
-
"Lincoln's Inn Fields",
|
|
9
|
-
"Goodman's Fields",
|
|
10
|
-
'Haymarket Theatre',
|
|
11
|
-
'Covent Garden',
|
|
12
|
-
'Bartholomew Fair',
|
|
13
|
-
'Southwark Fair',
|
|
14
|
-
'Pantheon, Oxford Street',
|
|
15
|
-
]
|
|
16
|
-
|
|
17
|
-
export const processPerformances = (performances: {
|
|
18
|
-
theaterCode: string;
|
|
19
|
-
performanceTitle: string;
|
|
20
|
-
theaterName: string;
|
|
21
|
-
}[]): { pointPositions: Float32Array; pointColors: Float32Array; pointSizes: Float32Array; pointLabelToIndex: Map<string, number>; pointIndexToLabel: Map<number, string>; links: Float32Array } => {
|
|
22
|
-
const pointLabelToIndex = new Map<string, number>()
|
|
23
|
-
const pointIndexToLabel = new Map<number, string>()
|
|
24
|
-
const pointPositions: number[] = []
|
|
25
|
-
const pointColors: number[] = []
|
|
26
|
-
const pointSizes: number[] = []
|
|
27
|
-
|
|
28
|
-
Array.from(
|
|
29
|
-
new Set([
|
|
30
|
-
...performances.map((p) => `P:${p.performanceTitle}`),
|
|
31
|
-
...performances.map((p) => p.theaterName),
|
|
32
|
-
])
|
|
33
|
-
).forEach((point, index) => {
|
|
34
|
-
pointLabelToIndex.set(point, index)
|
|
35
|
-
pointIndexToLabel.set(index, point)
|
|
36
|
-
pointPositions.push(4096 * getRandom(0.495, 0.505)) // x
|
|
37
|
-
pointPositions.push(4096 * getRandom(0.495, 0.505)) // y
|
|
38
|
-
if (point.indexOf('P:') === 0) {
|
|
39
|
-
// #4B5BBF
|
|
40
|
-
pointColors.push(75 / 256) // r
|
|
41
|
-
pointColors.push(91 / 256) // g
|
|
42
|
-
pointColors.push(191 / 256) // b
|
|
43
|
-
pointColors.push(1) // a
|
|
44
|
-
} else {
|
|
45
|
-
// #ED69B4
|
|
46
|
-
pointColors.push(237 / 256) // r
|
|
47
|
-
pointColors.push(105 / 256) // g
|
|
48
|
-
pointColors.push(180 / 256) // b
|
|
49
|
-
pointColors.push(1) // a
|
|
50
|
-
}
|
|
51
|
-
pointSizes.push(pointsToShowLabelsFor.includes(point) ? 8 : 2)
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
const links = performances
|
|
55
|
-
.map((p) => {
|
|
56
|
-
const theaterIndex = pointLabelToIndex.get(p.theaterName)
|
|
57
|
-
const performanceIndex = pointLabelToIndex.get(`P:${p.performanceTitle}`)
|
|
58
|
-
if (theaterIndex === undefined || performanceIndex === undefined) {
|
|
59
|
-
return []
|
|
60
|
-
}
|
|
61
|
-
return [theaterIndex, performanceIndex]
|
|
62
|
-
})
|
|
63
|
-
.flat()
|
|
64
|
-
|
|
65
|
-
return {
|
|
66
|
-
pointPositions: new Float32Array(pointPositions),
|
|
67
|
-
pointColors: new Float32Array(pointColors),
|
|
68
|
-
pointSizes: new Float32Array(pointSizes),
|
|
69
|
-
pointLabelToIndex,
|
|
70
|
-
pointIndexToLabel,
|
|
71
|
-
links: new Float32Array(links),
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
import { CosmosLabels } from './labels'
|
|
3
|
-
import { processPerformances, pointsToShowLabelsFor } from './data'
|
|
4
|
-
import './style.css'
|
|
5
|
-
|
|
6
|
-
// Load data from Github Gist and use it as `performances` argument for `PointLabelsStory`:
|
|
7
|
-
// const data = await fetch('https://gist.githubusercontent.com/Stukova/e6c4c7777e0166431a983999213f10c8/raw/performances.json')
|
|
8
|
-
// const performances = await data.json()
|
|
9
|
-
|
|
10
|
-
export const pointLabels = (
|
|
11
|
-
performances: {
|
|
12
|
-
theaterCode: string;
|
|
13
|
-
performanceTitle: string;
|
|
14
|
-
theaterName: string;
|
|
15
|
-
}[]
|
|
16
|
-
): { graph: Graph; div: HTMLDivElement} => {
|
|
17
|
-
const { pointPositions, pointColors, pointSizes, links, pointIndexToLabel, pointLabelToIndex } = processPerformances(performances)
|
|
18
|
-
const div = document.createElement('div')
|
|
19
|
-
div.className = 'app'
|
|
20
|
-
|
|
21
|
-
const labelsDiv = document.createElement('div')
|
|
22
|
-
div.appendChild(labelsDiv)
|
|
23
|
-
|
|
24
|
-
const graphDiv = document.createElement('div')
|
|
25
|
-
graphDiv.className = 'graph'
|
|
26
|
-
div.appendChild(graphDiv)
|
|
27
|
-
|
|
28
|
-
const cosmosLabels = new CosmosLabels(labelsDiv, pointIndexToLabel)
|
|
29
|
-
|
|
30
|
-
const graph = new Graph(graphDiv, {
|
|
31
|
-
spaceSize: 4096,
|
|
32
|
-
backgroundColor: '#2d313a',
|
|
33
|
-
scalePointsOnZoom: true,
|
|
34
|
-
linkWidth: 0.6,
|
|
35
|
-
linkColor: '#5F74C2',
|
|
36
|
-
linkArrows: false,
|
|
37
|
-
fitViewOnInit: false,
|
|
38
|
-
enableDrag: true,
|
|
39
|
-
simulationGravity: 0.1,
|
|
40
|
-
simulationLinkDistance: 1,
|
|
41
|
-
simulationLinkSpring: 0.3,
|
|
42
|
-
simulationRepulsion: 0.4,
|
|
43
|
-
onSimulationTick: () => cosmosLabels.update(graph),
|
|
44
|
-
onZoom: () => cosmosLabels.update(graph),
|
|
45
|
-
attribution: 'visualized with <a href="https://cosmograph.app/" style="color: var(--cosmosgl-attribution-color);" target="_blank">Cosmograph</a>',
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
graph.setPointPositions(new Float32Array(pointPositions))
|
|
49
|
-
graph.setPointColors(new Float32Array(pointColors))
|
|
50
|
-
graph.setPointSizes(new Float32Array(pointSizes))
|
|
51
|
-
graph.setLinks(new Float32Array(links))
|
|
52
|
-
graph.render()
|
|
53
|
-
graph.setZoomLevel(0.6)
|
|
54
|
-
|
|
55
|
-
// _Track the points_ for which you wish to display labels.
|
|
56
|
-
// Their coordinates in the simulation space will be accessible
|
|
57
|
-
// via the `getTrackedPointPositionsMap` method. You can then convert
|
|
58
|
-
// them to the screen space with the `spaceToScreenPosition`
|
|
59
|
-
// method.
|
|
60
|
-
graph.trackPointPositionsByIndices(
|
|
61
|
-
pointsToShowLabelsFor.map((l) => pointLabelToIndex.get(l) as number)
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
return { div, graph }
|
|
65
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { LabelRenderer, LabelOptions } from '@interacta/css-labels'
|
|
2
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
3
|
-
|
|
4
|
-
export class CosmosLabels {
|
|
5
|
-
private labelRenderer: LabelRenderer
|
|
6
|
-
private labels: LabelOptions[] = []
|
|
7
|
-
private pointIndexToLabel: Map<number, string>
|
|
8
|
-
|
|
9
|
-
public constructor (div: HTMLDivElement, pointIndexToLabel: Map<number, string>) {
|
|
10
|
-
this.labelRenderer = new LabelRenderer(div, { pointerEvents: 'none' })
|
|
11
|
-
this.pointIndexToLabel = pointIndexToLabel
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public update (graph: Graph): void {
|
|
15
|
-
// Get coordinates of the tracked nodes
|
|
16
|
-
const trackedNodesPositions = graph.getTrackedPointPositionsMap()
|
|
17
|
-
let index = 0
|
|
18
|
-
trackedNodesPositions.forEach((positions, pointIndex) => {
|
|
19
|
-
// Convert coordinates to the screen space
|
|
20
|
-
const screenPosition = graph.spaceToScreenPosition([
|
|
21
|
-
positions?.[0] ?? 0,
|
|
22
|
-
positions?.[1] ?? 0,
|
|
23
|
-
])
|
|
24
|
-
|
|
25
|
-
// Get the node radius and convert it to the screen space value in pixels
|
|
26
|
-
const radius = graph.spaceToScreenRadius(
|
|
27
|
-
graph.getPointRadiusByIndex(pointIndex) as number
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
// Set label properties
|
|
31
|
-
this.labels[index] = {
|
|
32
|
-
id: `${pointIndex}`,
|
|
33
|
-
text: this.pointIndexToLabel.get(pointIndex) ?? '',
|
|
34
|
-
x: screenPosition[0],
|
|
35
|
-
y: screenPosition[1] - (radius + 2),
|
|
36
|
-
opacity: 1,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
index += 1
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
// Pass labels configuration to the renderer and draw them
|
|
43
|
-
this.labelRenderer.setLabels(this.labels)
|
|
44
|
-
this.labelRenderer.draw(true)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
body {
|
|
2
|
-
font-family: "Nunito Sans", -apple-system, ".SFNSText-Regular", "San Francisco", BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
3
|
-
margin: 0px;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.app {
|
|
7
|
-
position: absolute;
|
|
8
|
-
width: 100%;
|
|
9
|
-
height: 100%;
|
|
10
|
-
color: white;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.graph {
|
|
14
|
-
width: 100%;
|
|
15
|
-
height: 100vh;
|
|
16
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Graph, GraphConfigInterface } from '@cosmos.gl/graph'
|
|
2
|
-
|
|
3
|
-
export const quickStart = (): { graph: Graph; div: HTMLDivElement} => {
|
|
4
|
-
const div = document.createElement('div')
|
|
5
|
-
div.style.height = '100vh'
|
|
6
|
-
div.style.width = '100%'
|
|
7
|
-
|
|
8
|
-
const config: GraphConfigInterface = {
|
|
9
|
-
spaceSize: 4096,
|
|
10
|
-
backgroundColor: '#2d313a',
|
|
11
|
-
pointDefaultColor: '#F069B4',
|
|
12
|
-
scalePointsOnZoom: true,
|
|
13
|
-
simulationFriction: 0.1, // keeps the graph inert
|
|
14
|
-
simulationGravity: 0, // disables gravity
|
|
15
|
-
simulationRepulsion: 0.5, // increases repulsion between points
|
|
16
|
-
curvedLinks: true, // curved links
|
|
17
|
-
fitViewDelay: 1000, // wait 1 second before fitting the view
|
|
18
|
-
fitViewPadding: 0.3, // centers the graph width padding of ~30% of screen
|
|
19
|
-
rescalePositions: true, // rescale positions
|
|
20
|
-
enableDrag: true, // enable dragging points
|
|
21
|
-
onPointClick: pointIndex => { console.log('Clicked point index: ', pointIndex) },
|
|
22
|
-
onBackgroundClick: () => { console.log('Clicked background') },
|
|
23
|
-
attribution: 'visualized with <a href="https://cosmograph.app/" style="color: var(--cosmosgl-attribution-color);" target="_blank">Cosmograph</a>',
|
|
24
|
-
/* ... */
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const graph = new Graph(div, config)
|
|
28
|
-
|
|
29
|
-
// Points: [x1, y1, x2, y2, x3, y3]
|
|
30
|
-
const pointPositions = new Float32Array([
|
|
31
|
-
0.0, 0.0, // Point 1 at (0,0)
|
|
32
|
-
1.0, 0.0, // Point 2 at (1,0)
|
|
33
|
-
0.5, 1.0, // Point 3 at (0.5,1)
|
|
34
|
-
])
|
|
35
|
-
|
|
36
|
-
graph.setPointPositions(pointPositions)
|
|
37
|
-
|
|
38
|
-
// Links: [sourceIndex1, targetIndex1, sourceIndex2, targetIndex2]
|
|
39
|
-
const links = new Float32Array([
|
|
40
|
-
0, 1, // Link from point 0 to point 1
|
|
41
|
-
1, 2, // Link from point 1 to point 2
|
|
42
|
-
2, 0, // Link from point 2 to point 0
|
|
43
|
-
])
|
|
44
|
-
|
|
45
|
-
graph.setLinks(links)
|
|
46
|
-
|
|
47
|
-
graph.render()
|
|
48
|
-
|
|
49
|
-
return { div, graph }
|
|
50
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { GraphConfigInterface } from '@cosmos.gl/graph'
|
|
2
|
-
|
|
3
|
-
export const config: GraphConfigInterface = {
|
|
4
|
-
spaceSize: 4096,
|
|
5
|
-
backgroundColor: '#2d313a',
|
|
6
|
-
pointSize: 4,
|
|
7
|
-
pointDefaultColor: '#4B5BBF',
|
|
8
|
-
scalePointsOnZoom: true,
|
|
9
|
-
pointGreyoutOpacity: 0.1,
|
|
10
|
-
linkWidth: 0.6,
|
|
11
|
-
linkColor: '#5F74C2',
|
|
12
|
-
linkArrows: false,
|
|
13
|
-
linkGreyoutOpacity: 0,
|
|
14
|
-
hoveredPointCursor: 'pointer',
|
|
15
|
-
renderHoveredPointRing: true,
|
|
16
|
-
fitViewDuration: 1000,
|
|
17
|
-
fitViewPadding: 0.3,
|
|
18
|
-
enableSimulationDuringZoom: true,
|
|
19
|
-
simulationLinkDistance: 1,
|
|
20
|
-
simulationLinkSpring: 2,
|
|
21
|
-
simulationRepulsion: 0.2,
|
|
22
|
-
simulationGravity: 0.1,
|
|
23
|
-
simulationDecay: 100000,
|
|
24
|
-
attribution: 'visualized with <a href="https://cosmograph.app/" style="color: var(--cosmosgl-attribution-color);" target="_blank">Cosmograph</a>',
|
|
25
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
function getRandom (min: number, max: number): number {
|
|
2
|
-
return Math.random() * (max - min) + min
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export function generateData (n = 100, m = 100): { pointPositions: number[]; links: number[] } {
|
|
6
|
-
const pointPositions = new Array(n * m * 2)
|
|
7
|
-
const links: number[] = []
|
|
8
|
-
for (let pointIndex = 0; pointIndex < n * m; pointIndex += 1) {
|
|
9
|
-
const x = 4096 * getRandom(0.495, 0.505)
|
|
10
|
-
const y = 4096 * getRandom(0.495, 0.505)
|
|
11
|
-
pointPositions[pointIndex * 2] = x
|
|
12
|
-
pointPositions[pointIndex * 2 + 1] = y
|
|
13
|
-
const nextPointIndex = pointIndex + 1
|
|
14
|
-
const bottomPointIndex = pointIndex + n
|
|
15
|
-
const pointLine = Math.floor(pointIndex / n)
|
|
16
|
-
const nextPointLine = Math.floor(nextPointIndex / n)
|
|
17
|
-
const bottomPointLine = Math.floor(bottomPointIndex / n)
|
|
18
|
-
if (pointLine === nextPointLine) {
|
|
19
|
-
links.push(pointIndex)
|
|
20
|
-
links.push(nextPointIndex)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if (bottomPointLine < m) {
|
|
24
|
-
links.push(pointIndex)
|
|
25
|
-
links.push(bottomPointIndex)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return { pointPositions, links }
|
|
30
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
import { generateData } from './data-gen'
|
|
3
|
-
import { config } from './config'
|
|
4
|
-
import './style.css'
|
|
5
|
-
|
|
6
|
-
export const removePoints = (): { graph: Graph; div: HTMLDivElement} => {
|
|
7
|
-
const { pointPositions, links } = generateData()
|
|
8
|
-
const div = document.createElement('div')
|
|
9
|
-
div.className = 'app'
|
|
10
|
-
|
|
11
|
-
const graphDiv = document.createElement('div')
|
|
12
|
-
graphDiv.className = 'graph'
|
|
13
|
-
div.appendChild(graphDiv)
|
|
14
|
-
|
|
15
|
-
const actionsDiv = document.createElement('div')
|
|
16
|
-
actionsDiv.className = 'actions'
|
|
17
|
-
div.appendChild(actionsDiv)
|
|
18
|
-
|
|
19
|
-
let isPaused = false
|
|
20
|
-
|
|
21
|
-
let graphLinks = links
|
|
22
|
-
|
|
23
|
-
const graph = new Graph(graphDiv, {
|
|
24
|
-
...config,
|
|
25
|
-
onPointClick: (i): void => {
|
|
26
|
-
// Filter out the clicked point from positions array
|
|
27
|
-
const currentPositions = graph.getPointPositions()
|
|
28
|
-
const newPointPositions = currentPositions
|
|
29
|
-
.filter((pos, posIndex) => {
|
|
30
|
-
return (
|
|
31
|
-
(posIndex % 2 === 0 && posIndex !== i * 2) ||
|
|
32
|
-
(posIndex % 2 === 1 && posIndex !== i * 2 + 1)
|
|
33
|
-
)
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
// Convert links array to source-target pairs for easier filtering
|
|
37
|
-
const pairedNumbers = []
|
|
38
|
-
for (let j = 0; j < graphLinks.length; j += 2) {
|
|
39
|
-
const pair = [graphLinks[j], graphLinks[j + 1]]
|
|
40
|
-
pairedNumbers.push(pair)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Remove links connected to deleted point and adjust indices of remaining links
|
|
44
|
-
graphLinks = (pairedNumbers
|
|
45
|
-
.filter(
|
|
46
|
-
([sourceIndex, targetIndex]) => sourceIndex !== i && targetIndex !== i
|
|
47
|
-
)
|
|
48
|
-
.flat() as number[])
|
|
49
|
-
.map((p) => {
|
|
50
|
-
if (p > i) return p - 1
|
|
51
|
-
else return p
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
graph.setPointPositions(new Float32Array(newPointPositions))
|
|
55
|
-
graph.setLinks(new Float32Array(graphLinks))
|
|
56
|
-
graph.render(isPaused ? 0 : undefined)
|
|
57
|
-
console.log('Clicked node: ', i)
|
|
58
|
-
},
|
|
59
|
-
})
|
|
60
|
-
graph.setPointPositions(new Float32Array(pointPositions))
|
|
61
|
-
graph.setLinks(new Float32Array(graphLinks))
|
|
62
|
-
graph.render()
|
|
63
|
-
graph.zoom(0.9)
|
|
64
|
-
|
|
65
|
-
/* ~ Demo Actions ~ */
|
|
66
|
-
// Start / Pause
|
|
67
|
-
const pauseButton = document.createElement('div')
|
|
68
|
-
pauseButton.className = 'action'
|
|
69
|
-
pauseButton.textContent = 'Pause'
|
|
70
|
-
actionsDiv.appendChild(pauseButton)
|
|
71
|
-
|
|
72
|
-
function pause (): void {
|
|
73
|
-
isPaused = true
|
|
74
|
-
pauseButton.textContent = 'Start'
|
|
75
|
-
graph.pause()
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function start (): void {
|
|
79
|
-
isPaused = false
|
|
80
|
-
pauseButton.textContent = 'Pause'
|
|
81
|
-
graph.start()
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function togglePause (): void {
|
|
85
|
-
if (isPaused) start()
|
|
86
|
-
else pause()
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
pauseButton.addEventListener('click', togglePause)
|
|
90
|
-
|
|
91
|
-
return { div, graph }
|
|
92
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
body {
|
|
2
|
-
font-family: "Nunito Sans", -apple-system, ".SFNSText-Regular", "San Francisco", BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
3
|
-
margin: 0px;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.app {
|
|
7
|
-
position: absolute;
|
|
8
|
-
width: 100%;
|
|
9
|
-
height: 100%;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.graph {
|
|
13
|
-
width: 100%;
|
|
14
|
-
height: 100vh;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
.actions {
|
|
19
|
-
position: absolute;
|
|
20
|
-
top: 10px;
|
|
21
|
-
left: 10px;
|
|
22
|
-
color: #ccc;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.action {
|
|
26
|
-
margin-left: 2px;
|
|
27
|
-
font-size: 10pt;
|
|
28
|
-
text-decoration: underline;
|
|
29
|
-
cursor: pointer;
|
|
30
|
-
user-select: none;
|
|
31
|
-
}
|
|
@@ -1,131 +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 { quickStart } from './beginners/quick-start'
|
|
6
|
-
import { basicSetUp } from './beginners/basic-set-up'
|
|
7
|
-
import { pointLabels } from './beginners/point-labels'
|
|
8
|
-
import { removePoints } from './beginners/remove-points'
|
|
9
|
-
import { linkHovering } from './beginners/link-hovering'
|
|
10
|
-
import { pinnedPoints } from './beginners/pinned-points'
|
|
11
|
-
|
|
12
|
-
import quickStartStoryRaw from './beginners/quick-start?raw'
|
|
13
|
-
import basicSetUpStoryRaw from './beginners/basic-set-up/index?raw'
|
|
14
|
-
import basicSetUpStoryCssRaw from './beginners/basic-set-up/style.css?raw'
|
|
15
|
-
import basicSetUpStoryDataGenRaw from './beginners/basic-set-up/data-gen?raw'
|
|
16
|
-
import pointLabelsStoryRaw from './beginners/point-labels/index?raw'
|
|
17
|
-
import pointLabelsStoryDataRaw from './beginners/point-labels/data.ts?raw'
|
|
18
|
-
import pointLabelsStoryLabelsRaw from './beginners/point-labels/labels.ts?raw'
|
|
19
|
-
import pointLabelsStoryCssRaw from './beginners/point-labels/style.css?raw'
|
|
20
|
-
import removePointsStoryRaw from './beginners/remove-points/index?raw'
|
|
21
|
-
import removePointsStoryCssRaw from './beginners/remove-points/style.css?raw'
|
|
22
|
-
import removePointsStoryConfigRaw from './beginners/remove-points/config.ts?raw'
|
|
23
|
-
import removePointsStoryDataGenRaw from './beginners/remove-points/data-gen.ts?raw'
|
|
24
|
-
import linkHoveringStoryRaw from './beginners/link-hovering/index?raw'
|
|
25
|
-
import linkHoveringStoryDataGenRaw from './beginners/link-hovering/data-generator.ts?raw'
|
|
26
|
-
import linkHoveringStoryCssRaw from './beginners/link-hovering/style.css?raw'
|
|
27
|
-
import pinnedPointsStoryRaw from './beginners/pinned-points/index?raw'
|
|
28
|
-
import pinnedPointsStoryDataGenRaw from './beginners/pinned-points/data-gen.ts?raw'
|
|
29
|
-
|
|
30
|
-
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
|
|
31
|
-
const meta: Meta<CosmosStoryProps> = {
|
|
32
|
-
title: 'Examples/Beginners',
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const QuickStart: Story = {
|
|
36
|
-
...createStory(quickStart),
|
|
37
|
-
parameters: {
|
|
38
|
-
sourceCode: [
|
|
39
|
-
{ name: 'Story', code: quickStartStoryRaw },
|
|
40
|
-
],
|
|
41
|
-
},
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const BasicSetUp: Story = {
|
|
45
|
-
...createStory(basicSetUp),
|
|
46
|
-
name: '100x100 grid',
|
|
47
|
-
parameters: {
|
|
48
|
-
sourceCode: [
|
|
49
|
-
{ name: 'Story', code: basicSetUpStoryRaw },
|
|
50
|
-
{ name: 'style.css', code: basicSetUpStoryCssRaw },
|
|
51
|
-
{ name: 'data-gen', code: basicSetUpStoryDataGenRaw },
|
|
52
|
-
],
|
|
53
|
-
},
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export const PointLabels: Story = {
|
|
57
|
-
loaders: [
|
|
58
|
-
async (): Promise<{ data: { performances: [] } }> => {
|
|
59
|
-
try {
|
|
60
|
-
const response = await fetch('https://gist.githubusercontent.com/Stukova/e6c4c7777e0166431a983999213f10c8/raw/performances.json')
|
|
61
|
-
if (!response.ok) {
|
|
62
|
-
throw new Error(`HTTP error! Status: ${response.status}`)
|
|
63
|
-
}
|
|
64
|
-
return {
|
|
65
|
-
data: await response.json(),
|
|
66
|
-
}
|
|
67
|
-
} catch (error) {
|
|
68
|
-
console.error('Failed to fetch data:', error)
|
|
69
|
-
return {
|
|
70
|
-
data: { performances: [] },
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
async beforeEach (d): Promise<() => void> {
|
|
76
|
-
return (): void => {
|
|
77
|
-
d.args.graph?.destroy()
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
render: (args, { loaded: { data } }) => {
|
|
81
|
-
const story = pointLabels(data.performances)
|
|
82
|
-
args.graph = story.graph
|
|
83
|
-
return story.div
|
|
84
|
-
},
|
|
85
|
-
parameters: {
|
|
86
|
-
sourceCode: [
|
|
87
|
-
{ name: 'Story', code: pointLabelsStoryRaw },
|
|
88
|
-
{ name: 'data.ts', code: pointLabelsStoryDataRaw },
|
|
89
|
-
{ name: 'labels.ts', code: pointLabelsStoryLabelsRaw },
|
|
90
|
-
{ name: 'style.css', code: pointLabelsStoryCssRaw },
|
|
91
|
-
],
|
|
92
|
-
},
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export const RemovePoints: Story = {
|
|
96
|
-
...createStory(removePoints),
|
|
97
|
-
parameters: {
|
|
98
|
-
sourceCode: [
|
|
99
|
-
{ name: 'Story', code: removePointsStoryRaw },
|
|
100
|
-
{ name: 'config.ts', code: removePointsStoryConfigRaw },
|
|
101
|
-
{ name: 'data-gen.ts', code: removePointsStoryDataGenRaw },
|
|
102
|
-
{ name: 'style.css', code: removePointsStoryCssRaw },
|
|
103
|
-
],
|
|
104
|
-
},
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export const LinkHovering: Story = {
|
|
108
|
-
...createStory(linkHovering),
|
|
109
|
-
name: 'Link Hovering',
|
|
110
|
-
parameters: {
|
|
111
|
-
sourceCode: [
|
|
112
|
-
{ name: 'Story', code: linkHoveringStoryRaw },
|
|
113
|
-
{ name: 'data-generator.ts', code: linkHoveringStoryDataGenRaw },
|
|
114
|
-
{ name: 'style.css', code: linkHoveringStoryCssRaw },
|
|
115
|
-
],
|
|
116
|
-
},
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export const PinnedPoints: Story = {
|
|
120
|
-
...createStory(pinnedPoints),
|
|
121
|
-
name: 'Pinned Points',
|
|
122
|
-
parameters: {
|
|
123
|
-
sourceCode: [
|
|
124
|
-
{ name: 'Story', code: pinnedPointsStoryRaw },
|
|
125
|
-
{ name: 'data-gen.ts', code: pinnedPointsStoryDataGenRaw },
|
|
126
|
-
],
|
|
127
|
-
},
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// eslint-disable-next-line import/no-default-export
|
|
131
|
-
export default meta
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { Graph } from '@cosmos.gl/graph'
|
|
2
|
-
import { createCosmos } from '../../create-cosmos'
|
|
3
|
-
import { generateMeshData } from '../../generate-mesh-data'
|
|
4
|
-
import { PolygonSelection } from './polygon'
|
|
5
|
-
|
|
6
|
-
export const polygonSelection = (): {div: HTMLDivElement; graph: Graph; destroy: () => void } => {
|
|
7
|
-
const nClusters = 25
|
|
8
|
-
const { pointPositions, pointColors, pointClusters } = generateMeshData(150, 150, nClusters, 1.0)
|
|
9
|
-
|
|
10
|
-
const { div, graph } = createCosmos({
|
|
11
|
-
pointPositions,
|
|
12
|
-
pointColors,
|
|
13
|
-
pointClusters,
|
|
14
|
-
simulationGravity: 1.5,
|
|
15
|
-
simulationCluster: 0.3,
|
|
16
|
-
simulationRepulsion: 8,
|
|
17
|
-
pointSize: 8,
|
|
18
|
-
backgroundColor: '#1a1a2e',
|
|
19
|
-
pointGreyoutOpacity: 0.2,
|
|
20
|
-
onBackgroundClick: (): void => {
|
|
21
|
-
graph.unselectPoints()
|
|
22
|
-
},
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
graph.setZoomLevel(0.4)
|
|
26
|
-
|
|
27
|
-
const polygonSelection = new PolygonSelection(div, (polygonPoints) => {
|
|
28
|
-
graph.selectPointsInPolygon(polygonPoints)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
const actionsDiv = document.createElement('div')
|
|
32
|
-
actionsDiv.className = 'actions'
|
|
33
|
-
div.appendChild(actionsDiv)
|
|
34
|
-
|
|
35
|
-
const polygonButton = document.createElement('div')
|
|
36
|
-
polygonButton.className = 'action'
|
|
37
|
-
polygonButton.textContent = 'Enable Polygon Selection'
|
|
38
|
-
polygonButton.addEventListener('click', () => {
|
|
39
|
-
polygonSelection.enablePolygonMode()
|
|
40
|
-
})
|
|
41
|
-
actionsDiv.appendChild(polygonButton)
|
|
42
|
-
|
|
43
|
-
const destroy = (): void => {
|
|
44
|
-
polygonSelection.destroy()
|
|
45
|
-
if (actionsDiv.parentNode) {
|
|
46
|
-
actionsDiv.parentNode.removeChild(actionsDiv)
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return { div, graph, destroy }
|
|
51
|
-
}
|