/*
Copyright 2008-2010 Gephi
Authors : Jeremy Subtil <jeremy.subtil@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
Gephi is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
Gephi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Gephi. If not, see <http://www.gnu.org/licenses/>.
*/
package org.gephi.preview;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.gephi.preview.api.BidirectionalEdge;
import org.gephi.preview.api.Graph;
import org.gephi.preview.api.Node;
import org.gephi.preview.api.SelfLoop;
import org.gephi.preview.api.UndirectedEdge;
import org.gephi.preview.api.UnidirectionalEdge;
/**
* Implementation of a partial preview graph.
*
* @author Jérémy Subtil <jeremy.subtil@gephi.org>
*/
public class PartialGraphImpl implements Graph {
private final float visibilityRatio;
private final Set<Node> visibleNodes = new HashSet<Node>();
private final Set<SelfLoop> visibleSelfLoops = new HashSet<SelfLoop>();
private final Set<UnidirectionalEdge> visibleUnidirectionalEdges = new HashSet<UnidirectionalEdge>();
private final Set<BidirectionalEdge> visibleBidirectionalEdges = new HashSet<BidirectionalEdge>();
private final Set<UndirectedEdge> visibleUndirectedEdges = new HashSet<UndirectedEdge>();
private final Graph originalGraph;
/**
* Constructor.
*
* @param originalGraph the original preview graph
* @param visibilityRatio the graph's visibility ratio
*/
public PartialGraphImpl(Graph originalGraph, float visibilityRatio) {
this.originalGraph = originalGraph;
this.visibilityRatio = visibilityRatio;
updateVisibleGraphParts();
}
/**
* Returns the graph visibility ratio.
*
* @return the graph visibility ratio
*/
public float getVisibilityRatio() {
return visibilityRatio;
}
/**
* Returns the original preview graph.
*
* @return the original preview graph
*/
public Graph getOriginalGraph() {
return originalGraph;
}
/**
* Returns an iterable on the graph's visible nodes.
*
* @return an iterable on the graph's visible nodes
* @see Graph#getNodes()
*/
public Iterable<Node> getNodes() {
return visibleNodes;
}
/**
* Returns an iterable on the graph's visible self-loops.
*
* @return an iterable on the graph's visible self-loops
* @see Graph#getSelfLoops()
*/
public Iterable<SelfLoop> getSelfLoops() {
return visibleSelfLoops;
}
/**
* Returns an iterable on the graph's visible unidirectional edges.
*
* @return an iterable on the graph's visible unidirectional edges
* @see Graph#getUnidirectionalEdges()
*/
public Iterable<UnidirectionalEdge> getUnidirectionalEdges() {
return visibleUnidirectionalEdges;
}
/**
* Returns an iterable on the graph's visible bidirectional edges.
*
* @return an iterable on the graph's visible bidirectional edges
* @see Graph#getBidirectionalEdges()
*/
public Iterable<BidirectionalEdge> getBidirectionalEdges() {
return visibleBidirectionalEdges;
}
/**
* Returns an iterable on the graph's visible undirected edges.
*
* @return an iterable on the graph's visible undirected edges
* @see Graph#getUndirectedEdges()
*/
public Iterable<UndirectedEdge> getUndirectedEdges() {
return visibleUndirectedEdges;
}
/**
* Returns the number of visible nodes in the graph.
*
* @return the number of visible nodes in the graph
* @see Graph#countNodes()
*/
public int countNodes() {
return visibleNodes.size();
}
/**
* Returns the number of visible self-loops in the graph.
*
* @return the number of visible self-loops in the graph
* @see Graph#countSelfLoops()
*/
public int countSelfLoops() {
return visibleSelfLoops.size();
}
/**
* Returns the number of visible unidirectional edges in the graph.
*
* @return the number of visible unidirectional edges in the graph
* @see Graph#countUnidirectionalEdges()
*/
public int countUnidirectionalEdges() {
return visibleUnidirectionalEdges.size();
}
/**
* Returns the number of visible bidirectional edges in the graph.
*
* @return the number of visible bidirectional edges in the graph
* @see Graph#countBidirectionalEdges()
*/
public int countBidirectionalEdges() {
return visibleBidirectionalEdges.size();
}
/**
* Returns the number of visible undirected edges in the graph.
*
* @return the number of visible undirected edges in the graph
* @see Graph#countUndirectedEdges()
*/
public int countUndirectedEdges() {
return visibleUndirectedEdges.size();
}
public Boolean showNodes() {
return originalGraph.showNodes();
}
public Boolean showEdges() {
return originalGraph.showEdges();
}
public Boolean showSelfLoops() {
return originalGraph.showSelfLoops();
}
/**
* Updates lists of visible graph parts.
*/
private void updateVisibleGraphParts() {
updateVisibleNodes();
updateVisibleSelfLoops();
updateVisibleUnidirectionalEdges();
updateVisibleBidirectionalEdges();
updateVisibleUndirectedEdges();
}
/**
* Updates the list of visible nodes.
*/
private void updateVisibleNodes() {
int visibleNodesCount = (int) (originalGraph.countNodes() * visibilityRatio);
if (visibleNodesCount == 0) {
visibleNodesCount = Math.min(10, originalGraph.countNodes());
}
Iterator<Node> nodeIt = originalGraph.getNodes().iterator();
visibleNodes.clear();
for (int i = 0; i < visibleNodesCount; i++) {
if (!nodeIt.hasNext()) {
break;
}
visibleNodes.add(nodeIt.next());
}
}
/**
* Updates the list of visible self-loops.
*/
private void updateVisibleSelfLoops() {
visibleSelfLoops.clear();
for (SelfLoop sl : originalGraph.getSelfLoops()) {
if (visibleNodes.contains(sl.getNode())) {
visibleSelfLoops.add(sl);
}
}
}
/**
* Updates the list of visible unidirectional edges.
*/
private void updateVisibleUnidirectionalEdges() {
visibleUnidirectionalEdges.clear();
for (UnidirectionalEdge ue : originalGraph.getUnidirectionalEdges()) {
if (visibleNodes.contains(ue.getNode1()) && visibleNodes.contains(ue.getNode2())) {
visibleUnidirectionalEdges.add(ue);
}
}
}
/**
* Updates the list of visible bidirectional edges.
*/
private void updateVisibleBidirectionalEdges() {
visibleBidirectionalEdges.clear();
for (BidirectionalEdge be : originalGraph.getBidirectionalEdges()) {
if (visibleNodes.contains(be.getNode1()) && visibleNodes.contains(be.getNode2())) {
visibleBidirectionalEdges.add(be);
}
}
}
/**
* Updates the list of visible undirected edges.
*/
private void updateVisibleUndirectedEdges() {
visibleUndirectedEdges.clear();
for (UndirectedEdge e : originalGraph.getUndirectedEdges()) {
if (visibleNodes.contains(e.getNode1()) && visibleNodes.contains(e.getNode2())) {
visibleUndirectedEdges.add(e);
}
}
}
}