declare module "ngraph.forcelayout" { import { Graph, NodeId, LinkId, Node, Link } from "ngraph.graph"; export type ForceFunction = (iterationNumber: number) => void; export interface Vector { x: number; y: number; z?: number; [coord: string]: number | undefined; } export interface Body { isPinned: boolean; pos: Vector; force: Vector; velocity: Vector; mass: number; springCount: number; springLength: number; reset(): void; setPosition(x: number, y: number, z?: number, ...c: number[]): void; } export interface Spring { from: Body; to: Body; length: number; coefficient: number; } export interface QuadNode { body: Body | null; mass: number; mass_x: number; mass_y: number; mass_z?: number; } export interface QuadTree { insertBodies(bodies: Body[]): void; getRoot(): QuadNode & Record; updateBodyForce(sourceBody: Body): void; options(newOptions: { gravity: number; theta: number }): { gravity: number; theta: number }; } export interface BoundingBox { min_x: number; max_x: number; min_y: number; max_y: number; min_z?: number; max_z?: number; [min_max: string]: number | undefined; } /** * Settings for a PhysicsSimulator */ export interface PhysicsSettings { /** * Ideal length for links (springs in physical model). */ springLength: number; /** * Hook's law coefficient. 1 - solid spring. */ springCoefficient: number; /** * Coulomb's law coefficient. It's used to repel nodes thus should be negative * if you make it positive nodes start attract each other :). */ gravity: number; /** * Theta coefficient from Barnes Hut simulation. Ranged between (0, 1). * The closer it's to 1 the more nodes algorithm will have to go through. * Setting it to one makes Barnes Hut simulation no different from * brute-force forces calculation (each node is considered). */ theta: number; /** * Drag force coefficient. Used to slow down system, thus should be less than 1. * The closer it is to 0 the less tight system will be. */ dragCoefficient: number; /** * Default time step (dt) for forces integration */ timeStep: number; /** * Adaptive time step uses average spring length to compute actual time step: * See: https://twitter.com/anvaka/status/1293067160755957760 */ adaptiveTimeStepWeight: number; /** * This parameter defines number of dimensions of the space where simulation * is performed. */ dimensions: number; /** * In debug mode more checks are performed, this will help you catch errors * quickly, however for production build it is recommended to turn off this flag * to speed up computation. */ debug: boolean; } /** * Manages a simulation of physical forces acting on bodies and springs. */ export interface PhysicsSimulator { /** * Array of bodies, registered with current simulator * * Note: To add new body, use addBody() method. This property is only * exposed for testing/performance purposes. */ bodies: Body[]; quadTree: QuadTree; /** * Array of springs, registered with current simulator * * Note: To add new spring, use addSpring() method. This property is only * exposed for testing/performance purposes. */ springs: Spring[]; /** * Returns settings with which current simulator was initialized */ settings: PhysicsSettings; /** * Adds a new force to simulation * @param forceName force identifier * @param forceFunction the function to apply */ addForce(forceName: string, forceFunction: ForceFunction): void; /** * Removes a force from the simulation * @param forceName force identifier */ removeForce(forceName: string): void; /** * Returns a map of all registered forces */ getForces(): Map; /** * Performs one step of force simulation. * * @returns true if system is considered stable; False otherwise. */ step(): boolean; /** * Adds body to the system * @param body physical body * @returns added body */ addBody(body: Body): Body; /** * Adds body to the system at given position * @param pos position of a body * @returns added body */ addBodyAt(pos: Vector): Body; /** * Removes body from the system * @param body to remove * @returns true if body found and removed. falsy otherwise; */ removeBody(body: Body): boolean; /** * Adds a spring to this simulation * @param body1 first body * @param body2 second body * @param springLength Ideal length for links * @param springCoefficient Hook's law coefficient. 1 - solid spring * @returns a handle for a spring. If you want to later remove * spring pass it to removeSpring() method. */ addSpring(body1: Body, body2: Body, springLength: number, springCoefficient: number): Spring; /** * Returns amount of movement performed on last step() call */ getTotalMovement(): number; /** * Removes spring from the system * @param spring to remove. Spring is an object returned by addSpring * @returns true if spring found and removed. falsy otherwise; */ removeSpring(spring: Spring): boolean; getBestNewBodyPosition(neighbors: Body[]): Vector; /** * Returns bounding box which covers all bodies */ getBBox(): BoundingBox; /** * Returns bounding box which covers all bodies */ getBoundingBox(): BoundingBox; /** @deprecated invalidateBBox() is deprecated, bounds always recomputed on `getBBox()` call */ invalidateBBox(): void; /** * Changes the gravity for the system * @param value Coulomb's law coefficient */ gravity(value: number): number; /** * Changes the theta coeffitient for the system * @param value Theta coefficient from Barnes Hut simulation */ theta(value: number): number; // TODO: create types declaration file for ngraph.random /** * Returns pseudo-random number generator instance */ random: any; } /** * Force based layout for a given graph. */ export interface Layout { /** * Performs one step of iterative layout algorithm * @returns true if the system should be considered stable; False otherwise. * The system is stable if no further call to `step()` can improve the layout. */ step(): boolean; /** * For a given `nodeId` returns position * @param nodeId node identifier */ getNodePosition(nodeId: NodeId): Vector; /** * Sets position of a node to a given coordinates * @param nodeId node identifier * @param x position of a node * @param y position of a node * @param z position of node (only if applicable to body) */ setNodePosition(nodeId: NodeId, x: number, y: number, z?: number, ...c: number[]): void; /** * Gets Link position by link id * @param linkId link identifier * @returns from: {x, y} coordinates of link start * @returns to: {x, y} coordinates of link end */ getLinkPosition(linkId: LinkId): { from: Vector; to: Vector }; /** * @returns area required to fit in the graph. Object contains * `x1`, `y1` - top left coordinates * `x2`, `y2` - bottom right coordinates */ getGraphRect(): { x1: number; y1: number; x2: number; y2: number }; /** * Iterates over each body in the layout simulator and performs a callback(body, nodeId) * @param callbackfn the callback function */ forEachBody(callbackfn: (value: Body, key: NodeId, map: Map) => void): void; /** * Requests layout algorithm to pin/unpin node to its current position * Pinned nodes should not be affected by layout algorithm and always * remain at their position * @param node the node to pin/unpin * @param isPinned true to pin, false to unpin */ pinNode(node: Node, isPinned: boolean): void; /** * Checks whether given graph's node is currently pinned * @param node the node to check */ isNodePinned(node: Node): boolean; /** * Request to release all resources */ dispose(): void; /** * Gets physical body for a given node id. If node is not found undefined * value is returned. * @param nodeId node identifier */ getBody(nodeId: NodeId): Body | undefined; /** * Gets spring for a given edge. * * @param linkId link identifer. */ getSpring(linkId: LinkId | Link): Spring; /** * Gets spring for a given edge. * * @param fromId node identifer - tail of the link * @param toId head of the link - head of the link */ getSpring(fromId: NodeId, toId: NodeId): Spring | undefined; /** * Returns length of cumulative force vector. The closer this to zero - the more stable the system is */ getForceVectorLength(): number; /** * @readonly Gets current physics simulator */ readonly simulator: PhysicsSimulator; /** * Gets the graph that was used for layout */ graph: T; /** * Gets amount of movement performed during last step operation */ lastMove: number; } /** * Creates force based layout for a given graph. * * @param graph which needs to be laid out * @param physicsSettings if you need custom settings * for physics simulator you can pass your own settings here. If it's not passed * a default one will be created. */ export default function createLayout( graph: T, physicsSettings?: Partial ): Layout; }