@cosmograph/cosmos
Advanced tools
Comparing version 0.9.9 to 1.0.0-beta.1
@@ -5,2 +5,96 @@ import { Node, Link, InputNode, InputLink } from "./types"; | ||
export declare type ColorAccessor<Datum> = ((d: Datum, i?: number, ...rest: unknown[]) => string | [number, number, number, number] | null) | string | [number, number, number, number] | null | undefined; | ||
export interface Events<N extends InputNode> { | ||
/** | ||
* Callback function that will be called on every canvas click. | ||
* If clicked on a node, its data will be passed as an argument: `(node: Node<N> | undefined) => void`. | ||
* Default value: `undefined` | ||
*/ | ||
onClick?: (clickedNode: Node<N> | undefined) => void; | ||
} | ||
export interface GraphSimulationSetting { | ||
/** | ||
* Decay coefficient. Use smaller values if you want the simulation to "cool down" slower. | ||
* Default value: `1000` | ||
*/ | ||
decay?: number; | ||
/** | ||
* Gravity force coefficient. | ||
* Default value: `0` | ||
*/ | ||
gravity?: number; | ||
/** | ||
* Centering to center mass force coefficient. | ||
* Default value: `0` | ||
*/ | ||
center?: number; | ||
/** | ||
* Repulsion force coefficient. | ||
* Default value: `0.1` | ||
*/ | ||
repulsion?: number; | ||
/** | ||
* Decreases / increases the detalization of the Many-Body force calculations. | ||
* When `useQuadtree` is set to `true`, this property corresponds to the Barnes–Hut approximation criterion. | ||
* Default value: `1.7` | ||
*/ | ||
repulsionTheta?: number; | ||
/** | ||
* Barnes–Hut approximation depth. | ||
* Can only be used when `useQuadtree` is set `true`. | ||
* Default value: 12 | ||
*/ | ||
repulsionQuadtreeLevels?: number; | ||
/** | ||
* Link spring force coefficient. | ||
* Default value: `1` | ||
*/ | ||
linkSpring?: number; | ||
/** | ||
* Minimum link distance. | ||
* Default value: `2` | ||
*/ | ||
linkDistance?: number; | ||
/** | ||
* Range of random link distance values. | ||
* Default value: `[1, 1.2]` | ||
*/ | ||
linkDistRandomVariationRange?: number[]; | ||
/** | ||
* Repulsion coefficient from mouse position. | ||
* Default value: `2` | ||
*/ | ||
repulsionFromMouse?: number; | ||
/** | ||
* Friction coefficient. | ||
* Default value: `0.85` | ||
*/ | ||
friction?: number; | ||
/** | ||
* Callback function that will be called when the simulation starts. | ||
* Default value: `undefined` | ||
*/ | ||
onStart?: () => void; | ||
/** | ||
* Callback function that will be called on every simulation tick. | ||
* The value of the argument `alpha` will decrease over time as the simulation "cools down": | ||
* `(alpha: number) => void`. | ||
* Default value: `undefined` | ||
*/ | ||
onTick?: (alpha?: number) => void; | ||
/** | ||
* Callback function that will be called when the simulation stops. | ||
* Default value: `undefined` | ||
*/ | ||
onEnd?: () => void; | ||
/** | ||
* Callback function that will be called when the simulation gets paused. | ||
* Default value: `undefined` | ||
*/ | ||
onPause?: () => void; | ||
/** | ||
* Callback function that will be called when the simulation is restarted. | ||
* Default value: `undefined` | ||
*/ | ||
onRestart?: () => void; | ||
} | ||
export interface GraphConfigInterface<N extends InputNode, L extends InputLink> { | ||
@@ -13,8 +107,8 @@ /** | ||
/** | ||
* Simulation space side length. | ||
* Default value: 4096 | ||
* Simulation space size (max 8192). | ||
* Default value: `4096` | ||
*/ | ||
spaceSize?: number; | ||
/** | ||
* Node color accessor function or value. | ||
* Node color accessor function or hex value. | ||
* Default value: '#b3b3b3' | ||
@@ -25,12 +119,17 @@ */ | ||
* Node size accessor function or value in pixels. | ||
* Default value: 4 | ||
* Default value: `4` | ||
*/ | ||
nodeSize?: NumericAccessor<N>; | ||
/** | ||
* The number by which nodeSize is multiplied. | ||
* Default value: 1 | ||
* Scale factor for the node size. | ||
* Default value: `1` | ||
*/ | ||
nodeSizeMultiplier?: number; | ||
nodeSizeScale?: number; | ||
/** | ||
* Link color accessor function or value. | ||
* Turns link rendering on / off. | ||
* Default value: `true` | ||
*/ | ||
renderLinks?: boolean; | ||
/** | ||
* Link color accessor function or hex value. | ||
* Default value: '#666666' | ||
@@ -41,136 +140,52 @@ */ | ||
* Link width accessor function or value in pixels. | ||
* Default value: 1 | ||
* Default value: `1` | ||
*/ | ||
linkWidth?: NumericAccessor<L>; | ||
/** | ||
* The number by which linkWidth is multiplied. | ||
* Default value: 1 | ||
* Scale factor for the link width. | ||
* Default value: `1` | ||
*/ | ||
linkWidthMultiplier?: number; | ||
linkWidthScale?: number; | ||
/** | ||
* Whether to render links or not. | ||
* Default value: true | ||
* Turns link arrow rendering on / off. | ||
* Default value: `true` | ||
*/ | ||
renderLinks?: boolean; | ||
linkArrows?: boolean; | ||
/** | ||
* Whether to render link's arrows or not. | ||
* Default value: true | ||
* Scale factor for the link arrows size. | ||
* Default value: `1` | ||
*/ | ||
arrowLinks?: boolean; | ||
linkArrowsSizeScale?: number; | ||
/** | ||
* The number by which arrow size is multiplied. | ||
* Default value: 1 | ||
* The range defines the minimum and maximum link visibility distance in pixels. | ||
* 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. | ||
* 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). | ||
* Default value: `[50, 150]` | ||
*/ | ||
arrowSizeMultiplier?: number; | ||
linkVisibilityDistanceRange?: number[]; | ||
/** | ||
* The minimum link distance in which link color do not loose transparency. | ||
* Default value: 50 | ||
* The transparency value that the link will have when its length reaches | ||
* the maximum link distance value from `linkVisibilityDistanceRange`. | ||
* Default value: `0.25` | ||
*/ | ||
minOpaqueLinkDist?: number; | ||
linkVisibilityMinTransparency?: number; | ||
/** | ||
* The maximum link distance in which link color will reach clampLinkMinOpacity value. | ||
* Default value: 150 | ||
* Use the classic quadtree algorithm for the Many-Body force. | ||
* This property will be applied only on component initialization and it | ||
* can't be changed using the `setConfig` method. | ||
* Default value: `false` | ||
*/ | ||
maxTransparentLinkDist?: number; | ||
useQuadtree?: boolean; | ||
/** Simulation parameters and event listeners */ | ||
simulation?: GraphSimulationSetting; | ||
/** | ||
* The transparency value for maxTransparentLinkDist. | ||
* Default value: 0.25 | ||
*/ | ||
clampLinkMinOpacity?: number; | ||
/** Simulation parameters */ | ||
simulation?: { | ||
/** | ||
* Decay coefficient. Small values for quick simulation. | ||
* Default value: 1000 | ||
*/ | ||
decay?: number; | ||
/** | ||
* Gravity force coefficient. | ||
* Default value: 0 | ||
*/ | ||
gravity?: number; | ||
/** | ||
* Centering to center mass force coefficient. | ||
* Default value: 0 | ||
*/ | ||
center?: number; | ||
/** | ||
* Repulsion force coefficient. | ||
* Default value: 0.1 | ||
*/ | ||
repulsion?: number; | ||
/** | ||
* Barnes–Hut approximation criterion. | ||
* Default value: 1.7 | ||
*/ | ||
repulsionTheta?: number; | ||
/** | ||
* Barnes–Hut approximation depth. | ||
* Default value: 12 | ||
*/ | ||
repulsionQuadtreeLevels?: number; | ||
/** | ||
* Link spring force coefficient. | ||
* Default value: 1 | ||
*/ | ||
linkSpring?: number; | ||
/** | ||
* Minimum link distance. | ||
* Default value: 2 | ||
*/ | ||
linkDistance?: number; | ||
/** | ||
* Range of random link distance values. | ||
* Default value: [1, 1.2] | ||
*/ | ||
linkDistRandomVariationRange?: number[]; | ||
/** | ||
* Repulsion coefficient from mouse position. | ||
* Default value: 2 | ||
*/ | ||
repulsionFromMouse?: number; | ||
/** | ||
* Friction value from 0 to 1. | ||
* Default value: 0.85 | ||
*/ | ||
friction?: number; | ||
/** | ||
* On start simulation callback function. | ||
* Default value: () => undefined | ||
*/ | ||
onStart?: () => void; | ||
/** | ||
* On tick simulation callback function. | ||
* Default value: (alpha) => undefined | ||
*/ | ||
onTick?: (alpha?: number) => void; | ||
/** | ||
* On end simulation callback function. | ||
* Default value: () => undefined | ||
*/ | ||
onEnd?: () => void; | ||
/** | ||
* On pause simulation callback function. | ||
* Default value: () => undefined | ||
*/ | ||
onPause?: () => void; | ||
/** | ||
* On restart simulation callback function. | ||
* Default value: () => undefined | ||
*/ | ||
onRestart?: () => void; | ||
}; | ||
/** | ||
* Events | ||
*/ | ||
events?: { | ||
/** | ||
* On click callback function. | ||
* Default value: (clickedNode) => undefined | ||
*/ | ||
onClick?: (clickedNode?: Node<N> | undefined) => void; | ||
}; | ||
events?: Events<N>; | ||
/** | ||
* Whether to show WebGL performance monitor or not. | ||
* Default value: false | ||
* Show WebGL performance monitor. | ||
* Default value: `false` | ||
*/ | ||
@@ -180,3 +195,3 @@ showFPSMonitor?: boolean; | ||
* Canvas pixel ratio. | ||
* Default value: 2 | ||
* Default value: `2` | ||
*/ | ||
@@ -190,33 +205,14 @@ pixelRatio?: number; | ||
nodeSize: number; | ||
nodeSizeMultiplier: number; | ||
nodeSizeScale: number; | ||
linkColor: string; | ||
linkWidth: number; | ||
linkWidthMultiplier: number; | ||
linkWidthScale: number; | ||
renderLinks: boolean; | ||
arrowLinks: boolean; | ||
arrowSizeMultiplier: number; | ||
minOpaqueLinkDist: number; | ||
maxTransparentLinkDist: number; | ||
clampLinkMinOpacity: number; | ||
simulation: { | ||
decay: number; | ||
gravity: number; | ||
center: number; | ||
repulsion: number; | ||
repulsionTheta: number; | ||
repulsionQuadtreeLevels: number; | ||
linkSpring: number; | ||
linkDistance: number; | ||
linkDistRandomVariationRange: number[]; | ||
repulsionFromMouse: number; | ||
friction: number; | ||
onStart: () => void; | ||
onTick: (alpha?: number | undefined) => void; | ||
onEnd: () => void; | ||
onPause: () => void; | ||
onRestart: () => void; | ||
}; | ||
events: { | ||
onClick: (clickedNode?: Node<N> | undefined) => void; | ||
}; | ||
linkArrows: boolean; | ||
linkArrowsSizeScale: number; | ||
linkVisibilityDistanceRange: number[]; | ||
linkVisibilityMinTransparency: number; | ||
useQuadtree: boolean; | ||
simulation: GraphSimulationSetting; | ||
events: Events<N>; | ||
showFPSMonitor: boolean; | ||
@@ -223,0 +219,0 @@ pixelRatio: number; |
@@ -7,4 +7,6 @@ import { CoreModule } from "../core-module"; | ||
private clearLevelsCommand; | ||
private clearVelocityCommand; | ||
private calculateLevelsCommand; | ||
private quadtreeCommand; | ||
private forceCommand; | ||
private forceFromItsOwnCentermassCommand; | ||
private quadtreeLevels; | ||
@@ -11,0 +13,0 @@ create(): void; |
@@ -8,10 +8,10 @@ export declare const defaultNodeColor = "#b3b3b3"; | ||
spaceSize: number; | ||
nodeSizeMultiplier: number; | ||
linkWidthMultiplier: number; | ||
arrowSizeMultiplier: number; | ||
nodeSizeScale: number; | ||
linkWidthScale: number; | ||
arrowSizeScale: number; | ||
renderLinks: boolean; | ||
arrowLinks: boolean; | ||
minOpaqueLinkDist: number; | ||
maxTransparentLinkDist: number; | ||
clampLinkMinOpacity: number; | ||
linkVisibilityDistanceRange: number[]; | ||
linkVisibilityMinTransparency: number; | ||
useQuadtree: boolean; | ||
simulation: { | ||
@@ -18,0 +18,0 @@ decay: number; |
{ | ||
"name": "@cosmograph/cosmos", | ||
"version": "0.9.9", | ||
"version": "1.0.0-beta.1", | ||
"description": "GPU-based force graph layout algorithm and rendering engine", | ||
@@ -14,2 +14,8 @@ "main": "dist/index.js", | ||
}, | ||
"engines": { | ||
"node": ">=12.2.0", | ||
"npm": ">=7.0.0" | ||
}, | ||
"keywords": ["graph", "webgl", "force", "simulation", "visualization"], | ||
"homepage": "https://cosmograph.app", | ||
"author": "cosmograph-org", | ||
@@ -16,0 +22,0 @@ "devDependencies": { |
@@ -6,6 +6,8 @@ <p align="center" style="color: #444"> | ||
Cosmos is a WebGL Force Graph layout algorithm and rendering engine. All the computations and drawing are happening on the GPU in fragment and vertex shaders avoiding expensive memory operations. That enables real time simulation of network graphs consisting of more than a million of nodes and edges on a modern hardware. | ||
Cosmos is a WebGL Force Graph layout algorithm and rendering engine. All the computations and drawing are happening on the GPU in fragment and vertex shaders avoiding expensive memory operations. | ||
> ⚠️ **If you are a Windows user, you'll need to take a few extra steps to make Cosmos work.** Here's our [step-by-step guide](https://medium.com/@cosmograph.app/how-to-make-cosmograph-work-on-windows-d02291093b7a) for Chrome and Firefox. | ||
It enables real time simulation of network graphs consisting of hundreds thousands of nodes and edges on modern hardware. | ||
https://user-images.githubusercontent.com/755708/165214913-40701c64-afc5-498f-a92e-db10e6caa19d.mp4 | ||
[🎮 Try Cosmos on CodeSandbox](https://codesandbox.io/s/cosmos-example-fmuf1x?file=/src/index.ts) | ||
@@ -15,3 +17,3 @@ | ||
Install the package | ||
Install the package: | ||
@@ -22,3 +24,3 @@ ```bash | ||
Get your data and run the simulation | ||
Get the data, [configure](#cosmos_configuration) the graph and run the simulation: | ||
```javascript | ||
@@ -47,3 +49,4 @@ import { Graph } from '@cosmograph/cosmos' | ||
> **NOTE**: If your canvas element has no width and height styles (either CSS or inline) Cosmos will automatically set them to 100%. | ||
> **Note** | ||
> If your canvas element has no width and height styles (either CSS or inline) Cosmos will automatically set them to 100%. | ||
@@ -60,24 +63,53 @@ ### Examples | ||
### Layout configuration | ||
### <a name="cosmos_configuration" href="#cosmos_configuration">#</a> Cosmos configuration | ||
| Property | Description | Default | | ||
|---|---|---| | ||
| backgroundColor | Canvas background color | `#222222` | ||
| spaceSize | Simulation space size (max 8192) | `4096` | ||
| nodeColor | Node color accessor function or hex value | `#b3b3b3` | ||
| nodeSize | Node size accessor function or value in pixels | `4` | ||
| nodeSizeScale | Scale factor for the node size | `1` | ||
| renderLinks | Turns link rendering on / off | `true` | ||
| linkColor | Link color accessor function or hex value | `#666666` | ||
| linkWidth | Link width accessor function or value in pixels | `1` | ||
| linkWidthScale | Scale factor for the link width | `1` | ||
| linkArrows | Turns link arrow rendering on / off | `true` | ||
| linkArrowsSizeScale | Scale factor for the link arrows size | `1` | ||
| 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]` | ||
| linkVisibilityMinTransparency | The transparency value that the link will have when its length reaches the maximum link distance value from `linkVisibilityDistanceRange`. | `0.25` | ||
| useQuadtree | 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` | ||
| simulation | Simulation parameters and event listeners | See [Simulation configuration](#simulation_configuration) table for more details | ||
| events.onClick | Callback function that will be called on every canvas click. If clicked on a node, its data will be passed as an argument: <code>(node: Node<N> | undefined) => void</code> | `undefined` | ||
| showFPSMonitor | Show WebGL performance monitor | `false` | ||
| pixelRatio | Canvas pixel ratio | `2` | ||
### <a name="simulation_configuration" href="#simulation_configuration">#</a> Simulation configuration | ||
Cosmos 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. | ||
Repulsion force works as a repulsion part of the classic many-body force. Its implementation was heavily inspired by quadtrees and the [Barnes-Hut simulation approximation algorithm](https://en.wikipedia.org/wiki/Barnes%E2%80%93Hut_simulation) adapted for WebGL technology. | ||
| Property | Description | Recommended range | Default | | ||
|---|---|---|---| | ||
repulsion | Repulsion force coefficient | 0.0 – 2.0 | 0.1 | | ||
repulsionTheta | Barnes–Hut approximation criterion | 0.3 – 2.0 | 1.7 | | ||
repulsionQuadtreeLevels | Barnes–Hut approximation depth | 5 – 12 | 12 | | ||
linkSpring | Link spring force coefficient | 0.0 – 2.0 | 1.0 | | ||
linkDistance | Minimum link distance | 1 – 20 | 2 | | ||
linkDistRandomVariationRange | Link distance randomness multiplier range | [0.8 – 1.2, 1.2 – 2.0] | [1.0, 1.2] | | ||
gravity | Gravity force coefficient | 0.0 – 1.0 | 0.0 | | ||
center | Centering force coefficient | 0.0 – 1.0 | 0.0 | | ||
friction | Friction value from 0.0 to 1.0 | 0.8 – 1.0 | 0.85 | | ||
decay | Force simulation decay coefficient. Smaller the values faster the simulation goes| 100 – 10 000| 1000 | | ||
repulsionFromMouse | Repulsion from the mouse pointer force coefficient | 0.0 – 5.0 | 2.0 | ||
| repulsion | Repulsion force coefficient | 0.0 – 2.0 | `0.1` | | ||
| repulsionTheta | Decreases / increases the detalization of the Many-Body force calculations. <br /><br /> When `useQuadtree` is set to `true`, this property corresponds to the Barnes–Hut approximation criterion. | 0.3 – 2.0 | `1.7` | | ||
| repulsionQuadtreeLevels | Barnes–Hut approximation depth. <br /><br />Can only be used when `useQuadtree` is set `true`. | 5 – 12 | `12` | | ||
| linkSpring | Link spring force coefficient | 0.0 – 2.0 | `1.0` | | ||
| linkDistance | Minimum link distance | 1 – 20 | `2` | | ||
| linkDistRandomVariationRange | Link distance randomness multiplier range | [0.8 – 1.2,<br/> 1.2 – 2.0] | `[1.0, 1.2]` | | ||
| gravity | Gravity force coefficient | 0.0 – 1.0 | `0.0` | | ||
| center | Centering force coefficient | 0.0 – 1.0 | `0.0` | | ||
| friction | Friction coefficient| 0.8 – 1.0 | `0.85` | | ||
| decay | Force simulation decay coefficient. <br /><br />Use smaller values if you want the simulation to "cool down" slower.| 100 – 10 000| `1000` | | ||
| repulsionFromMouse | Repulsion from the mouse pointer force coefficient | 0.0 – 5.0 | `2.0` | ||
| simulation.onStart | Callback function that will be called when the simulation starts | | `undefined` | ||
| simulation.onTick | Callback function that will be called on every simulation tick. <br /><br />The value of the argument `alpha` will decrease over time as the simulation "cools down": `(alpha: number) => void` | | `undefined` | ||
| simulation.onEnd | Callback function that will be called when the simulation stops | | `undefined` | ||
| simulation.onPause | Callback function that will be called when the simulation gets paused | | `undefined` | ||
| simulation.onRestart | Callback function that will be called when the simulation is restarted | | `undefined` | ||
### License | ||
CC-BY-NC-3.0 | ||
CC-BY-NC-4.0 | ||
@@ -84,0 +116,0 @@ Cosmos is free non-commercial usage. If you're a scientist, artist, educator, journalist, student, ..., we would love to hear about your project and how you use Cosmos! If you want to use it in a commercial project, please reach out to us. |
@@ -16,2 +16,98 @@ import { Node, Link, InputNode, InputLink } from '@/graph/types' | ||
export interface Events <N extends InputNode> { | ||
/** | ||
* Callback function that will be called on every canvas click. | ||
* If clicked on a node, its data will be passed as an argument: `(node: Node<N> | undefined) => void`. | ||
* Default value: `undefined` | ||
*/ | ||
onClick?: (clickedNode: Node<N> | undefined) => void; | ||
} | ||
export interface GraphSimulationSetting { | ||
/** | ||
* Decay coefficient. Use smaller values if you want the simulation to "cool down" slower. | ||
* Default value: `1000` | ||
*/ | ||
decay?: number; | ||
/** | ||
* Gravity force coefficient. | ||
* Default value: `0` | ||
*/ | ||
gravity?: number; | ||
/** | ||
* Centering to center mass force coefficient. | ||
* Default value: `0` | ||
*/ | ||
center?: number; | ||
/** | ||
* Repulsion force coefficient. | ||
* Default value: `0.1` | ||
*/ | ||
repulsion?: number; | ||
/** | ||
* Decreases / increases the detalization of the Many-Body force calculations. | ||
* When `useQuadtree` is set to `true`, this property corresponds to the Barnes–Hut approximation criterion. | ||
* Default value: `1.7` | ||
*/ | ||
repulsionTheta?: number; | ||
/** | ||
* Barnes–Hut approximation depth. | ||
* Can only be used when `useQuadtree` is set `true`. | ||
* Default value: 12 | ||
*/ | ||
repulsionQuadtreeLevels?: number; | ||
/** | ||
* Link spring force coefficient. | ||
* Default value: `1` | ||
*/ | ||
linkSpring?: number; | ||
/** | ||
* Minimum link distance. | ||
* Default value: `2` | ||
*/ | ||
linkDistance?: number; | ||
/** | ||
* Range of random link distance values. | ||
* Default value: `[1, 1.2]` | ||
*/ | ||
linkDistRandomVariationRange?: number[]; | ||
/** | ||
* Repulsion coefficient from mouse position. | ||
* Default value: `2` | ||
*/ | ||
repulsionFromMouse?: number; | ||
/** | ||
* Friction coefficient. | ||
* Default value: `0.85` | ||
*/ | ||
friction?: number; | ||
/** | ||
* Callback function that will be called when the simulation starts. | ||
* Default value: `undefined` | ||
*/ | ||
onStart?: () => void; | ||
/** | ||
* Callback function that will be called on every simulation tick. | ||
* The value of the argument `alpha` will decrease over time as the simulation "cools down": | ||
* `(alpha: number) => void`. | ||
* Default value: `undefined` | ||
*/ | ||
onTick?: (alpha?: number) => void; | ||
/** | ||
* Callback function that will be called when the simulation stops. | ||
* Default value: `undefined` | ||
*/ | ||
onEnd?: () => void; | ||
/** | ||
* Callback function that will be called when the simulation gets paused. | ||
* Default value: `undefined` | ||
*/ | ||
onPause?: () => void; | ||
/** | ||
* Callback function that will be called when the simulation is restarted. | ||
* Default value: `undefined` | ||
*/ | ||
onRestart?: () => void; | ||
} | ||
export interface GraphConfigInterface<N extends InputNode, L extends InputLink> { | ||
@@ -24,8 +120,8 @@ /** | ||
/** | ||
* Simulation space side length. | ||
* Default value: 4096 | ||
* Simulation space size (max 8192). | ||
* Default value: `4096` | ||
*/ | ||
spaceSize?: number; | ||
/** | ||
* Node color accessor function or value. | ||
* Node color accessor function or hex value. | ||
* Default value: '#b3b3b3' | ||
@@ -36,13 +132,18 @@ */ | ||
* Node size accessor function or value in pixels. | ||
* Default value: 4 | ||
* Default value: `4` | ||
*/ | ||
nodeSize?: NumericAccessor<N>; | ||
/** | ||
* The number by which nodeSize is multiplied. | ||
* Default value: 1 | ||
* Scale factor for the node size. | ||
* Default value: `1` | ||
*/ | ||
nodeSizeMultiplier?: number; | ||
nodeSizeScale?: number; | ||
/** | ||
* Link color accessor function or value. | ||
* Turns link rendering on / off. | ||
* Default value: `true` | ||
*/ | ||
renderLinks?: boolean; | ||
/** | ||
* Link color accessor function or hex value. | ||
* Default value: '#666666' | ||
@@ -53,143 +154,58 @@ */ | ||
* Link width accessor function or value in pixels. | ||
* Default value: 1 | ||
* Default value: `1` | ||
*/ | ||
linkWidth?: NumericAccessor<L>; | ||
/** | ||
* The number by which linkWidth is multiplied. | ||
* Default value: 1 | ||
* Scale factor for the link width. | ||
* Default value: `1` | ||
*/ | ||
linkWidthMultiplier?: number; | ||
linkWidthScale?: number; | ||
/** | ||
* Whether to render links or not. | ||
* Default value: true | ||
* Turns link arrow rendering on / off. | ||
* Default value: `true` | ||
*/ | ||
renderLinks?: boolean; | ||
linkArrows?: boolean; | ||
/** | ||
* Whether to render link's arrows or not. | ||
* Default value: true | ||
* Scale factor for the link arrows size. | ||
* Default value: `1` | ||
*/ | ||
arrowLinks?: boolean; | ||
linkArrowsSizeScale?: number; | ||
/** | ||
* The number by which arrow size is multiplied. | ||
* Default value: 1 | ||
* The range defines the minimum and maximum link visibility distance in pixels. | ||
* 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. | ||
* 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). | ||
* Default value: `[50, 150]` | ||
*/ | ||
arrowSizeMultiplier?: number; | ||
linkVisibilityDistanceRange?: number[]; | ||
/** | ||
* The minimum link distance in which link color do not loose transparency. | ||
* Default value: 50 | ||
* The transparency value that the link will have when its length reaches | ||
* the maximum link distance value from `linkVisibilityDistanceRange`. | ||
* Default value: `0.25` | ||
*/ | ||
minOpaqueLinkDist?: number; | ||
linkVisibilityMinTransparency?: number; | ||
/** | ||
* The maximum link distance in which link color will reach clampLinkMinOpacity value. | ||
* Default value: 150 | ||
* Use the classic quadtree algorithm for the Many-Body force. | ||
* This property will be applied only on component initialization and it | ||
* can't be changed using the `setConfig` method. | ||
* Default value: `false` | ||
*/ | ||
maxTransparentLinkDist?: number; | ||
useQuadtree?: boolean; | ||
/** Simulation parameters and event listeners */ | ||
simulation?: GraphSimulationSetting; | ||
/** | ||
* The transparency value for maxTransparentLinkDist. | ||
* Default value: 0.25 | ||
*/ | ||
clampLinkMinOpacity?: number; | ||
/** Simulation parameters */ | ||
simulation?: { | ||
/** | ||
* Decay coefficient. Small values for quick simulation. | ||
* Default value: 1000 | ||
*/ | ||
decay?: number; | ||
/** | ||
* Gravity force coefficient. | ||
* Default value: 0 | ||
*/ | ||
gravity?: number; | ||
/** | ||
* Centering to center mass force coefficient. | ||
* Default value: 0 | ||
*/ | ||
center?: number; | ||
/** | ||
* Repulsion force coefficient. | ||
* Default value: 0.1 | ||
*/ | ||
repulsion?: number; | ||
/** | ||
* Barnes–Hut approximation criterion. | ||
* Default value: 1.7 | ||
*/ | ||
repulsionTheta?: number; | ||
/** | ||
* Barnes–Hut approximation depth. | ||
* Default value: 12 | ||
*/ | ||
repulsionQuadtreeLevels?: number; | ||
/** | ||
* Link spring force coefficient. | ||
* Default value: 1 | ||
*/ | ||
linkSpring?: number; | ||
/** | ||
* Minimum link distance. | ||
* Default value: 2 | ||
*/ | ||
linkDistance?: number; | ||
/** | ||
* Range of random link distance values. | ||
* Default value: [1, 1.2] | ||
*/ | ||
linkDistRandomVariationRange?: number[]; | ||
/** | ||
* Repulsion coefficient from mouse position. | ||
* Default value: 2 | ||
*/ | ||
repulsionFromMouse?: number; | ||
/** | ||
* Friction value from 0 to 1. | ||
* Default value: 0.85 | ||
*/ | ||
friction?: number; | ||
/** | ||
* On start simulation callback function. | ||
* Default value: () => undefined | ||
*/ | ||
onStart?: () => void; | ||
/** | ||
* On tick simulation callback function. | ||
* Default value: (alpha) => undefined | ||
*/ | ||
onTick?: (alpha?: number) => void; | ||
/** | ||
* On end simulation callback function. | ||
* Default value: () => undefined | ||
*/ | ||
onEnd?: () => void; | ||
/** | ||
* On pause simulation callback function. | ||
* Default value: () => undefined | ||
*/ | ||
onPause?: () => void; | ||
/** | ||
* On restart simulation callback function. | ||
* Default value: () => undefined | ||
*/ | ||
onRestart?: () => void; | ||
}; | ||
/** | ||
* Events | ||
*/ | ||
events?: { | ||
/** | ||
* On click callback function. | ||
* Default value: (clickedNode) => undefined | ||
*/ | ||
onClick?: (clickedNode?: Node<N> | undefined) => void; | ||
}; | ||
events?: Events<N>; | ||
/** | ||
* Whether to show WebGL performance monitor or not. | ||
* Default value: false | ||
* Show WebGL performance monitor. | ||
* Default value: `false` | ||
*/ | ||
showFPSMonitor?: boolean; | ||
showFPSMonitor?: boolean; | ||
/** | ||
* Canvas pixel ratio. | ||
* Default value: 2 | ||
* Default value: `2` | ||
*/ | ||
@@ -204,14 +220,14 @@ pixelRatio?: number; | ||
public nodeSize = defaultNodeSize | ||
public nodeSizeMultiplier = defaultConfigValues.nodeSizeMultiplier | ||
public nodeSizeScale = defaultConfigValues.nodeSizeScale | ||
public linkColor = defaultLinkColor | ||
public linkWidth = defaultLinkWidth | ||
public linkWidthMultiplier = defaultConfigValues.linkWidthMultiplier | ||
public linkWidthScale = defaultConfigValues.linkWidthScale | ||
public renderLinks = defaultConfigValues.renderLinks | ||
public arrowLinks = defaultConfigValues.arrowLinks | ||
public arrowSizeMultiplier = defaultConfigValues.arrowSizeMultiplier | ||
public minOpaqueLinkDist = defaultConfigValues.minOpaqueLinkDist | ||
public maxTransparentLinkDist = defaultConfigValues.maxTransparentLinkDist | ||
public clampLinkMinOpacity = defaultConfigValues.clampLinkMinOpacity | ||
public linkArrows = defaultConfigValues.arrowLinks | ||
public linkArrowsSizeScale = defaultConfigValues.arrowSizeScale | ||
public linkVisibilityDistanceRange = defaultConfigValues.linkVisibilityDistanceRange | ||
public linkVisibilityMinTransparency = defaultConfigValues.linkVisibilityMinTransparency | ||
public useQuadtree = defaultConfigValues.useQuadtree | ||
public simulation = { | ||
public simulation: GraphSimulationSetting = { | ||
decay: defaultConfigValues.simulation.decay, | ||
@@ -228,13 +244,11 @@ gravity: defaultConfigValues.simulation.gravity, | ||
friction: defaultConfigValues.simulation.friction, | ||
onStart: (): void => undefined, | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
onTick: (alpha?: number): void => undefined, | ||
onEnd: (): void => undefined, | ||
onPause: (): void => undefined, | ||
onRestart: (): void => undefined, | ||
onStart: undefined, | ||
onTick: undefined, | ||
onEnd: undefined, | ||
onPause: undefined, | ||
onRestart: undefined, | ||
} | ||
public events = { | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
onClick: (clickedNode?: Node<N>): void => undefined, | ||
public events: Events<N> = { | ||
onClick: undefined, | ||
} | ||
@@ -241,0 +255,0 @@ |
@@ -11,2 +11,3 @@ import { select } from 'd3-selection' | ||
import { ForceManyBody } from '@/graph/modules/ForceManyBody' | ||
import { ForceManyBodyQuadtree } from '@/graph/modules/ForceManyBodyQuadtree' | ||
import { ForceMouse } from '@/graph/modules/ForceMouse' | ||
@@ -20,2 +21,3 @@ import { FPSMonitor } from '@/graph/modules/FPSMonitor' | ||
import { Node, Link, InputNode, InputLink } from '@/graph/types' | ||
import { defaultConfigValues } from '@/graph/variables' | ||
@@ -35,3 +37,3 @@ export class Graph<N extends InputNode, L extends InputLink> { | ||
private forceCenter: ForceCenter<N, L> | ||
private forceManyBody: ForceManyBody<N, L> | ||
private forceManyBody: ForceManyBody<N, L> | ForceManyBodyQuadtree<N, L> | undefined | ||
private forceLinkIncoming: ForceLink<N, L> | ||
@@ -83,3 +85,5 @@ private forceLinkOutcoming: ForceLink<N, L> | ||
this.forceCenter = new ForceCenter(this.reglInstance, this.config, this.store, this.graph, this.points) | ||
this.forceManyBody = new ForceManyBody(this.reglInstance, this.config, this.store, this.graph, this.points) | ||
this.forceManyBody = this.config.useQuadtree | ||
? new ForceManyBodyQuadtree(this.reglInstance, this.config, this.store, this.graph, this.points) | ||
: new ForceManyBody(this.reglInstance, this.config, this.store, this.graph, this.points) | ||
this.forceLinkIncoming = new ForceLink(this.reglInstance, this.config, this.store, this.graph, this.points) | ||
@@ -249,3 +253,3 @@ this.forceLinkOutcoming = new ForceLink(this.reglInstance, this.config, this.store, this.graph, this.points) | ||
this.forceLinkOutcoming.destroy() | ||
this.forceManyBody.destroy() | ||
this.forceManyBody?.destroy() | ||
this.reglInstance.destroy() | ||
@@ -258,3 +262,3 @@ this.hasBeenRecentlyDestroyed = true | ||
this.lines.create() | ||
this.forceManyBody.create() | ||
this.forceManyBody?.create() | ||
this.forceLinkIncoming.create(LinkDirection.INCOMING) | ||
@@ -287,3 +291,3 @@ this.forceLinkOutcoming.create(LinkDirection.OUTCOMING) | ||
this.forceMouse.initPrograms() | ||
this.forceManyBody.initPrograms() | ||
this.forceManyBody?.initPrograms() | ||
this.forceCenter.initPrograms() | ||
@@ -317,3 +321,3 @@ } | ||
this.forceManyBody.run() | ||
this.forceManyBody?.run() | ||
this.points.updatePosition() | ||
@@ -326,3 +330,3 @@ | ||
this.store.alpha += this.store.addAlpha(this.config.simulation.decay) | ||
this.store.alpha += this.store.addAlpha(this.config.simulation.decay ?? defaultConfigValues.simulation.decay) | ||
if (this.isRightClickMouse) this.store.alpha = Math.max(this.store.alpha, 0.1) | ||
@@ -329,0 +333,0 @@ this.store.simulationProgress = Math.sqrt(Math.min(1, ALPHA_MIN / this.store.alpha)) |
import regl from 'regl' | ||
import { CoreModule } from '@/graph/modules/core-module' | ||
import { calculateLevelVert } from '@/graph/modules/ForceManyBody/calculate-level' | ||
import calculateLevelFrag from '@/graph/modules/ForceManyBody/calculate-level.frag' | ||
import { forceFrag } from '@/graph/modules/ForceManyBody/quadtree-frag-shader' | ||
import calculateLevelVert from '@/graph/modules/ForceManyBody/calculate-level.vert' | ||
import forceFrag from '@/graph/modules/ForceManyBody/force-level.frag' | ||
import forceCenterFrag from '@/graph/modules/ForceManyBody/force-centermass.frag' | ||
import { createIndexesBuffer, createQuadBuffer } from '@/graph/modules/Shared/buffer' | ||
@@ -17,4 +18,6 @@ import clearFrag from '@/graph/modules/Shared/clear.frag' | ||
private clearLevelsCommand: regl.DrawCommand | undefined | ||
private clearVelocityCommand: regl.DrawCommand | undefined | ||
private calculateLevelsCommand: regl.DrawCommand | undefined | ||
private quadtreeCommand: regl.DrawCommand | undefined | ||
private forceCommand: regl.DrawCommand | undefined | ||
private forceFromItsOwnCentermassCommand: regl.DrawCommand | undefined | ||
private quadtreeLevels = 0 | ||
@@ -27,9 +30,5 @@ | ||
const levelTextureSize = Math.pow(2, i + 1) | ||
this.levelsFbos.set(`level[${i}]`, reglInstance.framebuffer({ | ||
color: reglInstance.texture({ | ||
data: new Float32Array(levelTextureSize * levelTextureSize * 4), | ||
shape: [levelTextureSize, levelTextureSize, 4], | ||
type: 'float', | ||
}), | ||
shape: [levelTextureSize, levelTextureSize], | ||
colorType: 'float', | ||
depth: false, | ||
@@ -70,7 +69,4 @@ stencil: false, | ||
frag: calculateLevelFrag, | ||
vert: ( | ||
_: regl.DefaultContext, | ||
props: { levelFbo: regl.Framebuffer2D; matrixSize: number; levelSize: number } | ||
) => calculateLevelVert(props.matrixSize, props.levelSize), | ||
framebuffer: (_: regl.DefaultContext, props: { levelFbo: regl.Framebuffer2D }) => props.levelFbo, | ||
vert: calculateLevelVert, | ||
framebuffer: (_: regl.DefaultContext, props: { levelFbo: regl.Framebuffer2D; levelTextureSize: number; cellSize: number }) => props.levelFbo, | ||
primitive: 'points', | ||
@@ -82,2 +78,4 @@ count: () => data.nodes.length, | ||
pointsTextureSize: () => store.pointsTextureSize, | ||
levelTextureSize: (_: regl.DefaultContext, props: { levelTextureSize: number }) => props.levelTextureSize, | ||
cellSize: (_: regl.DefaultContext, props: { cellSize: number }) => props.cellSize, | ||
}, | ||
@@ -98,4 +96,5 @@ blend: { | ||
}) | ||
this.quadtreeCommand = reglInstance({ | ||
frag: forceFrag(config.simulation?.repulsionQuadtreeLevels ?? this.quadtreeLevels, this.quadtreeLevels), | ||
this.forceCommand = reglInstance({ | ||
frag: forceFrag, | ||
vert: updateVert, | ||
@@ -108,10 +107,63 @@ framebuffer: () => points?.velocityFbo as regl.Framebuffer2D, | ||
position: () => points?.previousPositionFbo, | ||
randomValues: () => this.randomValuesFbo, | ||
level: (_, props: { levelFbo: regl.Framebuffer2D; levelTextureSize: number; level: number }) => props.level, | ||
levels: this.quadtreeLevels, | ||
levelFbo: (_, props) => props.levelFbo, | ||
levelTextureSize: (_, props) => props.levelTextureSize, | ||
alpha: () => store.alpha, | ||
repulsion: () => config.simulation?.repulsion, | ||
spaceSize: () => config.spaceSize, | ||
repulsion: () => config.simulation?.repulsion, | ||
theta: () => config.simulation?.repulsionTheta, | ||
}, | ||
blend: { | ||
enable: true, | ||
func: { | ||
src: 'one', | ||
dst: 'one', | ||
}, | ||
equation: { | ||
rgb: 'add', | ||
alpha: 'add', | ||
}, | ||
}, | ||
depth: { enable: false, mask: false }, | ||
stencil: { enable: false }, | ||
}) | ||
this.forceFromItsOwnCentermassCommand = reglInstance({ | ||
frag: forceCenterFrag, | ||
vert: updateVert, | ||
framebuffer: () => points?.velocityFbo as regl.Framebuffer2D, | ||
primitive: 'triangle strip', | ||
count: 4, | ||
attributes: { quad: createQuadBuffer(reglInstance) }, | ||
uniforms: { | ||
position: () => points?.previousPositionFbo, | ||
randomValues: () => this.randomValuesFbo, | ||
levelFbo: (_, props: { levelFbo: regl.Framebuffer2D; levelTextureSize: number }) => props.levelFbo, | ||
levelTextureSize: (_, props) => props.levelTextureSize, | ||
alpha: () => store.alpha, | ||
...Object.fromEntries(this.levelsFbos), | ||
repulsion: () => config.simulation?.repulsion, | ||
spaceSize: () => config.spaceSize, | ||
}, | ||
blend: { | ||
enable: true, | ||
func: { | ||
src: 'one', | ||
dst: 'one', | ||
}, | ||
equation: { | ||
rgb: 'add', | ||
alpha: 'add', | ||
}, | ||
}, | ||
depth: { enable: false, mask: false }, | ||
stencil: { enable: false }, | ||
}) | ||
this.clearVelocityCommand = reglInstance({ | ||
frag: clearFrag, | ||
vert: updateVert, | ||
framebuffer: () => points?.velocityFbo as regl.Framebuffer2D, | ||
primitive: 'triangle strip', | ||
count: 4, | ||
attributes: { quad: createQuadBuffer(reglInstance) }, | ||
}) | ||
} | ||
@@ -123,9 +175,27 @@ | ||
this.clearLevelsCommand?.({ levelFbo: this.levelsFbos.get(`level[${i}]`) }) | ||
const levelTextureSize = Math.pow(2, i + 1) | ||
const cellSize = (config.spaceSize ?? defaultConfigValues.spaceSize) / levelTextureSize | ||
this.calculateLevelsCommand?.({ | ||
levelFbo: this.levelsFbos.get(`level[${i}]`), | ||
matrixSize: Math.pow(2, i + 1), | ||
levelSize: (config.spaceSize ?? defaultConfigValues.spaceSize) / Math.pow(2, i + 1), | ||
levelTextureSize: levelTextureSize, | ||
cellSize: cellSize, | ||
}) | ||
} | ||
this.quadtreeCommand?.() | ||
this.clearVelocityCommand?.() | ||
for (let i = 0; i < this.quadtreeLevels; i += 1) { | ||
const levelTextureSize = Math.pow(2, i + 1) | ||
this.forceCommand?.({ | ||
levelFbo: this.levelsFbos.get(`level[${i}]`), | ||
levelTextureSize, | ||
level: i, | ||
}) | ||
if (i === this.quadtreeLevels - 1) { | ||
this.forceFromItsOwnCentermassCommand?.({ | ||
levelFbo: this.levelsFbos.get(`level[${i}]`), | ||
levelTextureSize, | ||
level: i, | ||
}) | ||
} | ||
} | ||
} | ||
@@ -132,0 +202,0 @@ |
@@ -83,12 +83,11 @@ import regl from 'regl' | ||
pointsTextureSize: () => store.pointsTextureSize, | ||
nodeSizeMultiplier: () => config.nodeSizeMultiplier, | ||
widthMultiplier: () => config.linkWidthMultiplier, | ||
useArrow: () => config.arrowLinks, | ||
arrowSizeMultiplier: () => config.arrowSizeMultiplier, | ||
nodeSizeScale: () => config.nodeSizeScale, | ||
widthScale: () => config.linkWidthScale, | ||
useArrow: () => config.linkArrows, | ||
arrowSizeScale: () => config.linkArrowsSizeScale, | ||
spaceSize: () => config.spaceSize, | ||
screenSize: () => store.screenSize, | ||
ratio: () => config.pixelRatio, | ||
maxTransparentLinkDist: () => config.maxTransparentLinkDist, | ||
minOpaqueLinkDist: () => config.minOpaqueLinkDist, | ||
clampLinkMinOpacity: () => config.clampLinkMinOpacity, | ||
linkVisibilityDistanceRange: () => config.linkVisibilityDistanceRange, | ||
linkVisibilityMinTransparency: () => config.linkVisibilityMinTransparency, | ||
}, | ||
@@ -95,0 +94,0 @@ cull: { |
@@ -111,3 +111,3 @@ import regl from 'regl' | ||
ratio: () => config.pixelRatio, | ||
sizeMultiplier: () => config.nodeSizeMultiplier, | ||
sizeScale: () => config.nodeSizeScale, | ||
pointsTextureSize: () => store.pointsTextureSize, | ||
@@ -148,3 +148,3 @@ transform: () => store.transform, | ||
screenSize: () => store.screenSize, | ||
sizeMultiplier: () => config.nodeSizeMultiplier, | ||
sizeScale: () => config.nodeSizeScale, | ||
transform: () => store.transform, | ||
@@ -151,0 +151,0 @@ ratio: () => config.pixelRatio, |
@@ -9,10 +9,10 @@ export const defaultNodeColor = '#b3b3b3' | ||
spaceSize: 4096, | ||
nodeSizeMultiplier: 1, | ||
linkWidthMultiplier: 1, | ||
arrowSizeMultiplier: 1, | ||
nodeSizeScale: 1, | ||
linkWidthScale: 1, | ||
arrowSizeScale: 1, | ||
renderLinks: true, | ||
arrowLinks: true, | ||
minOpaqueLinkDist: 50, | ||
maxTransparentLinkDist: 150, | ||
clampLinkMinOpacity: 0.25, | ||
linkVisibilityDistanceRange: [50, 150], | ||
linkVisibilityMinTransparency: 0.25, | ||
useQuadtree: false, | ||
simulation: { | ||
@@ -19,0 +19,0 @@ decay: 1000, |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
263611
83
4842
1
117
6