index.d.ts 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. declare module "ngraph.forcelayout" {
  2. import { Graph, NodeId, LinkId, Node, Link } from "ngraph.graph";
  3. export type ForceFunction = (iterationNumber: number) => void;
  4. export interface Vector {
  5. x: number;
  6. y: number;
  7. z?: number;
  8. [coord: `c${number}`]: number
  9. }
  10. export interface Body {
  11. isPinned: boolean;
  12. pos: Vector;
  13. force: Vector;
  14. velocity: Vector;
  15. mass: number;
  16. springCount: number;
  17. springLength: number;
  18. reset(): void;
  19. setPosition(x: number, y: number, z?: number, ...c: number[]): void;
  20. }
  21. export interface Spring {
  22. from: Body;
  23. to: Body;
  24. length: number;
  25. coefficient: number;
  26. }
  27. export interface QuadNode {
  28. body: Body | null;
  29. mass: number;
  30. mass_x: number;
  31. mass_y: number;
  32. mass_z?: number;
  33. [mass: `mass_c${number}`]: number | null;
  34. [mass: `min_c${number}`]: number | null;
  35. [mass: `max_c${number}`]: number | null;
  36. [quad: `quad${number}`]: number | null;
  37. }
  38. export interface QuadTree {
  39. insertBodies(bodies: Body[]): void;
  40. getRoot(): QuadNode;
  41. updateBodyForce(sourceBody: Body): void;
  42. options(newOptions: { gravity: number; theta: number }): { gravity: number; theta: number };
  43. }
  44. export interface BoundingBox {
  45. min_x: number;
  46. max_x: number;
  47. min_y: number;
  48. max_y: number;
  49. min_z?: number;
  50. max_z?: number;
  51. [min: `min_c${number}`]: number;
  52. [max: `max_c${number}`]: number;
  53. }
  54. /**
  55. * Settings for a PhysicsSimulator
  56. */
  57. export interface PhysicsSettings {
  58. /**
  59. * Ideal length for links (springs in physical model).
  60. */
  61. springLength: number;
  62. /**
  63. * Hook's law coefficient. 1 - solid spring.
  64. */
  65. springCoefficient: number;
  66. /**
  67. * Coulomb's law coefficient. It's used to repel nodes thus should be negative
  68. * if you make it positive nodes start attract each other :).
  69. */
  70. gravity: number;
  71. /**
  72. * Theta coefficient from Barnes Hut simulation. Ranged between (0, 1).
  73. * The closer it's to 1 the more nodes algorithm will have to go through.
  74. * Setting it to one makes Barnes Hut simulation no different from
  75. * brute-force forces calculation (each node is considered).
  76. */
  77. theta: number;
  78. /**
  79. * Drag force coefficient. Used to slow down system, thus should be less than 1.
  80. * The closer it is to 0 the less tight system will be.
  81. */
  82. dragCoefficient: number;
  83. /**
  84. * Default time step (dt) for forces integration
  85. */
  86. timeStep: number;
  87. /**
  88. * Adaptive time step uses average spring length to compute actual time step:
  89. * See: https://twitter.com/anvaka/status/1293067160755957760
  90. */
  91. adaptiveTimeStepWeight: number;
  92. /**
  93. * This parameter defines number of dimensions of the space where simulation
  94. * is performed.
  95. */
  96. dimensions: number;
  97. /**
  98. * In debug mode more checks are performed, this will help you catch errors
  99. * quickly, however for production build it is recommended to turn off this flag
  100. * to speed up computation.
  101. */
  102. debug: boolean;
  103. }
  104. /**
  105. * Manages a simulation of physical forces acting on bodies and springs.
  106. */
  107. export interface PhysicsSimulator {
  108. /**
  109. * Array of bodies, registered with current simulator
  110. *
  111. * Note: To add new body, use addBody() method. This property is only
  112. * exposed for testing/performance purposes.
  113. */
  114. bodies: Body[];
  115. quadTree: QuadTree;
  116. /**
  117. * Array of springs, registered with current simulator
  118. *
  119. * Note: To add new spring, use addSpring() method. This property is only
  120. * exposed for testing/performance purposes.
  121. */
  122. springs: Spring[];
  123. /**
  124. * Returns settings with which current simulator was initialized
  125. */
  126. settings: PhysicsSettings;
  127. /**
  128. * Adds a new force to simulation
  129. * @param forceName force identifier
  130. * @param forceFunction the function to apply
  131. */
  132. addForce(forceName: string, forceFunction: ForceFunction): void;
  133. /**
  134. * Removes a force from the simulation
  135. * @param forceName force identifier
  136. */
  137. removeForce(forceName: string): void;
  138. /**
  139. * Returns a map of all registered forces
  140. */
  141. getForces(): Map<string, ForceFunction>;
  142. /**
  143. * Performs one step of force simulation.
  144. *
  145. * @returns true if system is considered stable; False otherwise.
  146. */
  147. step(): boolean;
  148. /**
  149. * Adds body to the system
  150. * @param body physical body
  151. * @returns added body
  152. */
  153. addBody(body: Body): Body;
  154. /**
  155. * Adds body to the system at given position
  156. * @param pos position of a body
  157. * @returns added body
  158. */
  159. addBodyAt(pos: Vector): Body;
  160. /**
  161. * Removes body from the system
  162. * @param body to remove
  163. * @returns true if body found and removed. falsy otherwise;
  164. */
  165. removeBody(body: Body): boolean;
  166. /**
  167. * Adds a spring to this simulation
  168. * @param body1 first body
  169. * @param body2 second body
  170. * @param springLength Ideal length for links
  171. * @param springCoefficient Hook's law coefficient. 1 - solid spring
  172. * @returns a handle for a spring. If you want to later remove
  173. * spring pass it to removeSpring() method.
  174. */
  175. addSpring(body1: Body, body2: Body, springLength: number, springCoefficient: number): Spring;
  176. /**
  177. * Returns amount of movement performed on last step() call
  178. */
  179. getTotalMovement(): number;
  180. /**
  181. * Removes spring from the system
  182. * @param spring to remove. Spring is an object returned by addSpring
  183. * @returns true if spring found and removed. falsy otherwise;
  184. */
  185. removeSpring(spring: Spring): boolean;
  186. getBestNewBodyPosition(neighbors: Body[]): Vector;
  187. /**
  188. * Returns bounding box which covers all bodies
  189. */
  190. getBBox(): BoundingBox;
  191. /**
  192. * Returns bounding box which covers all bodies
  193. */
  194. getBoundingBox(): BoundingBox;
  195. /** @deprecated invalidateBBox() is deprecated, bounds always recomputed on `getBBox()` call */
  196. invalidateBBox(): void;
  197. /**
  198. * Changes the gravity for the system
  199. * @param value Coulomb's law coefficient
  200. */
  201. gravity(value: number): number;
  202. /**
  203. * Changes the theta coeffitient for the system
  204. * @param value Theta coefficient from Barnes Hut simulation
  205. */
  206. theta(value: number): number;
  207. // TODO: create types declaration file for ngraph.random
  208. /**
  209. * Returns pseudo-random number generator instance
  210. */
  211. random: any;
  212. }
  213. /**
  214. * Force based layout for a given graph.
  215. */
  216. export interface Layout<T extends Graph> {
  217. /**
  218. * Performs one step of iterative layout algorithm
  219. * @returns true if the system should be considered stable; False otherwise.
  220. * The system is stable if no further call to `step()` can improve the layout.
  221. */
  222. step(): boolean;
  223. /**
  224. * For a given `nodeId` returns position
  225. * @param nodeId node identifier
  226. */
  227. getNodePosition(nodeId: NodeId): Vector;
  228. /**
  229. * Sets position of a node to a given coordinates
  230. * @param nodeId node identifier
  231. * @param x position of a node
  232. * @param y position of a node
  233. * @param z position of node (only if applicable to body)
  234. */
  235. setNodePosition(nodeId: NodeId, x: number, y: number, z?: number, ...c: number[]): void;
  236. /**
  237. * Gets Link position by link id
  238. * @param linkId link identifier
  239. * @returns from: {x, y} coordinates of link start
  240. * @returns to: {x, y} coordinates of link end
  241. */
  242. getLinkPosition(linkId: LinkId): { from: Vector; to: Vector };
  243. /**
  244. * @returns area required to fit in the graph. Object contains
  245. * `x1`, `y1` - top left coordinates
  246. * `x2`, `y2` - bottom right coordinates
  247. */
  248. getGraphRect(): { x1: number; y1: number; x2: number; y2: number };
  249. /**
  250. * Iterates over each body in the layout simulator and performs a callback(body, nodeId)
  251. * @param callbackfn the callback function
  252. */
  253. forEachBody(callbackfn: (value: Body, key: NodeId, map: Map<NodeId, Body>) => void): void;
  254. /**
  255. * Requests layout algorithm to pin/unpin node to its current position
  256. * Pinned nodes should not be affected by layout algorithm and always
  257. * remain at their position
  258. * @param node the node to pin/unpin
  259. * @param isPinned true to pin, false to unpin
  260. */
  261. pinNode(node: Node, isPinned: boolean): void;
  262. /**
  263. * Checks whether given graph's node is currently pinned
  264. * @param node the node to check
  265. */
  266. isNodePinned(node: Node): boolean;
  267. /**
  268. * Request to release all resources
  269. */
  270. dispose(): void;
  271. /**
  272. * Gets physical body for a given node id. If node is not found undefined
  273. * value is returned.
  274. * @param nodeId node identifier
  275. */
  276. getBody(nodeId: NodeId): Body | undefined;
  277. /**
  278. * Gets spring for a given edge.
  279. *
  280. * @param linkId link identifer.
  281. */
  282. getSpring(linkId: LinkId | Link): Spring;
  283. /**
  284. * Gets spring for a given edge.
  285. *
  286. * @param fromId node identifer - tail of the link
  287. * @param toId head of the link - head of the link
  288. */
  289. getSpring(fromId: NodeId, toId: NodeId): Spring | undefined;
  290. /**
  291. * Returns length of cumulative force vector. The closer this to zero - the more stable the system is
  292. */
  293. getForceVectorLength(): number;
  294. /**
  295. * @readonly Gets current physics simulator
  296. */
  297. readonly simulator: PhysicsSimulator;
  298. /**
  299. * Gets the graph that was used for layout
  300. */
  301. graph: T;
  302. /**
  303. * Gets amount of movement performed during last step operation
  304. */
  305. lastMove: number;
  306. }
  307. /**
  308. * Creates force based layout for a given graph.
  309. *
  310. * @param graph which needs to be laid out
  311. * @param physicsSettings if you need custom settings
  312. * for physics simulator you can pass your own settings here. If it's not passed
  313. * a default one will be created.
  314. */
  315. export default function createLayout<T extends Graph>(
  316. graph: T,
  317. physicsSettings?: Partial<PhysicsSettings>
  318. ): Layout<T>;
  319. }