3d-force-graph
Advanced tools
Comparing version 0.0.3 to 0.0.4-d3-force
{ | ||
"name": "3d-force-graph", | ||
"version": "0.0.3", | ||
"version": "0.0.4-d3-force", | ||
"description": "UI component for a 3D force-directed graph using ThreeJS and ngraph.forcelayout3d layout engine", | ||
@@ -34,4 +34,5 @@ "main": "dist/3d-force-graph.js", | ||
"dependencies": { | ||
"ngraph.forcelayout3d": "~0.0.16", | ||
"ngraph.graph": "~0.0.12", | ||
"d3": "^4.7.0", | ||
"d3-binarytree": "^0.1", | ||
"d3-octree": "^0.1", | ||
"three": "~0.84", | ||
@@ -38,0 +39,0 @@ "three-trackballcontrols": "~0.0.5" |
@@ -6,5 +6,4 @@ import './3d-force-graph.css'; | ||
import graph from 'ngraph.graph'; | ||
import forcelayout3d from 'ngraph.forcelayout3d'; | ||
const ngraph = { graph, forcelayout3d }; | ||
import * as d3Force from './d3-force'; | ||
var d3 = d3Force.__moduleExports; | ||
@@ -133,22 +132,26 @@ export default function() { | ||
// Build graph with data | ||
const graph = ngraph.graph(); | ||
for (let nodeId in env.graphData.nodes) { | ||
graph.addNode(nodeId, env.graphData.nodes[nodeId]); | ||
const d3Nodes = []; | ||
for (let nodeId in env.graphData.nodes) { // Turn nodes into array | ||
const node = env.graphData.nodes[nodeId]; | ||
node._id = nodeId; | ||
d3Nodes.push(node); | ||
} | ||
for (let link of env.graphData.links) { | ||
graph.addLink(...link, {}); | ||
} | ||
const d3Links = env.graphData.links.map(link => { | ||
return { source: link[0], target: link[1] }; | ||
}); | ||
if (!d3Nodes.length) { return; } | ||
// Add WebGL objects | ||
graph.forEachNode(node => { | ||
const nodeMaterial = new THREE.MeshBasicMaterial({ color: env.colorAccessor(node.data) || 0xffffaa, transparent: true }); | ||
d3Nodes.forEach(node => { | ||
const nodeMaterial = new THREE.MeshBasicMaterial({ color: env.colorAccessor(node) || 0xffffaa, transparent: true }); | ||
nodeMaterial.opacity = 0.75; | ||
const sphere = new THREE.Mesh( | ||
new THREE.SphereGeometry(Math.cbrt(env.valAccessor(node.data) || 1) * env.nodeRelSize), | ||
new THREE.SphereGeometry(Math.cbrt(env.valAccessor(node) || 1) * env.nodeRelSize), | ||
nodeMaterial | ||
); | ||
sphere.name = env.nameAccessor(node.data) || ''; | ||
sphere.name = env.nameAccessor(node) || ''; | ||
env.scene.add(node.data.sphere = sphere) | ||
env.scene.add(node._sphere = sphere) | ||
}); | ||
@@ -158,10 +161,11 @@ | ||
lineMaterial.opacity = env.lineOpacity; | ||
graph.forEachLink(link => { | ||
d3Links.forEach(link => { | ||
const line = new THREE.Line(new THREE.Geometry(), lineMaterial); | ||
line.name = `${getNodeName(link.fromId)} > ${getNodeName(link.toId)}`; | ||
line.geometry.vertices=[new THREE.Vector3(0,0,0), new THREE.Vector3(0,0,0)]; | ||
line.name = `${getNodeName(link.source)} > ${getNodeName(link.target)}`; | ||
env.scene.add(link.data.line = line) | ||
env.scene.add(link._line = line); | ||
function getNodeName(nodeId) { | ||
return env.nameAccessor(graph.getNode(nodeId).data); | ||
return env.nameAccessor(env.graphData.nodes[nodeId]); | ||
} | ||
@@ -171,12 +175,18 @@ }); | ||
env.camera.lookAt(env.scene.position); | ||
env.camera.position.z = Math.cbrt(Object.keys(env.graphData.nodes).length) * CAMERA_DISTANCE2NODES_FACTOR; | ||
env.camera.position.z = Math.cbrt(d3Nodes.length) * CAMERA_DISTANCE2NODES_FACTOR; | ||
// Add force-directed layout | ||
const layout = ngraph.forcelayout3d(graph); | ||
const layout = d3.forceSimulation() | ||
.numDimensions(3) | ||
.nodes(d3Nodes) | ||
.force('link', d3.forceLink().id(d => d._id).links(d3Links)) | ||
.force('charge', d3.forceManyBody()) | ||
.force('center', d3.forceCenter()) | ||
.stop(); | ||
for (let i=0; i<env.initialEngineTicks; i++) { layout.step(); } // Initial ticks before starting to render | ||
for (let i=0; i<env.initialEngineTicks; i++) { layout.tick(); } // Initial ticks before starting to render | ||
let cntTicks = 0; | ||
const startTickTime = new Date(); | ||
env.onFrame = layoutTick; | ||
layout.on("tick", layoutTick).restart(); | ||
@@ -194,30 +204,22 @@ // | ||
function layoutTick() { | ||
if (cntTicks++ > env.maxConvergeFrames || (new Date()) - startTickTime > env.maxConvergeTime) { | ||
env.onFrame = ()=>{}; // Stop ticking graph | ||
} | ||
layout.step(); // Tick it | ||
// Update nodes position | ||
graph.forEachNode(node => { | ||
const sphere = node.data.sphere, | ||
pos = layout.getNodePosition(node.id); | ||
sphere.position.x = pos.x; | ||
sphere.position.y = pos.y; | ||
sphere.position.z = pos.z; | ||
d3Nodes.forEach(node => { | ||
const sphere = node._sphere; | ||
sphere.position.x = node.x; | ||
sphere.position.y = node.y || 0; | ||
sphere.position.z = node.z || 0; | ||
}); | ||
// Update links position | ||
graph.forEachLink(link => { | ||
const line = link.data.line, | ||
pos = layout.getLinkPosition(link.id); | ||
d3Links.forEach(link => { | ||
const line = link._line; | ||
line.geometry.vertices = [ | ||
new THREE.Vector3(pos.from.x, pos.from.y, pos.from.z), | ||
new THREE.Vector3(pos.to.x, pos.to.y, pos.to.z) | ||
new THREE.Vector3(link.source.x, link.source.y || 0, link.source.z || 0), | ||
new THREE.Vector3(link.target.x, link.target.y || 0, link.target.z || 0) | ||
]; | ||
line.geometry.verticesNeedUpdate = true; | ||
}) | ||
line.geometry.computeBoundingSphere(); | ||
}); | ||
} | ||
@@ -224,0 +226,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
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
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
2053529
17
52851
5
+ Addedd3@^4.7.0
+ Addedd3-binarytree@^0.1
+ Addedd3-octree@^0.1
+ Addedcommander@2.20.3(transitive)
+ Addedd3@4.13.0(transitive)
+ Addedd3-array@1.2.1(transitive)
+ Addedd3-axis@1.0.8(transitive)
+ Addedd3-binarytree@0.1.8(transitive)
+ Addedd3-brush@1.0.4(transitive)
+ Addedd3-chord@1.0.4(transitive)
+ Addedd3-collection@1.0.4(transitive)
+ Addedd3-color@1.0.3(transitive)
+ Addedd3-dispatch@1.0.3(transitive)
+ Addedd3-drag@1.2.1(transitive)
+ Addedd3-dsv@1.0.8(transitive)
+ Addedd3-ease@1.0.3(transitive)
+ Addedd3-force@1.1.0(transitive)
+ Addedd3-format@1.2.2(transitive)
+ Addedd3-geo@1.9.1(transitive)
+ Addedd3-hierarchy@1.1.5(transitive)
+ Addedd3-interpolate@1.1.6(transitive)
+ Addedd3-octree@0.1.8(transitive)
+ Addedd3-path@1.0.5(transitive)
+ Addedd3-polygon@1.0.3(transitive)
+ Addedd3-quadtree@1.0.3(transitive)
+ Addedd3-queue@3.0.7(transitive)
+ Addedd3-random@1.1.0(transitive)
+ Addedd3-request@1.0.6(transitive)
+ Addedd3-scale@1.0.7(transitive)
+ Addedd3-selection@1.3.0(transitive)
+ Addedd3-shape@1.2.0(transitive)
+ Addedd3-time@1.0.8(transitive)
+ Addedd3-time-format@2.1.1(transitive)
+ Addedd3-timer@1.0.7(transitive)
+ Addedd3-transition@1.1.1(transitive)
+ Addedd3-voronoi@1.1.2(transitive)
+ Addedd3-zoom@1.7.1(transitive)
+ Addediconv-lite@0.4.24(transitive)
+ Addedrw@1.3.3(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedxmlhttprequest@1.8.0(transitive)
- Removedngraph.forcelayout3d@~0.0.16
- Removedngraph.graph@~0.0.12
- Removedngraph.events@0.0.3(transitive)
- Removedngraph.expose@0.0.0(transitive)
- Removedngraph.forcelayout@0.0.22(transitive)
- Removedngraph.forcelayout3d@0.0.16(transitive)
- Removedngraph.graph@0.0.18(transitive)
- Removedngraph.merge@0.0.1(transitive)
- Removedngraph.physics.primitives@0.0.7(transitive)
- Removedngraph.physics.simulator@0.0.12(transitive)
- Removedngraph.quadtreebh@0.0.3(transitive)
- Removedngraph.quadtreebh3d@0.0.3(transitive)
- Removedngraph.random@0.0.1(transitive)