Open d0znpp opened 8 years ago
This should be straightforward. I can give it a try when I get some free time (likely in two weeks), but let me know if you try it before then.
From draw
(here), we could add a node with something like:
jgraph.addNode = function (node) {
var material, mesh, self = jgraph;
if (node.hasOwnProperty('color')) {
node.color = node.color.toLowerCase();
if (!self.materials.hasOwnProperty(node.color)) {
self.materials[node.color] = self.makeMaterial(node.color);
}
}
material = self.materials[node.hasOwnProperty('color') ?
node.color : self.defaultNodeColor];
mesh = new THREE.Mesh(self.sphereGeometry, material);
mesh.position.fromArray(node.hasOwnProperty('location') ?
node.location : [0, 0, 0]);
if (node.hasOwnProperty('size')) {
mesh.scale.set(node.size, node.size, node.size);
}
self.scene.add(mesh);
self.nodes.push(mesh);
}
where node
is an object of the form:
{color: optional, size: optional, location: [x, y, z]}
It may require some tweaking, but something like that should work. This could be tested as a patch in google dev console in one of the example graphs (this would be a good test).
Once this is working, you can use the same logic to add in edges. Take this part, strip out unnecessary lines, make sure the variables and names line up, and you should be all set.
Great! Thanks. It works. But I have no idea how to calculate node position automatically.
Original function puts nodes automatically, but incremental is not.
mesh.position.fromArray(node.hasOwnProperty('location') ?
node.location : [0, 0, 0]);
The node position depends on the effect you're going for. It's hard to tell without knowing more about what you're trying to do, but here are some ideas:
The link you sent uses what looks like a random layout. In this setup, you would generate a random location and check for collisions. A python implementation is here, but you could also do it in javascript. Three.js has some useful vector math that would make this simple.
You can run jgraph.optimize()
after every addNode
call. This will re-run the optimization jiggling, so may not be the right approach if you want to quickly add many nodes.
If you're trying to gradually reveal a known graph, you can run the force-directed optimization on the whole graph. Then, save it with something like this in the console:
var data = JSON.stringify(jgraph.current);
var url = 'data:text/json;charset=utf8,' + encodeURIComponent(data);
window.open(url, '_blank');
window.focus();
From here, initialize jgraph as jgraph.create('selector', {runOptimization: false})
to disable the optimization from running. You can then loop through your graph, calling addNode
to slowly reveal nodes.
Perfect! Thanks.
It would be great if you can add incremental addNode function. Like https://cdn.rawgit.com/frewsxcv/graphosaurus/HEAD/examples/incremental/index.html