anvaka / ngraph.pixel

Fast graph renderer based on low level ShaderMaterial from three.js
https://github.com/anvaka/ngraph.pixel#demo
MIT License
319 stars 45 forks source link

Opaque Links? #6

Closed palafranchise closed 8 years ago

palafranchise commented 8 years ago

Hi Andrei,

ngraph.pixel is awesome!

Is there a way to set the opacity on links? Or, set the stroke width? I'm trying to create some links that are not visible. So far the best I have been able to do is set the link color to the background color for the links I want to "hide".

Happy holidays,

Andrew

anvaka commented 8 years ago

This is interesting.

To answer your question: There is no way to set links opacity or stroke width in version 1.1.0.

I think we need an API to hide links. Since they are very expensive (memory wise). Each link requires 6 Float32 values to store position, and 6 Float32 values to store color in rgb format (beginning of a link/end of the link). That means if you have 1 million links, we'll need 1m*12*4 ~ 45MB of GPU memory.

@palafranchise are you going to hide links dynamically or their state is know beforehand and does not change once rendered?

palafranchise commented 8 years ago

Interesting!

In this case I am not going to hide links dynamically.

I'm parsing and graphing a genealogy tree (GEDCOM) and adding a hidden link between husband and wife nodes helps to separate the parents from the children in a family group. I have attached a small example graph. Each surname is represented by its own color. You can see where I am "hiding" edges by making them black.

screen shot 2015-12-28 at 4 05 29 pm

anvaka commented 8 years ago

I'm somewhat stuck with this issue. Imagine an API like this:

var renderGraph = require('ngrpah.pixel');

var renderer = renderGraph(graph, {
  link: renderLink
});

function renderLink(link) {
  // link is an instance of graph's link. The output of the function is
  // a "ui" object. If falsy value returned, the renderer does not
  // render it at all
  if (link.data === 'invisible') return; // this could be your own condition
  return {
    from: 0xff0000,
    to: 0x00ff00
  }
}

What do you think about this one?

palafranchise commented 8 years ago

I think this would perfectly!

anvaka commented 8 years ago

I've just pushed updated version with this API. The following should hide link between 2 and 3 but render link between 1 and 2:

var graph = require('ngraph.graph')();
graph.addLink(1, 2);
graph.addLink(2, 3, 'hidden');

var renderGraph = require('ngraph.pixel');
var renderer = renderGraph(graph, {
  link: function createLinkUI(link) {
    if (link.data === 'hidden') return; // don't need to render!
    // otherwise return default link:
    return {
      fromColor: 0xFFFFFF,
      toColor: 0xFFFFFF
    };
  }
});

The API of the library has changed too, but I hope it would make it more flexible in future. I'll add changelog later, but major changes is: linkColor(), nodeColor(), nodeSize() are gone. Use getNode()/getLink() and update the properties of returned objects directly.

The update API is in the readme

Please let me know how it feels.

anvaka commented 8 years ago

Changelog added.

anvaka commented 8 years ago

Closing the issue. Let me know if you'd have any feedback.

ghost commented 8 years ago

Just stumbled upon this library - great work @anvaka! I really like the modular structure, it's very easy to work with.

I've been playing around with hiding nodes and links based on the examples posted here, but have noticed that it is not yet possible to hide/unhide nodes and links 'on the fly'. I can easily hide elements on first render, but have not managed to hide/unhide elements afterwards.

This would have multiple advantages:

Do you think 'on the fly' hiding and unhiding would be a viable addition?

AVermeij commented 8 years ago

In relation to the above: been trying to get quick node/edge filtering to work as well, but no luck so far. Tried playing around with the edge legends, but that seems to simply remove/re-add nodes and edges from the graph and is costly when filtering e.g. large clusters. What do you think @anvaka?