ThreeJS Force-Directed Graph ============================ [![NPM package][npm-img]][npm-url] [![Build Size][build-size-img]][build-size-url] [![Dependencies][dependencies-img]][dependencies-url]

A [ThreeJS](https://threejs.org/) WebGL class to represent a graph data structure in a 3-dimensional space using a force-directed iterative layout. Uses either [d3-force-3d](https://github.com/vasturiano/d3-force-3d) or [ngraph](https://github.com/anvaka/ngraph.forcelayout3d) for the underlying physics engine. ## Quick start ``` import ThreeForceGraph from 'three-forcegraph'; ``` or ``` var ThreeForceGraph = require('three-forcegraph'); ``` or even ``` ``` then ``` var myGraph = new ThreeForceGraph() .graphData(); var myScene = new THREE.Scene(); myScene.add(myGraph); ... // on animation frame myGraph.tickFrame(); ``` ## API reference | Method | Description | Default | | --- | --- | :--: | | graphData([data]) | Getter/setter for graph data structure (see below for syntax details). Can also be used to apply [incremental updates](https://bl.ocks.org/vasturiano/2f602ea6c51c664c29ec56cbe2d6a5f6). | `{ nodes: [], links: [] }` | | jsonUrl([url]) | URL of JSON file to load graph data directly from, as an alternative to specifying graphData directly. | | | numDimensions([int]) | Getter/setter for number of dimensions to run the force simulation on (1, 2 or 3). | 3 | | dagMode([str]) | Apply layout constraints based on the graph directionality. Only works correctly for [DAG](https://en.wikipedia.org/wiki/Directed_acyclic_graph) graph structures (without cycles). Choice between `td` (top-down), `bu` (bottom-up), `lr` (left-to-right), `rl` (right-to-left), `zout` (near-to-far), `zin` (far-to-near), `radialout` (outwards-radially) or `radialin` (inwards-radially). | | | dagLevelDistance([num]) | If `dagMode` is engaged, this specifies the distance between the different graph depths. | *auto-derived from the number of nodes* | | dagNodeFilter([fn]) | Node accessor function to specify nodes to ignore during the DAG layout processing. This accessor method receives a node object and should return a `boolean` value indicating whether the node is to be included. Excluded nodes will be left unconstrained and free to move in any direction. | `node => true` | | onDagError([fn]) | Callback to invoke if a cycle is encountered while processing the data structure for a DAG layout. The loop segment of the graph is included for information, as an array of node ids. By default an exception will be thrown whenever a loop is encountered. You can override this method to handle this case externally and allow the graph to continue the DAG processing. Strict graph directionality is not guaranteed if a loop is encountered and the result is a best effort to establish a hierarchy. | *throws exception* | | nodeRelSize([num]) | Getter/setter for the ratio of node sphere volume (cubic px) per value unit. | 4 | | nodeId([str]) | Node object accessor attribute for unique node id (used in link objects source/target). | `id` | | nodeVal([num, str or fn]) | Node object accessor function, attribute or a numeric constant for the node numeric value (affects sphere volume). | `val` | | nodeResolution([num]) | Getter/setter for the geometric resolution of each node, expressed in how many slice segments to divide the circumference. Higher values yield smoother spheres. | 8 | | nodeVisibility([boolean, str or fn]) | Node object accessor function, attribute or a boolean constant for whether to display the node. | `true` | | nodeColor([str or fn]) | Node object accessor function or attribute for node color (affects sphere color). | `color` | | nodeAutoColorBy([str or fn]) | Node object accessor function (`fn(node)`) or attribute (e.g. `'type'`) to automatically group colors by. Only affects nodes without a color attribute. | | | nodeOpacity([num]) | Getter/setter for all the nodes sphere opacity, between [0,1]. | 0.75 | | nodeThreeObject([Object3d, str or fn]) | Node object accessor function or attribute for generating a custom 3d object to render as graph nodes. Should return an instance of [ThreeJS Object3d](https://threejs.org/docs/index.html#api/core/Object3D). If a falsy value is returned, the default 3d object type will be used instead for that node. | *default node object is a sphere, sized according to `val` and styled according to `color`.* | | nodeThreeObjectExtend([bool, str or fn]) | Node object accessor function, attribute or a boolean value for whether to replace the default node when using a custom `nodeThreeObject` (`false`) or to extend it (`true`). | `false` | | linkSource([str]) | Link object accessor attribute referring to id of source node. | `source` | | linkTarget([str]) | Link object accessor attribute referring to id of target node. | `target` | | linkVisibility([boolean, str or fn]) | Link object accessor function, attribute or a boolean constant for whether to display the link line. A value of `false` maintains the link force without rendering it. | `true` | | linkColor([str or fn]) | Link object accessor function or attribute for line color. | `color` | | linkAutoColorBy([str or fn]) | Link object accessor function (`fn(link)`) or attribute (e.g. `'type'`) to automatically group colors by. Only affects links without a color attribute. | | | linkOpacity([num]) | Getter/setter for line opacity of all the links, between [0,1]. | 0.2 | | linkWidth([num, str or fn]) | Link object accessor function, attribute or a numeric constant for the link line width. A value of zero will render a [ThreeJS Line](https://threejs.org/docs/#api/objects/Line) whose width is constant (`1px`) regardless of distance. Values are rounded to the nearest decimal for indexing purposes. | 0 | | linkResolution([num]) | Getter/setter for the geometric resolution of each link, expressed in how many radial segments to divide the cylinder. Higher values yield smoother cylinders. Applicable only to links with positive width. | 6 | | linkCurvature([num, str or fn]) | Link object accessor function, attribute or a numeric constant for the curvature radius of the link line. Curved lines are represented as 3D bezier curves, and any numeric value is accepted. A value of `0` renders a straight line. `1` indicates a radius equal to half of the line length, causing the curve to approximate a semi-circle. For self-referencing links (`source` equal to `target`) the curve is represented as a loop around the node, with length proportional to the curvature value. Lines are curved clockwise for positive values, and counter-clockwise for negative values. Note that rendering curved lines is purely a visual effect and does not affect the behavior of the underlying forces. | 0 | | linkCurveRotation([num, str or fn]) | Link object accessor function, attribute or a numeric constant for the rotation along the line axis to apply to the curve. Has no effect on straight lines. At `0` rotation, the curve is oriented in the direction of the intersection with the `XY` plane. The rotation angle (in radians) will rotate the curved line clockwise around the "start-to-end" axis from this reference orientation. | 0 | | linkMaterial([Material, str or fn]) | Link object accessor function or attribute for specifying a custom material to style the graph links with. Should return an instance of [ThreeJS Material](https://threejs.org/docs/#api/materials/Material). If a falsy value is returned, the default material will be used instead for that link. | *default link material is [MeshLambertMaterial](https://threejs.org/docs/#api/materials/MeshLambertMaterial) styled according to `color` and `opacity`.* | | linkThreeObject([Object3d, str or fn]) | Link object accessor function or attribute for generating a custom 3d object to render as graph links. Should return an instance of [ThreeJS Object3d](https://threejs.org/docs/index.html#api/core/Object3D). If a falsy value is returned, the default 3d object type will be used instead for that link. | *default link object is a line or cylinder, sized according to `width` and styled according to `material`.* | | linkThreeObjectExtend([bool, str or fn]) | Link object accessor function, attribute or a boolean value for whether to replace the default link when using a custom `linkThreeObject` (`false`) or to extend it (`true`). | `false` | | linkPositionUpdate([fn(linkObject, { start, end }, link)]) | Getter/setter for the custom function to call for updating the position of links at every render iteration. It receives the respective link `ThreeJS Object3d`, the `start` and `end` coordinates of the link (`{x,y,z}` each), and the link's `data`. If the function returns a truthy value, the regular position update function will not run for that link. | | | linkDirectionalArrowLength([num, str or fn]) | Link object accessor function, attribute or a numeric constant for the length of the arrow head indicating the link directionality. The arrow is displayed directly over the link line, and points in the direction of `source` > `target`. A value of `0` hides the arrow. | 0 | | linkDirectionalArrowColor([str or fn]) | Link object accessor function or attribute for the color of the arrow head. | `color` | | linkDirectionalArrowRelPos([num, str or fn]) | Link object accessor function, attribute or a numeric constant for the longitudinal position of the arrow head along the link line, expressed as a ratio between `0` and `1`, where `0` indicates immediately next to the `source` node, `1` next to the `target` node, and `0.5` right in the middle. | 0.5 | | linkDirectionalArrowResolution([num]) | Getter/setter for the geometric resolution of the arrow head, expressed in how many slice segments to divide the cone base circumference. Higher values yield smoother arrows. | 8 | | linkDirectionalParticles([num, str or fn]) | Link object accessor function, attribute or a numeric constant for the number of particles (small spheres) to display over the link line. The particles are distributed equi-spaced along the line, travel in the direction `source` > `target`, and can be used to indicate link directionality. | 0 | | linkDirectionalParticleSpeed([num, str or fn]) | Link object accessor function, attribute or a numeric constant for the directional particles speed, expressed as the ratio of the link length to travel per frame. Values above `0.5` are discouraged. | 0.01 | | linkDirectionalParticleWidth([num, str or fn]) | Link object accessor function, attribute or a numeric constant for the directional particles width. Values are rounded to the nearest decimal for indexing purposes. | 0.5 | | linkDirectionalParticleColor([str or fn]) | Link object accessor function or attribute for the directional particles color. | `color` | | linkDirectionalParticleResolution([num]) | Getter/setter for the geometric resolution of each directional particle, expressed in how many slice segments to divide the circumference. Higher values yield smoother particles. | 4 | | emitParticle(link) | An alternative mechanism for generating particles, this method emits a non-cyclical single particle within a specific link. The emitted particle shares the styling (speed, width, color) of the regular particle props. A valid `link` object that is included in `graphData` should be passed as a single parameter. || | getGraphBbox([nodeFilterFn]) | Returns the current bounding box of the nodes in the graph, formatted as `{ x: [, ], y: [, ], z: [, ] }`. If no nodes are found, returns `null`. Accepts an optional argument to define a custom node filter: `node => `, which should return a truthy value if the node is to be included. This can be useful to calculate the bounding box of a portion of the graph. || | forceEngine([str]) | Getter/setter for which force-simulation engine to use ([*d3*](https://github.com/vasturiano/d3-force-3d) or [*ngraph*](https://github.com/anvaka/ngraph.forcelayout)). | `d3` | | d3ReheatSimulation() | Reheats the force simulation engine, by setting the `alpha` value to `1`. Only applicable if using the d3 simulation engine. | | | d3AlphaMin([num]) | Getter/setter for the [simulation alpha min](https://github.com/vasturiano/d3-force-3d#simulation_alphaMin) parameter, only applicable if using the d3 simulation engine. | `0` | | d3AlphaDecay([num]) | Getter/setter for the [simulation intensity decay](https://github.com/vasturiano/d3-force-3d#simulation_alphaDecay) parameter, only applicable if using the d3 simulation engine. | `0.0228` | | d3VelocityDecay([num]) | Getter/setter for the nodes' [velocity decay](https://github.com/vasturiano/d3-force-3d#simulation_velocityDecay) that simulates the medium resistance, only applicable if using the d3 simulation engine. | `0.4` | | d3Force(str, [fn]) | Getter/setter for the internal forces that control the d3 simulation engine. Follows the same interface as `d3-force-3d`'s [simulation.force](https://github.com/vasturiano/d3-force-3d#simulation_force). Three forces are included by default: `'link'` (based on [forceLink](https://github.com/vasturiano/d3-force-3d#forceLink)), `'charge'` (based on [forceManyBody](https://github.com/vasturiano/d3-force-3d#forceManyBody)) and `'center'` (based on [forceCenter](https://github.com/vasturiano/d3-force-3d#forceCenter)). Each of these forces can be reconfigured, or new forces can be added to the system. This method is only applicable if using the d3 simulation engine. | | | ngraphPhysics([object]) | Specify custom physics configuration for ngraph, according to its [configuration object](https://github.com/anvaka/ngraph.forcelayout#physics-simulator) syntax. This method is only applicable if using the ngraph simulation engine. | *ngraph default* | | warmupTicks([int]) | Getter/setter for number of layout engine cycles to dry-run at ignition before starting to render. | 0 | | cooldownTicks([int]) | Getter/setter for how many build-in frames to render before stopping and freezing the layout engine. | Infinity | | cooldownTime([num]) | Getter/setter for how long (ms) to render for before stopping and freezing the layout engine. | 15000 | | onEngineTick(fn) | Callback function invoked at every tick of the simulation engine. | - | | onEngineStop(fn) | Callback function invoked when the simulation engine stops and the layout is frozen. | - | | onLoading(fn) | Callback function for notification that data is being loaded asynchronously based on `jsonUrl`. | - | | onFinishLoading(fn) | Callback function for notification that the component has finished loading data asynchronously. | - | | onUpdate(fn) | Callback function for notification that the component has started updating and the simulation engine is temporarily paused. | - | | onFinishUpdate(fn) | Callback function for notification that the component has finished updating, done iterating through the warmup phase (if needed) and the simulation engine has been resumed. | - | | tickFrame() | This method should be called on each cycle of the global renderer to iterate the underlying force simulation engine and update the nodes/links objects' positions. || | resetProps() | Reset all object properties to their default value. || | refresh() | Redraws all the nodes/links. || ### Input JSON syntax ``` { "nodes": [ { "id": "id1", "name": "name1", "val": 1 }, { "id": "id2", "name": "name2", "val": 10 }, (...) ], "links": [ { "source": "id1", "target": "id2" }, (...) ] } ``` ## Giving Back [![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=L398E7PKP47E8¤cy_code=USD&source=url) If this project has helped you and you'd like to contribute back, you can always [buy me a ☕](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=L398E7PKP47E8¤cy_code=USD&source=url)! [npm-img]: https://img.shields.io/npm/v/three-forcegraph.svg [npm-url]: https://npmjs.org/package/three-forcegraph [build-size-img]: https://img.shields.io/bundlephobia/minzip/three-forcegraph.svg [build-size-url]: https://bundlephobia.com/result?p=three-forcegraph [dependencies-img]: https://img.shields.io/david/vasturiano/three-forcegraph.svg [dependencies-url]: https://david-dm.org/vasturiano/three-forcegraph