Skip to content

Commit

Permalink
added #HierarchicalGraphView api and unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
trajar committed Apr 21, 2016
1 parent edea848 commit b9a9255
Show file tree
Hide file tree
Showing 14 changed files with 2,576 additions and 142 deletions.
12 changes: 10 additions & 2 deletions store/src/main/java/org/gephi/graph/api/GraphModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
*/
package org.gephi.graph.api;

import org.gephi.graph.impl.GraphModelImpl;
import org.joda.time.DateTimeZone;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.gephi.graph.impl.GraphModelImpl;
import org.joda.time.DateTimeZone;

/**
* Graph API's entry point.
Expand Down Expand Up @@ -351,6 +352,13 @@ public static void write(DataOutput output, GraphModel graphModel) throws IOExce
*/
public GraphView createView(boolean node, boolean edge);

/**
* Creates a new hierarchical graph view.
*
* @return newly created hierarchical graph view
*/
public HierarchicalGraphView createHierarchicalView();

/**
* Creates a new graph view based on an existing view.
*
Expand Down
25 changes: 25 additions & 0 deletions store/src/main/java/org/gephi/graph/api/HierarchicalGraphView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.gephi.graph.api;

/**
* A hierarchical graph view which allows for collapsible sub-groups. Each node,
* whether it is collapsed or extended, should be in core in view. If a node is
* node is hidden by collapsed parent, it will omitted within
* directed/undirected graph queries.
*/
public interface HierarchicalGraphView extends GraphView {
/**
* @return Return iterator for each hierarchical node group.
*/
Iterable<HierarchicalNodeGroup> getGroups();

/**
* @return Return root node which first-tier nodes should be attached.
*/
HierarchicalNodeGroup getRoot();

/**
* @param node node within graph graph
* @return Return existing hierarchical group if available; else null.
*/
HierarchicalNodeGroup getGroup(Node node);
}
54 changes: 54 additions & 0 deletions store/src/main/java/org/gephi/graph/api/HierarchicalNodeGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.gephi.graph.api;

/**
* A group of nodes within a hierarchical graph view.
*/
public interface HierarchicalNodeGroup {
/**
* @return Returns true if the group is collapsed, which means the children
* are hidden from visible graph.
*/
boolean isCollapsed();

/**
* @return Returns true if the group is expanded, which means the children
* are visible within visible graph.
*/
boolean isExpanded();

/**
* Expand node, displaying children.
*/
void expand();

/**
* Collapse node, hiding children.
*/
void collapse();

/**
* @return Return iterator containing children nodes (not recursive).
*/
Iterable<Node> getNodes();

/**
* @return Return iterator containing children nodes.
*/
Iterable<Node> getNodes(boolean recursive);

/**
* Add node to this group.
*
* @param node child node
* @return Returns child hierarchical group, if created; else null.
*/
HierarchicalNodeGroup addNode(Node node);

/**
* Remove node from group.
*
* @param node child node
* @return Returns true if child hierarchical group was remoce; else false.
*/
boolean removeNode(Node node);
}
105 changes: 105 additions & 0 deletions store/src/main/java/org/gephi/graph/impl/AbstractGraphView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package org.gephi.graph.impl;

import org.gephi.graph.api.DirectedSubgraph;
import org.gephi.graph.api.Graph;
import org.gephi.graph.api.GraphObserver;
import org.gephi.graph.api.GraphView;
import org.gephi.graph.api.Interval;
import org.gephi.graph.api.UndirectedSubgraph;

abstract public class AbstractGraphView implements GraphView {
protected final GraphStore graphStore;

protected final GraphAttributesImpl attributes;

protected final boolean nodeView;

protected final boolean edgeView;

private Interval interval;

private int storeId = GraphViewStore.NULL_VIEW;

public AbstractGraphView(final GraphStore store, boolean nodes, boolean edges) {
this.graphStore = store;
this.nodeView = nodes;
this.edgeView = edges;
this.interval = Interval.INFINITY_INTERVAL;
this.attributes = new GraphAttributesImpl();
}

public AbstractGraphView(final AbstractGraphView view, boolean nodes, boolean edges) {
this.graphStore = view.graphStore;
this.nodeView = nodes;
this.edgeView = edges;
this.interval = view.interval;
this.attributes = new GraphAttributesImpl();
}

public int getStoreId() {
return this.storeId;
}

protected void setStoreId(final int id) {
this.storeId = id;
}

@Override
public boolean isDestroyed() {
return GraphViewStore.NULL_VIEW == this.storeId;
}

@Override
public GraphModelImpl getGraphModel() {
return this.graphStore.graphModel;
}

@Override
public boolean isMainView() {
return false;
}

@Override
public boolean isNodeView() {
return this.nodeView;
}

@Override
public boolean isEdgeView() {
return this.edgeView;
}

public void setTimeInterval(Interval interval) {
if (interval == null) {
interval = Interval.INFINITY_INTERVAL;
}
this.interval = interval;
}

@Override
public Interval getTimeInterval() {
return this.interval;
}

abstract public DirectedSubgraph getDirectedGraph();

abstract public UndirectedSubgraph getUndirectedGraph();

abstract public boolean deepEquals(AbstractGraphView view);

abstract public int deepHashCode();

abstract protected void viewDestroyed();

abstract protected void nodeAdded(NodeImpl node);

abstract protected void nodeRemoved(NodeImpl node);

abstract protected void edgeAdded(EdgeImpl edge);

abstract protected void edgeRemoved(EdgeImpl edge);

abstract protected GraphObserverImpl createGraphObserver(Graph graph, boolean withDiff);

abstract protected void destroyGraphObserver(GraphObserver graphObserver);
}
6 changes: 6 additions & 0 deletions store/src/main/java/org/gephi/graph/impl/GraphModelImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.gephi.graph.impl;

import org.gephi.graph.api.Configuration;
import org.gephi.graph.api.HierarchicalGraphView;
import org.gephi.graph.api.Index;
import org.gephi.graph.api.Table;
import org.gephi.graph.api.TimeFormat;
Expand Down Expand Up @@ -238,6 +239,11 @@ public GraphView createView(boolean node, boolean edge) {
return store.viewStore.createView(node, edge);
}

@Override
public HierarchicalGraphView createHierarchicalView() {
return store.viewStore.createHierarchicalView();
}

@Override
public GraphView copyView(GraphView view) {
return store.viewStore.createView(view);
Expand Down
50 changes: 38 additions & 12 deletions store/src/main/java/org/gephi/graph/impl/GraphStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,56 +15,74 @@
*/
package org.gephi.graph.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.gephi.graph.api.Configuration;
import org.gephi.graph.api.Origin;
import org.gephi.graph.api.TimeFormat;
import org.gephi.graph.api.Interval;
import org.gephi.graph.api.types.TimestampSet;
import org.gephi.graph.api.DirectedGraph;
import org.gephi.graph.api.DirectedSubgraph;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.EdgeIterable;
import org.gephi.graph.api.Graph;
import org.gephi.graph.api.GraphModel;
import org.gephi.graph.api.GraphView;
import org.gephi.graph.api.Interval;
import org.gephi.graph.api.Node;
import org.gephi.graph.api.NodeIterable;
import org.gephi.graph.api.Origin;
import org.gephi.graph.api.Subgraph;
import org.joda.time.DateTimeZone;
import org.gephi.graph.api.TimeFormat;
import org.gephi.graph.api.TimeRepresentation;
import org.gephi.graph.api.types.IntervalSet;
import org.gephi.graph.api.types.TimestampSet;
import org.joda.time.DateTimeZone;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class GraphStore implements DirectedGraph, DirectedSubgraph {

protected final GraphModelImpl graphModel;

protected final Configuration configuration;

// Stores
protected final NodeStore nodeStore;

protected final EdgeStore edgeStore;

protected final EdgeTypeStore edgeTypeStore;

protected final TableImpl<Node> nodeTable;

protected final TableImpl<Edge> edgeTable;

protected final GraphViewStore viewStore;

protected final TimeStore timeStore;

protected final GraphAttributesImpl attributes;

// Factory
protected final GraphFactoryImpl factory;

// Lock
protected final GraphLock lock;

// Version
protected final GraphVersion version;

protected final List<GraphObserverImpl> observers;

// Undirected
protected final UndirectedDecorator undirectedDecorator;

// Main Graph view
protected final GraphView mainGraphView;

// TimeFormat
protected TimeFormat timeFormat;

// Time zone
protected DateTimeZone timeZone;

Expand Down Expand Up @@ -822,6 +840,7 @@ public boolean deepEquals(GraphStore obj) {
protected class NodeIterableWrapper implements NodeIterable {

protected final Iterator<Node> iterator;

protected final boolean blocking;

public NodeIterableWrapper(Iterator<Node> iterator) {
Expand All @@ -842,7 +861,10 @@ public Iterator<Node> iterator() {
public Node[] toArray() {
List<Node> list = new ArrayList<Node>();
for (; iterator.hasNext();) {
list.add(iterator.next());
Node node = iterator.next();
if (node != null) {
list.add(node);
}
}
return list.toArray(new Node[0]);
}
Expand All @@ -851,7 +873,10 @@ public Node[] toArray() {
public Collection<Node> toCollection() {
List<Node> list = new ArrayList<Node>();
for (; iterator.hasNext();) {
list.add(iterator.next());
Node node = iterator.next();
if (node != null) {
list.add(node);
}
}
return list;
}
Expand All @@ -867,6 +892,7 @@ public void doBreak() {
protected class EdgeIterableWrapper implements EdgeIterable {

protected final Iterator<Edge> iterator;

protected final boolean blocking;

public EdgeIterableWrapper(Iterator<Edge> iterator) {
Expand Down
13 changes: 7 additions & 6 deletions store/src/main/java/org/gephi/graph/impl/GraphViewDecorator.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
*/
package org.gephi.graph.impl;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import org.gephi.graph.api.DirectedSubgraph;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.EdgeIterable;
Expand All @@ -30,6 +27,10 @@
import org.gephi.graph.api.Subgraph;
import org.gephi.graph.api.UndirectedSubgraph;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

public class GraphViewDecorator implements DirectedSubgraph, UndirectedSubgraph {

protected final boolean undirected;
Expand Down Expand Up @@ -736,10 +737,10 @@ void checkValidViewObject(final GraphView view) {
if (view == null) {
throw new NullPointerException();
}
if (!(view instanceof GraphViewImpl)) {
throw new ClassCastException("Object must be a GraphViewImpl object");
if (!(view instanceof AbstractGraphView)) {
throw new ClassCastException("Object must be a AbstractGraphView object");
}
if (((GraphViewImpl) view).graphStore != graphStore) {
if (((AbstractGraphView) view).graphStore != graphStore) {
throw new RuntimeException("The view doesn't belong to this store");
}
}
Expand Down
Loading

0 comments on commit b9a9255

Please sign in to comment.