Grouping in Cytoscape 3.0

Background

In Cytoscape 2.x, we added several different grouping concepts which utilized two APIs: NestedNetworks and CyGroups. Each of these was added to support specific use cases and actions. Ideally, in Cytoscape 3, we would have a more unified grouping mechanism that would meet the various use cases. A good discussion of possible use cases and visualizations is available as an RFC at GroupViews and in the RFC than led up the CyGroup API: groupAPI. If we separate out some of the node visualizations discussions, there are two major concepts: grouping nodes visually onscreen (convex or concave surfaces, bounding boxes, etc.), and collapsing nodes into a single parent node. The CyGroups mechanism in 2.x attempted to provide a framework to handle both of these use cases. NestedNetworks is a form of the "parent node" concept except that the child network is independent (actually, I think of a nested network as a kind of link).

Model

For Cytoscape 3.0, we have a model that supports a true hierarchical networking model. This provides us with the opportunity to rethink how grouping concepts are handled. The org.cytoscape.model.subnetwork package adds two new concepts to Cytoscape: a CyRootNetwork and a CySubNetwork. Conceptually, the idea is that a CyRootNetwork contains a number of CySubNetworks which are perspectives on the root network. What this means is that the root network (similar to the Cytoscape 2.x RootGraph) contains all of the nodes and edges which are part of this forest of graphs. This gives us (almost) everything we need to begin to think about implementing all of the use cases outlined in GroupViews. There are a couple of missing things, though. To illustrate this, I'm going to try to go through the process of creating a metanode (purrely from a model perspective).

  1. Somehow, we get a list of nodes and edges in a network that we want to collapse. Then, if this network is not a CySubNetwork, we need to convert it to a CyRootNetwork:

    CyRootNetwork root = CyRootNetworkFactory.convert(network);
  2. Next, we need to create a new subnetwork that will hold are list of nodes and edges:
    CySubNetwork metaNetwork = root.addSubNetwork();
  3. Then we add each node and each edge to the metaNetwork we just created.
    1. Actually, is there any reason we shouldn't have a method:
      CySubNetwork metaNetwork = root.addSubNetwork(nodeList, edgeList);
      It would make this a lot cleaner.
  4. Now we need to add a node to represent this group in the root network. The problem is that a straight CyNode won't work since we need the node to reference this CySubNetwork. So, I would propose a new class:

    package org.cytoscape.model.subnetwork;
    public interface CyGroupNode extends CyNode {
        CyNetwork getNetwork();
    }

I think we would also need to add a new method to either CyRootNetwork or CySubNetwork to create a CyGroupNode. So, we get a CyGroupNode and we add it to the CyRootNetwork. I *think* that's all we need from the model. Note that since a CyGroupNode returns a CyNetwork, it would reference a CySubNetwork as well as a network not in this CyRootNetwork. If it references a CyNetwork outside of this CyRootNetwork, it becomes the equivalent of an "off-page" link -- providing the hooks necessary to support NestedNetworks.

View Model

The view part of this is much more difficult, I think. Currently, there doesn't seem to be a way to hide and unhide nodes and edges. That will clearly be necessary to implement a collapse/expand style of visualization for groups. So, I think there should be new methods in CyNetworkView:

There may also be some rationale for adding a method to View to determine if a View is hidden or not:

I think this provides all the hook we need in the view model to manage the various states of group objects. I would imagine that there would also be a new column in the default CyDataTable that would track the state of these groups.

Presentation

The collapse/expand presentation is moderately straightforward and I'm not sure we need much in the way of additional support to handle it. Handling the various node graphics is a separable issue (e.g. the NodeCharts plugin), and while it would be really nice to have some kind of animation capability in the expand/collapse, I think that's something that might wait for a new renderer.

Implementing the convex/concave hulls is much more difficult. The current renderer only knows how to render nodes and edges, and while we can work around that limitation by using the foreground or background canvases, I'm not sure that's the best approach. This should be a topic of conversation.

MoinMoin Appliance - Powered by TurnKey Linux