Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental addNode() calls #7

Open
d0znpp opened this issue Jun 28, 2016 · 4 comments
Open

Incremental addNode() calls #7

d0znpp opened this issue Jun 28, 2016 · 4 comments

Comments

@d0znpp
Copy link

d0znpp commented Jun 28, 2016

It would be great if you can add incremental addNode function.
Like https://cdn.rawgit.com/frewsxcv/graphosaurus/HEAD/examples/incremental/index.html

@patrickfuller
Copy link
Owner

patrickfuller commented Jun 30, 2016

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.

@d0znpp
Copy link
Author

d0znpp commented Jul 2, 2016

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]);

@patrickfuller
Copy link
Owner

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:

Random

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.

Force-directed layout after every node

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.

Force-directed layout, pre-rendered

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.

@d0znpp
Copy link
Author

d0znpp commented Jul 9, 2016

Perfect! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants