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

Cytoscape and Ember #21

Open
xkb opened this issue Dec 24, 2014 · 8 comments
Open

Cytoscape and Ember #21

xkb opened this issue Dec 24, 2014 · 8 comments
Milestone

Comments

@xkb
Copy link
Contributor

xkb commented Dec 24, 2014

@kdbanman, this is a followup of our earlier discussion.

I've managed to get something working with the container method as follows

var cy = Cyto({
  container: this.$()[0],
  style: graphstyle,
  layout: layoutOptions,
  panningEnabled: true,
  userPanningEnabled: true,
  boxSelectionEnabled: true,
});
//then add nodes and edges with
cy.add( {
  nodes: graph.nodes,
  edges: graph.edges
});

I looked into different ways of doing what we want with ember and the ideal/efficient approach would be to initialize cytoscape once on didInsertElement and then use array observes for selected, incoming and outgoing as resources are added/removed, since they're all arrays.

Peeking into the Cytoscape's API, there doesn't seem a way to completely remove nodes/edges from the graph after adding them. There is a remove method but it keeps old objects in memory which isn't ideal.

I don't think re-initializing the entire graph is an option either.

Unsure where to go from here... feels like a dead end. Ideas?

@kdbanman
Copy link
Member

Yeah I have an idea.

That persistence after remove() is a bit of a pain, but I think it'll force us into an even more performant solution. Cytoscape elements are mutable by design, so the component could keep a pool of nodes and a pool of edges.

  • Each pool would be created as part of the initialization right after cytoscape is initialized.
  • The array observers looking at selected, incoming, and outgoing would mutate the nodes and edges inside the pools, and add/remove them from the cytoscape graph as necessary.

I can think of a few things for me to be concerned about, but none seem too tricky:

  • The element pools would need to grow as necessary. i.e. if there are more nodes or edges in the query results than there are in the existing pools.
  • The functions observing incoming, outgoing, and selection mutate the same state, so they should never execute at the same time I know JavaScript is single threaded and execution is never interrupted/preempted, but I've been surprised by Ember before. @KarimBaaba, from what you know of Ember's event loop, is it possible for a component's observer method to be interrupted somehow? I think the only situation I'm actually worried about is if one of the graph's observer functions interrupts another.

@xkb
Copy link
Contributor Author

xkb commented Dec 25, 2014

I looked at eles.data() and eles.removeData() and they allow you to mutate element's data but not the elements themselves.. By 'pools' did you mean to store elements even if a new selection is made and it doesn't re-use any old elements? The collection would exponentially grow. We have to discard nodes/edges when an item from selected is removed.

You have nothing to worry about with observers, it's all single execution from a giant for-loop aka Ember's Run-Loop

@kdbanman
Copy link
Member

doesn't re-use any old elements?

The opposite, actually. Cytoscape node and edge objects would be kept statically over the life of the component. They'd be reused for every selection change, mutating their data rather than discarding them. Elements would only be added to the pool if the pool size is too small to service any particular result set.

@xkb
Copy link
Contributor Author

xkb commented Dec 26, 2014

Ah, I get it. Pretty clever, actually. However, not easy.

@xkb
Copy link
Contributor Author

xkb commented Dec 30, 2014

I'v also noticed that edges in a multiple selection graph can become very cluttered. Any chance we can have a different colour for multiple edges on the same node?

@xkb xkb added this to the 1.0 Beta milestone Dec 30, 2014
@kdbanman
Copy link
Member

I'm not sure what the best solution is to the clutter problem. Differently colored edges are simple to implement, but I think I can't think of a way to make it consistently look good. Some options are (in order of complexity):

  • All edges hidden until a node mouseover event shows all of its connected edges.
  • All edges visible until a node mouseover event hides all edges not connected to it.
  • Differently colored edges
  • Cluster all members of selection into a single parent node and only, so there is only a single edge per predicate. Though the square shape of the parent is fugly.

By design, every member of the selection is connected to each predicate, regardless of selection. The only possible difference is the direction of the edge. So to me it feels like there's actually a lot of redundancy in having an edge between each predicate and selection member.

@xkb
Copy link
Contributor Author

xkb commented Dec 30, 2014

  • All edges visible until a node mouseover event hides all edges not connected to it.

I like the idea but rather than hiding all edges not connected to it, highlight/emphasize the edges that are connected? A little more optimal.

@kdbanman
Copy link
Member

Alright. That's the change I'll make.

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

No branches or pull requests

2 participants