================ CODE SNIPPETS ================ ### Quick Start: Initialize 3D Force Graph Instance Source: https://github.com/vasturiano/3d-force-graph/blob/master/README.md This snippet illustrates the basic initialization of a 'ForceGraph3D' instance. It takes a DOM element as a container for the graph and then loads graph data, setting up the 3D visualization. ```js const myGraph = new ForceGraph3D() .graphData(); ``` -------------------------------- ### Initialize 3D Force Graph with Random Tree Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/directional-links-arrows/index.html Generates a random tree structure with 40 nodes and initializes a 3D force-directed graph using the ForceGraph3D library. It configures link directional arrows and curvature for visual clarity. ```JavaScript const N = 40; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .graphData(gData) .linkDirectionalArrowLength(3.5) .linkDirectionalArrowRelPos(1) .linkCurvature(0.25); ``` -------------------------------- ### Initialize 3D Force Graph with Random Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/fit-to-canvas/index.html This JavaScript snippet initializes a 3D force-directed graph using the ForceGraph3D library. It generates a random tree structure with 300 nodes and links, configures the graph with a cooldown period, and sets it to zoom to fit the canvas once the physics simulation engine stops. ```JavaScript const N = 300; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .cooldownTicks(100) .graphData(gData); // fit to canvas when engine stops Graph.onEngineStop(() => Graph.zoomToFit(400)); ``` -------------------------------- ### Initialize 3D Force Graph with Random Tree Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/basic/index.html This JavaScript code generates a random tree structure with 300 nodes and initializes a 3D force-directed graph. It uses the ForceGraph3D library to render the graph, attaching it to an HTML element with the ID '3d-graph'. The data includes nodes with unique IDs and links connecting them in a tree-like fashion. ```JavaScript const N = 300; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .graphData(gData); ``` -------------------------------- ### Basic CSS for Full-Page Display Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/directional-links-arrows/index.html Sets the body margin to zero to ensure the graph occupies the full viewport without default browser spacing, providing a clean canvas for the 3D graph. ```CSS body { margin: 0; } ``` -------------------------------- ### Initialize 3D Force Graph with JSON Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/async-load/index.html Initializes a new instance of ForceGraph3D, attaching it to a specified DOM element. It then configures the graph to load data from a JSON URL, sets the node label property to 'id', and automatically colors nodes based on their 'group' property. ```JavaScript const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .jsonUrl('../datasets/miserables.json') .nodeLabel('id') .nodeAutoColorBy('group'); ``` -------------------------------- ### Basic CSS Body Styling Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/fit-to-canvas/index.html Sets the margin of the HTML body element to zero, effectively removing any default browser spacing around the page content. ```CSS body { margin: 0; } ``` -------------------------------- ### Quick Start: Include 3D Force Graph via Script Tag Source: https://github.com/vasturiano/3d-force-graph/blob/master/README.md This snippet shows how to include the '3d-force-graph' library directly in an HTML file using a ' ``` -------------------------------- ### Initializing 3D Force Graph with Custom Link Properties Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/curved-links/index.html This JavaScript snippet initializes a `ForceGraph3D` instance, attaching it to an HTML element with the ID '3d-graph'. It configures various link properties such as `linkCurvature`, `linkCurveRotation`, and `linkDirectionalParticles`, and then loads the previously defined `gData` into the graph. ```JavaScript const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .linkCurvature('curvature') .linkCurveRotation('rotation') .linkDirectionalParticles(2) .graphData(gData); ``` -------------------------------- ### Initialize 3D Force Graph with Random Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/auto-colored/index.html Generates a dataset of random nodes and links, then initializes a ForceGraph3D instance. It configures the graph to automatically color nodes by their assigned group and links based on the source node's group, setting a link opacity of 0.5. ```JavaScript // Random tree const NODES = 300; const GROUPS = 12; const gData = { nodes: [...Array(NODES).keys()].map(i => ({ id: i, group: Math.ceil(Math.random() * GROUPS) })), links: [...Array(NODES).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .nodeAutoColorBy('group') .linkAutoColorBy(d => gData.nodes[d.source].group) .linkOpacity(0.5) .graphData(gData); ``` -------------------------------- ### Quick Start: Import 3D Force Graph in JavaScript Source: https://github.com/vasturiano/3d-force-graph/blob/master/README.md This snippet demonstrates how to import the 'ForceGraph3D' module using ES6 'import' syntax. This is the recommended way for modern JavaScript projects, allowing the module to be integrated into your application's build process. ```js import ForceGraph3D from '3d-force-graph'; ``` -------------------------------- ### Basic CSS Body Styling Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/async-load/index.html Applies a fundamental CSS rule to remove default margin from the body element, which is often necessary to allow canvas-based visualizations like 3D graphs to occupy the full viewport without scrollbars. ```CSS body { margin: 0; } ``` -------------------------------- ### Basic CSS Body Styling Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/auto-colored/index.html Applies a fundamental CSS rule to remove the default margin from the body element, ensuring the 3D graph can occupy the full viewport without unwanted spacing. ```CSS body { margin: 0; } ``` -------------------------------- ### Defining Graph Data for 3D Force Graph Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/curved-links/index.html This JavaScript snippet defines the `gData` object, which contains nodes and links for a 3D force-directed graph. It includes various link configurations, demonstrating different curvatures and rotations, as well as self-loops and multiple links between the same nodes. ```JavaScript const gData = { nodes: [...Array(14).keys()].map(i => ({ id: i })), links: [ { source: 0, target: 1, curvature: 0, rotation: 0 }, { source: 0, target: 1, curvature: 0.8, rotation: 0 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 1 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 2 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 3 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 4 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 5 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 7 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 8 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 9 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 10 / 6 }, { source: 0, target: 1, curvature: 0.8, rotation: Math.PI * 11 / 6 }, { source: 2, target: 3, curvature: 0.4, rotation: 0 }, { source: 3, target: 2, curvature: 0.4, rotation: Math.PI / 2 }, { source: 2, target: 3, curvature: 0.4, rotation: Math.PI }, { source: 3, target: 2, curvature: 0.4, rotation: -Math.PI / 2 }, { source: 4, target: 4, curvature: 0.3, rotation: 0 }, { source: 4, target: 4, curvature: 0.3, rotation: Math.PI * 2 / 3 }, { source: 4, target: 4, curvature: 0.3, rotation: Math.PI * 4 / 3 }, { source: 5, target: 6, curvature: 0, rotation: 0 }, { source: 5, target: 5, curvature: 0.5, rotation: 0 }, { source: 6, target: 6, curvature: -0.5, rotation: 0 }, { source: 7, target: 8, curvature: 0.2, rotation: 0 }, { source: 8, target: 9, curvature: 0.5, rotation: 0 }, { source: 9, target: 10, curvature: 0.7, rotation: 0 }, { source: 10, target: 11, curvature: 1, rotation: 0 }, { source: 11, target: 12, curvature: 2, rotation: 0 }, { source: 12, target: 7, curvature: 4, rotation: 0 }, { source: 13, target: 13, curvature: 0.1, rotation: 0 }, { source: 13, target: 13, curvature: 0.2, rotation: 0 }, { source: 13, target: 13, curvature: 0.5, rotation: 0 }, { source: 13, target: 13, curvature: 0.7, rotation: 0 }, { source: 13, target: 13, curvature: 1, rotation: 0 } ] }; ``` -------------------------------- ### Basic CSS Body Margin Reset Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/basic/index.html This CSS snippet resets the default margin of the HTML body element to zero. This is a common practice to ensure that the content fills the entire viewport without browser-default spacing. ```CSS body { margin: 0; } ``` -------------------------------- ### Resetting Body Margin with CSS Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/curved-links/index.html This CSS snippet removes the default margin from the `body` element, ensuring the content starts at the very edge of the viewport. This is a common practice for full-bleed layouts. ```CSS body { margin: 0; } ``` -------------------------------- ### Basic CSS Body Reset Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/custom-node-geometry/index.html This CSS snippet removes the default margin from the HTML body element, ensuring the content starts directly at the edge of the viewport. ```css body { margin: 0; } ``` -------------------------------- ### Initialize and Customize a 3D Force Graph with Custom Links Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/gradient-links/index.html This JavaScript code initializes a 3D force-directed graph using `ForceGraph3D`. It generates random nodes and links, applies a D3 color scale for node coloring, and implements custom link rendering. The custom rendering includes dynamic link colors based on connected node colors and precise link position updates to start and end at the node surfaces, rather than their centers. ```JavaScript import * as THREE from 'https://esm.sh/three'; import { scaleOrdinal, schemeRdYlGn, color as d3Color } from 'https://esm.sh/d3'; // Random tree const N = 25; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const nodeColorScale = scaleOrdinal(schemeRdYlGn[4]); const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .nodeColor(node => nodeColorScale(node.id)) .linkThreeObject(link => { // 2 (nodes) x 3 (r+g+b) bytes between [0, 1] // For example: // new Float32Array([ // 1, 0, 0, // source node: red // 0, 1, 0 // target node: green // ]); const colors = new Float32Array([ ].concat( ...[link.source, link.target] .map(nodeColorScale) .map(d3Color) .map(({ r, g, b }) => [r, g, b].map(v => v / 255)) ) ); const material = new THREE.LineBasicMaterial({ vertexColors: true }); const geometry = new THREE.BufferGeometry(); geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(2 * 3), 3)); geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); return new THREE.Line(geometry, material); }) .linkPositionUpdate((line, { start, end }) => { const startR = Graph.nodeRelSize(); const endR = Graph.nodeRelSize(); const lineLen = Math.sqrt(['x', 'y', 'z'].map(dim => Math.pow((end[dim] || 0) - (start[dim] || 0), 2)).reduce((acc, v) => acc + v, 0)); const linePos = line.geometry.getAttribute('position'); // calculate coordinate on the node's surface instead of center linePos.set([ startR / lineLen, 1 - endR / lineLen ].map(t => ['x', 'y', 'z'].map(dim => start[dim] + (end[dim] - start[dim]) * t) ).flat()); linePos.needsUpdate = true; return true; }) .graphData(gData); ``` -------------------------------- ### Initialize and Configure a 3D Force Graph Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/tree/index.html Initializes the `ForceGraph3D` instance, configuring its visual and physical properties. This includes setting background color, link appearance, node sizing, labeling, coloring, and applying D3 forces like collision and charge to simulate graph dynamics. ```JavaScript import { forceCollide } from 'https://esm.sh/d3-force-3d'; const NODE_REL_SIZE = 1; const graph = new ForceGraph3D(document.getElementById('graph')) .dagMode('td') .dagLevelDistance(200) .backgroundColor('#101020') .linkColor(() => 'rgba(255,255,255,0.2)') .nodeRelSize(NODE_REL_SIZE) .nodeId('path') .nodeVal('size') .nodeLabel('path') .nodeAutoColorBy('module') .nodeOpacity(0.9) .linkDirectionalParticles(2) .linkDirectionalParticleWidth(0.8) .linkDirectionalParticleSpeed(0.006) .d3Force('collision', forceCollide(node => Math.cbrt(node.size) * NODE_REL_SIZE)) .d3VelocityDecay(0.3); // Decrease repel intensity graph.d3Force('charge').strength(-15); ``` -------------------------------- ### Initialize and Configure 3D Force Graph Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/large-graph/index.html Initializes a 3D force graph instance, loads data from a JSON URL, automatically colors nodes based on a 'user' property, sets node labels using template literals, and defines a click handler to open a new browser window with a related URL. ```JavaScript const elem = document.getElementById('3d-graph'); const Graph = new ForceGraph3D(elem) .jsonUrl('../datasets/blocks.json') .nodeAutoColorBy('user') .nodeLabel(node => `${node.user}: ${node.description}`) .onNodeClick(node => window.open(`https://bl.ocks.org/${node.user}/${node.id}`, '_blank')); ``` -------------------------------- ### Initialize 3D Force Graph with Random Data and Responsiveness Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/responsive/index.html This JavaScript snippet imports the `element-resize-detector` library, generates a random tree structure for graph data, initializes a `ForceGraph3D` instance on a specified DOM element, and sets up a listener to dynamically adjust the graph's width when its container resizes. ```JavaScript import elementResizeDetectorMaker from 'https://esm.sh/element-resize-detector'; // Random tree const N = 300; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .height(window.innerHeight - 60) .graphData(gData); elementResizeDetectorMaker().listenTo( document.getElementById('3d-graph'), el => Graph.width(el.offsetWidth) ); ``` -------------------------------- ### Initialize 3D Force Graph and Handle Node Clicks Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/click-to-focus/index.html This JavaScript code initializes a 3D force-directed graph using the ForceGraph3D library. It loads graph data from a JSON URL, configures node labeling and coloring, and implements an onNodeClick event handler. The handler calculates a new camera position to smoothly transition and focus on the clicked node, providing an interactive zoom effect. ```JavaScript const elem = document.getElementById('3d-graph'); const Graph = new ForceGraph3D(elem) .jsonUrl('../datasets/miserables.json') .nodeLabel('id') .nodeAutoColorBy('group') .onNodeClick(node => { // Aim at node from outside it const distance = 40; const distRatio = 1 + distance/Math.hypot(node.x, node.y, node.z); const newPos = node.x || node.y || node.z ? { x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio } : { x: 0, y: 0, z: distance }; // special case if node is in (0,0,0) Graph.cameraPosition( newPos, // new position node, // lookAt ({ x, y, z }) 3000 // ms transition duration ); }); ``` -------------------------------- ### Initialize 3D Force Graph with Random Data and Hover Effects Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/highlight/index.html Generates a random tree-like graph structure with 80 nodes and links. Initializes a 3D force-directed graph using the ForceGraph3D library, configuring node and link colors, widths, and directional particles. Implements interactive hover effects to highlight nodes, their neighbors, and connected links, dynamically updating the graph's appearance. ```JavaScript // Random tree const N = 80; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; // cross-link node objects gData.links.forEach(link => { const a = gData.nodes[link.source]; const b = gData.nodes[link.target]; !a.neighbors && (a.neighbors = []); !b.neighbors && (b.neighbors = []); a.neighbors.push(b); b.neighbors.push(a); !a.links && (a.links = []); !b.links && (b.links = []); a.links.push(link); b.links.push(link); }); const highlightNodes = new Set(); const highlightLinks = new Set(); let hoverNode = null; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .graphData(gData) .nodeColor(node => highlightNodes.has(node) ? node === hoverNode ? 'rgb(255,0,0,1)' : 'rgba(255,160,0,0.8)' : 'rgba(0,255,255,0.6)') .linkWidth(link => highlightLinks.has(link) ? 4 : 1) .linkDirectionalParticles(link => highlightLinks.has(link) ? 4 : 0) .linkDirectionalParticleWidth(4) .onNodeHover(node => { // no state change if ((!node && !highlightNodes.size) || (node && hoverNode === node)) return; highlightNodes.clear(); highlightLinks.clear(); if (node) { highlightNodes.add(node); node.neighbors.forEach(neighbor => highlightNodes.add(neighbor)); node.links.forEach(link => highlightLinks.add(link)); } hoverNode = node || null; updateHighlight(); }) .onLinkHover(link => { highlightNodes.clear(); highlightLinks.clear(); if (link) { highlightLinks.add(link); highlightNodes.add(link.source); highlightNodes.add(link.target); } updateHighlight(); }); function updateHighlight() { // trigger update of highlighted objects in scene Graph .nodeColor(Graph.nodeColor()) .linkWidth(Graph.linkWidth()) .linkDirectionalParticles(Graph.linkDirectionalParticles()); } ``` -------------------------------- ### Initialize 3D Force Graph with Data and Customizations Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/directional-links-particles/index.html Initializes a 3D force-directed graph using the ForceGraph3D library. It loads graph data from a specified JSON URL, configures node labeling and automatic coloring based on a 'group' property, and sets up animated directional particles on links with speed proportional to their 'value' property. ```javascript const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .jsonUrl('../datasets/miserables.json') .nodeLabel('id') .nodeAutoColorBy('group') .linkDirectionalParticles("value") .linkDirectionalParticleSpeed(d => d.value * 0.001); ``` -------------------------------- ### API Reference: ForceGraph3D Initialization Source: https://github.com/vasturiano/3d-force-graph/blob/master/README.md This section details the initialization parameters for the 'ForceGraph3D' constructor. It covers configuration options like 'controlType' for camera controls, 'rendererConfig' for ThreeJS WebGLRenderer settings, and 'extraRenderers' for including custom renderer instances. ```APIDOC new ForceGraph3d(, { configOptions }) Config options: controlType: str Description: Which type of control to use to control the camera. Choice between [trackball](https://threejs.org/examples/misc_controls_trackball.html), [orbit](https://threejs.org/examples/#misc_controls_orbit) or [fly](https://threejs.org/examples/misc_controls_fly.html). Default: trackball rendererConfig: object Description: Configuration parameters to pass to the [ThreeJS WebGLRenderer](https://threejs.org/docs/#api/en/renderers/WebGLRenderer) constructor. Default: { antialias: true, alpha: true } extraRenderers: array Description: If you wish to include custom objects that require a dedicated renderer besides WebGL, such as [CSS3DRenderer](https://threejs.org/docs/#examples/en/renderers/CSS3DRenderer), include in this array those extra renderer instances. Default: [] ``` -------------------------------- ### Initialize 3D Force Graph with Random Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/pause-resume/index.html Sets up a 3D force graph instance using the ForceGraph3D library. It populates the graph with randomly generated nodes and links, configures the initial camera position, and disables default navigation controls and node dragging. ```JavaScript // Random tree const N = 300; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const distance = 1400; let isRotationActive = true; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .enableNodeDrag(false) .enableNavigationControls(false) .showNavInfo(false) .cameraPosition({ z: distance }) .graphData(gData); ``` -------------------------------- ### Initialize and Animate 3D Force Graph Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/dynamic/index.html Initializes a ForceGraph3D instance, disables node dragging, and sets up an interval to continuously add new nodes and random links to the graph every second. This demonstrates dynamic graph updates and interaction. ```JavaScript const initData = { nodes: [ {id: 0 } ], links: [] }; const elem = document.getElementById("3d-graph"); const Graph = new ForceGraph3D(elem) .enableNodeDrag(false) .onNodeClick(removeNode) .graphData(initData); setInterval(() => { const { nodes, links } = Graph.graphData(); const id = nodes.length; Graph.graphData({ nodes: [...nodes, { id }], links: [...links, { source: id, target: Math.round(Math.random() * (id-1)) }] }); }, 1000); ``` -------------------------------- ### Initialize 3D Force Graph and Control Link Distance with dat.gui Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/manipulate-link-force/index.html This JavaScript code initializes a 3D force-directed graph using the ForceGraph3D library. It generates random nodes and links, configures link colors and opacity, and integrates with dat.gui to allow real-time adjustment of link distances based on their color. The simulation is re-heated upon GUI changes to apply new force parameters. ```JavaScript import { GUI } from 'https://esm.sh/dat.gui'; // Create Random tree const N = 20; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)), color: id % 2 })) }; const graph = new ForceGraph3D(document.getElementById('3d-graph')) .nodeLabel(node => node.id) .linkColor(link => link.color ? 'red' : 'green' ) .linkOpacity(1) .graphData(gData); const linkForce = graph .d3Force('link') .distance(link => link.color ? settings.redDistance : settings.greenDistance); //Define GUI const Settings = function() { this.redDistance = 20; this.greenDistance = 20; }; const settings = new Settings(); const gui = new GUI(); const controllerOne = gui.add(settings, 'redDistance', 0, 100); const controllerTwo = gui.add(settings, 'greenDistance', 0, 100); controllerOne.onChange(updateLinkDistance); controllerTwo.onChange(updateLinkDistance); function updateLinkDistance() { linkForce.distance(link => link.color ? settings.redDistance : settings.greenDistance); graph.numDimensions(3); // Re-heat simulation } ``` -------------------------------- ### Force Engine Configuration API Reference Source: https://github.com/vasturiano/3d-force-graph/blob/master/README.md Comprehensive API documentation for methods used to configure the force simulation engine in 3D Force Graph. This includes settings for d3-force-3d and ngraph.forcelayout, DAG mode options, and simulation lifecycle callbacks. ```APIDOC forceEngine([str]) Description: Getter/setter for which force-simulation engine to use (d3 or ngraph). Default: d3 numDimensions([int]) Description: Getter/setter for number of dimensions to run the force simulation on (1, 2 or 3). Default: 3 dagMode([str]) Description: Apply layout constraints based on the graph directionality. Only works correctly for DAG 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]) Description: If dagMode is engaged, this specifies the distance between the different graph depths. Default: auto-derived from the number of nodes dagNodeFilter([fn]) Description: 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. Default: node => true onDagError([fn]) Description: 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. Default: throws exception d3AlphaMin([num]) Description: Getter/setter for the simulation alpha min parameter, only applicable if using the d3 simulation engine. Default: 0 d3AlphaDecay([num]) Description: Getter/setter for the simulation intensity decay parameter, only applicable if using the d3 simulation engine. Default: 0.0228 d3VelocityDecay([num]) Description: Getter/setter for the nodes' velocity decay that simulates the medium resistance, only applicable if using the d3 simulation engine. Default: 0.4 d3Force(str, [fn]) Description: Getter/setter for the internal forces that control the d3 simulation engine. Follows the same interface as d3-force-3d's simulation.force. Three forces are included by default: 'link' (based on forceLink), 'charge' (based on forceManyBody) and 'center' (based on 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. d3ReheatSimulation() Description: Reheats the force simulation engine, by setting the alpha value to 1. Only applicable if using the d3 simulation engine. ngraphPhysics([object]) Description: Specify custom physics configuration for ngraph, according to its configuration object syntax. This method is only applicable if using the ngraph simulation engine. Default: ngraph default warmupTicks([int]) Description: Getter/setter for number of layout engine cycles to dry-run at ignition before starting to render. Default: 0 cooldownTicks([int]) Description: Getter/setter for how many build-in frames to render before stopping and freezing the layout engine. Default: Infinity cooldownTime([num]) Description: Getter/setter for how long (ms) to render for before stopping and freezing the layout engine. Default: 15000 onEngineTick(fn) Description: Callback function invoked at every tick of the simulation engine. onEngineStop(fn) Description: Callback function invoked when the simulation engine stops and the layout is frozen. ``` -------------------------------- ### Initialize 3D Force Graph with GUI and Yarn Lock Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/dag-yarn/index.html Initializes a 3D force-directed graph using ForceGraph3D, configures its appearance and behavior, integrates dat.gui for interactive controls, and populates the graph with package dependency data parsed from a yarn.lock file. Nodes are rendered as SpriteText labels. ```JavaScript import SpriteText from 'https://esm.sh/three-spritetext'; import { forceCollide } from 'https://esm.sh/d3-force-3d'; import { GUI } from 'https://esm.sh/dat.gui'; // controls const controls = { 'DAG Orientation': 'lr'}; const gui = new GUI(); gui.add(controls, 'DAG Orientation', ['lr', 'td', 'zout', 'radialout', null]) .onChange(orientation => graph && graph.dagMode(orientation)); // graph config const graph = new ForceGraph3D(document.getElementById('graph')) .backgroundColor('#101020') .linkColor(() => 'rgba(255, 255, 255, 0.6)') .dagMode('lr') .onDagError(() => false) .dagLevelDistance(180) .nodeId('package') .linkCurvature(0.07) .nodeThreeObject(node => { const sprite = new SpriteText(node.package); sprite.material.depthWrite = false; sprite.color = 'lightsteelblue'; sprite.textHeight = 8; return sprite; }) .d3Force('collide', forceCollide(13)) .d3AlphaDecay(0.02) .d3VelocityDecay(0.3); fetch('../../yarn.lock') .then(r => r.text()) .then(text => { const yarnlock = _yarnpkg_lockfile.parse(text); if (yarnlock.type !== 'success') throw new Error('invalid yarn.lock'); return yarnlock.object; }) .then(yarnlock => { const nodes = []; const links = []; Object.entries(yarnlock).forEach(([pkg, details]) => { nodes.push({ package: pkg, version: details.version }); if (details.dependencies) { Object.entries(details.dependencies).forEach(([dep, version]) => { links.push({source: pkg, target: `${dep}@${version}`}); }); } }); graph.graphData({ nodes, links }); }); ``` -------------------------------- ### 3D Force Graph Initialization with Node Interaction Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/multi-selection/index.html Initializes a 3D force-directed graph with random nodes and links. It includes functionality for single and multi-node selection on click, updating node colors based on selection, and synchronized dragging of all selected nodes. ```javascript // Random tree const N = 40; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; let selectedNodes = new Set(); const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .graphData(gData) .nodeRelSize(9) .nodeColor(node => selectedNodes.has(node) ? 'yellow' : 'grey') .onNodeClick((node, event) => { if (event.ctrlKey || event.shiftKey || event.altKey) { // multi-selection selectedNodes.has(node) ? selectedNodes.delete(node) : selectedNodes.add(node); } else { // single-selection const untoggle = selectedNodes.has(node) && selectedNodes.size === 1; selectedNodes.clear(); !untoggle && selectedNodes.add(node); } Graph.nodeColor(Graph.nodeColor()); // update color of selected nodes }) .onNodeDrag((node, translate) => { if (selectedNodes.has(node)) { // moving a selected node [...selectedNodes] .filter(selNode => selNode !== node) // don't touch node being dragged .forEach(node => ['x', 'y', 'z'].forEach(coord => node[`f${coord}`] = node[coord] + translate[coord])); // translate other nodes by same amount } }) .onNodeDragEnd(node => { if (selectedNodes.has(node)) { // finished moving a selected node [...selectedNodes] .filter(selNode => selNode !== node) // don't touch node being dragged .forEach(node => ['x', 'y', 'z'].forEach(coord => node[`f${coord}`] = undefined)); // unfix controlled nodes } }); ``` -------------------------------- ### Initialize 3D Force Graph with JSON Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/controls-fly/index.html This JavaScript snippet initializes a 3D force-directed graph using the ForceGraph3D library. It targets an HTML element with the ID '3d-graph', configures 'fly' control type, loads graph data from a specified JSON URL, and sets up node labeling and automatic coloring based on 'id' and 'group' properties respectively. ```javascript const Graph = new ForceGraph3D(document.getElementById('3d-graph'), { controlType: 'fly' }) .jsonUrl('../datasets/miserables.json') .nodeLabel('id') .nodeAutoColorBy('group'); ``` -------------------------------- ### Initialize 3D Force Graph with Unreal Bloom Post-Processing Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/bloom-effect/index.html This JavaScript snippet initializes a 3D force-directed graph using the ForceGraph3D library. It configures the graph's background color, loads node data from a JSON file, and sets node labeling and coloring. Additionally, it applies an UnrealBloomPass from Three.js for a visual glow effect, customizing its strength, radius, and threshold. ```JavaScript import { UnrealBloomPass } from 'https://esm.sh/three/examples/jsm/postprocessing/UnrealBloomPass.js'; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .backgroundColor('#000003') .jsonUrl('../datasets/miserables.json') .nodeLabel('id') .nodeAutoColorBy('group'); const bloomPass = new UnrealBloomPass(); bloomPass.strength = 4; bloomPass.radius = 1; bloomPass.threshold = 0; Graph.postProcessingComposer().addPass(bloomPass); ``` -------------------------------- ### Get/Set Scene Lights in 3D Force Graph Source: https://github.com/vasturiano/3d-force-graph/blob/master/README.md Getter/setter for the list of lights to use in the scene. Each item should be an instance of [Light](https://threejs.org/docs/#api/en/lights/Light). ```APIDOC lights(lightsArray?: Light[]): Light[] ``` -------------------------------- ### Initialize and Configure 3D Force Graph with Collapsible Tree Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/expandable-nodes/index.html This JavaScript code initializes a 3D force-directed graph using the ForceGraph3D library. It generates a random tree structure, populates child links, and implements a 'getPrunedTree' function to dynamically filter visible nodes based on their collapsed state. Event handlers are set up for node hover and click to provide visual feedback and toggle node collapse, respectively, re-rendering the graph on state changes. ```JavaScript const rootId = 0; // Random tree const N = 300; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i, collapsed: i !== rootId, childLinks: [] })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: Math.round(Math.random() * (id - 1)), target: id })) }; // link parent/children const nodesById = Object.fromEntries(gData.nodes.map(node => [node.id, node])); gData.links.forEach(link => { nodesById[link.source].childLinks.push(link); }); const getPrunedTree = () => { const visibleNodes = []; const visibleLinks = []; (function traverseTree(node = nodesById[rootId]) { visibleNodes.push(node); if (node.collapsed) return; visibleLinks.push(...node.childLinks); node.childLinks .map(link => ((typeof link.target) === 'object') ? link.target : nodesById[link.target]) // get child node .forEach(traverseTree); })(); // IIFE return { nodes: visibleNodes, links: visibleLinks }; }; const elem = document.getElementById('3d-graph'); const Graph = new ForceGraph3D(elem) .graphData(getPrunedTree()) .linkDirectionalParticles(2) .nodeColor(node => !node.childLinks.length ? 'green' : node.collapsed ? 'red' : 'yellow') .onNodeHover(node => elem.style.cursor = node && node.childLinks.length ? 'pointer' : null) .onNodeClick(node => { if (node.childLinks.length) { node.collapsed = !node.collapsed; // toggle collapse state Graph.graphData(getPrunedTree()); } }); ``` -------------------------------- ### API Reference: ForceGraph3D Container Layout Methods Source: https://github.com/vasturiano/3d-force-graph/blob/master/README.md This section outlines methods for configuring the visual layout and appearance of the 3D graph container. It covers setting the canvas dimensions ('width', 'height'), background color, and visibility of navigation information. ```APIDOC width([px]) Description: Getter/setter for the canvas width. Default: height([px]) Description: Getter/setter for the canvas height. Default: backgroundColor([str]) Description: Getter/setter for the chart background color. Default: #000011 showNavInfo([boolean]) Description: Getter/setter for whether to show the navigation controls footer info. Default: true ``` -------------------------------- ### Load and Process CSV Data for Graph Visualization Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/tree/index.html Fetches dependency data from a CSV file, parses it using `d3-dsv`, and transforms it into a structured format of nodes and links. This processed data is then used to populate the `ForceGraph3D` instance, enabling the visualization of module relationships. ```JavaScript import { csvParse } from 'https://esm.sh/d3-dsv'; // Assumes 'graph' variable is already defined from ForceGraph3D initialization fetch('../datasets/d3-dependencies.csv') .then(r => r.text()) .then(csvParse) .then(data => { const nodes = [], links = []; data.forEach(({ size, path }) => { const levels = path.split('/'), level = levels.length - 1, module = level > 0 ? levels[1] : null, leaf = levels.pop(), parent = levels.join('/'); const node = { path, leaf, module, size: +size || 20, level }; nodes.push(node); if (parent) { links.push({source: parent, target: path, targetNode: node}); } }); graph.graphData({ nodes, links }); }); ``` -------------------------------- ### Initialize 3D Force Graph with Three.js and Custom Plane Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/scene/index.html Initializes a 3D force-directed graph using the ForceGraph3D library, generates random node and link data, and integrates a custom Three.js plane into the graph's scene. This demonstrates combining ForceGraph3D with standard Three.js objects for extended scene customization. ```JavaScript import * as THREE from 'https://esm.sh/three'; // Random tree const N = 30; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const graph = new ForceGraph3D(document.getElementById('3d-graph')) .graphData(gData); const planeGeometry = new THREE.PlaneGeometry(1000, 1000, 1, 1); const planeMaterial = new THREE.MeshLambertMaterial({color: 0xFF0000, side: THREE.DoubleSide}); const mesh = new THREE.Mesh(planeGeometry, planeMaterial); mesh.position.set(-100, -200, -100); mesh.rotation.set(0.5 * Math.PI, 0, 0); graph.scene().add(mesh); ``` -------------------------------- ### Initialize and Animate 3D Force Graph with Random Data Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/camera-auto-orbit/index.html Initializes a 3D force-directed graph with 300 randomly connected nodes using ForceGraph3D. It disables node dragging and navigation controls, sets an initial camera position, and implements a continuous camera orbit animation around the graph. ```JavaScript const N = 300; const gData = { nodes: [...Array(N).keys()].map(i => ({ id: i })), links: [...Array(N).keys()] .filter(id => id) .map(id => ({ source: id, target: Math.round(Math.random() * (id-1)) })) }; const distance = 1400; const Graph = new ForceGraph3D(document.getElementById('3d-graph')) .enableNodeDrag(false) .enableNavigationControls(false) .showNavInfo(false) .cameraPosition({ z: distance }) .graphData(gData); let angle = 0; setInterval(() => { Graph.cameraPosition({ x: distance * Math.sin(angle), z: distance * Math.cos(angle) }); angle += Math.PI / 300; }, 10); ``` -------------------------------- ### Basic CSS Body Styling Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/responsive/index.html Applies a 30px margin to the body element, providing spacing around the content, which can affect the layout of the 3D graph container. ```CSS body { margin: 30px; } ``` -------------------------------- ### Configure Interactive DAG Orientation Controls Source: https://github.com/vasturiano/3d-force-graph/blob/master/example/tree/index.html Sets up interactive controls using `dat.gui` to allow users to dynamically change the DAG (Directed Acyclic Graph) orientation of the initialized 3D force graph. It provides a dropdown with various orientation options and updates the graph's `dagMode` property accordingly. ```JavaScript import { GUI } from 'https://esm.sh/dat.gui'; // Assumes 'graph' variable is already defined from ForceGraph3D initialization const controls = { 'DAG Orientation': 'td'}; const gui = new GUI(); gui.add(controls, 'DAG Orientation', ['td', 'bu', 'lr', 'rl', 'zout', 'zin', 'radialout', 'radialin', null]) .onChange(orientation => graph && graph.dagMode(orientation)); ```