/*
* CCVisu is a tool for visual graph clustering
* and general force-directed graph layout.
* This file is part of CCVisu.
*
* Copyright (C) 2005-2012 Dirk Beyer
*
* CCVisu is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* CCVisu 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CCVisu; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Please find the GNU Lesser General Public License in file
* license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
*
* Dirk Beyer (firstname.lastname@uni-passau.de)
* University of Passau, Bavaria, Germany
*/
package org.sosy_lab.ccvisu;
import java.awt.Color;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.sosy_lab.ccvisu.graph.GraphData;
import org.sosy_lab.ccvisu.graph.GraphEdge;
import org.sosy_lab.ccvisu.graph.GraphVertex;
/**
* This class is used to determine which vertices or
* edges should be displayed
*/
public class DisplayCriteria {
// The associated writer instance on which
// the display criteria is applied.
// private WriterDataGraphicsDISP writer;
private Color addedVertexColor = Color.RED;
private Color removedVertexColor = Color.GREEN;
private Color unchangedVertexColor = Color.CYAN.darker();
private Color addedEdgeColor = Color.RED;
private Color removedEdgeColor = Color.GREEN.darker();
private Color unchangedEdgeColor = Color.BLUE;
private Set<GraphVertex> undoList = new HashSet<GraphVertex>();
public DisplayCriteria(GraphData gr) {
init(gr);
}
public DisplayCriteria(GraphData gr, Color addedVertexCol,
Color removedVertexCol, Color unchangedVertexCol,
Color addedEdgeCol, Color removedEdgeCol,
Color unchangedEdgeCol) {
addedVertexColor = addedVertexCol;
removedVertexColor = removedVertexCol;
unchangedVertexColor = unchangedVertexCol;
addedEdgeColor = addedEdgeCol;
removedEdgeColor = removedEdgeCol;
unchangedEdgeColor = unchangedEdgeCol;
init(gr);
}
public void init(GraphData gr) {
undoList = new HashSet<GraphVertex>(gr.getVertices());
}
/**
* @param filterType <br>
* 0: Display unchanged vertices<br>
* 1: Display removed vertices<br>
* 2: Display added vertices
*/
private boolean vertexPredicate(GraphVertex v, int filterType) {
switch (filterType) {
case 0: // is unchanged
return v.getColor().equals(unchangedVertexColor);
case 1: // is removed
return v.getColor().equals(removedVertexColor);
case 2: // is added
return v.getColor().equals(addedVertexColor);
default:
return false;
}
}
/**
* Makes all the vertices invisible except those
* that satisfy the filtering predicate.
*
* Warning: This method does not change the
* graph argument which it takes, but it might
* change the attributes of the vertices
* of the graph.
*
* This method can preserve the current view
* ("zooming" feature). For that end, pass
* a "true" value to the argument
* "onlyVisibles".
*
* @param onlyVisibles if true, then only the
* currently visible vertex members (with a true
* showVertex attribute) are affected by this
* method
*/
public void filterVertices(final GraphData gr, int filterType,
boolean onlyVisibles) {
resetView(gr.getVertices());
for (GraphVertex currVertex : gr.getVertices()) {
if (!vertexPredicate(currVertex, filterType)) {
currVertex.setShowVertex(false);
} else if (!onlyVisibles) {
currVertex.setShowVertex(true);
}
}
}
/**
* @param filterType <br>
* 0: Display unchanged edges<br>
* 1: Display removed edges<br>
* 2: Display added edges
*/
private boolean edgePredicate(GraphEdge e, int filterType) {
switch (filterType) {
case 0: // is unchanged
return e.getColor().equals(unchangedEdgeColor);
case 1: // is removed
return e.getColor().equals(removedEdgeColor);
case 2: // is added
return e.getColor().equals(addedEdgeColor);
default:
return false;
}
}
/**
* Makes visible all the incident vertices of those
* edges which satisfy the edge filtering predicate
* along with all the incident edges of these
* vertices.
*
* Warning: This method does not change the
* graph argument which it takes, but it might change
* the attributes of the vertices of the graph.
* This method can preserve the current view
* ("zooming" feature). For that end, pass
* a "true" value to the argument
* "onlyVisibles".
*
* @param gr
* @param onlyVisibles if true, then only the
* currently visible vertex members (with a true
* showVertex attribute) are affected by this
* method
*/
public void filterEdges(final GraphData gr, int filterType,
boolean onlyVisibles) {
Set<GraphVertex> verticesToDisplay = new HashSet<GraphVertex>();
// Determine the vertices which are incident
// to the desired edges
for (GraphEdge currEdge : gr.getEdges()) {
assert (gr.getVertices().size() > currEdge.getSource().getId());
assert (gr.getVertices().size() > currEdge.getTarget().getId());
if (edgePredicate(currEdge, filterType)) {
GraphVertex src = currEdge.getSource();
GraphVertex tar = currEdge.getTarget();
if (onlyVisibles) {
// Display the tail (src) and head (tar)
// vertices of the current edge only if both
// of them are visible simultaneously in
// the current view
if (src.isShowVertex() && tar.isShowVertex()) {
verticesToDisplay.add(src);
verticesToDisplay.add(tar);
}
} else {
verticesToDisplay.add(src);
verticesToDisplay.add(tar);
src.setShowVertex(true);
tar.setShowVertex(true);
}
}
}
// Now hide all the vertices that are not
// marked by the previous section
for (GraphVertex currVer : gr.getVertices()) {
if (!verticesToDisplay.contains(currVer)) {
currVer.setShowVertex(false);
}
}
}
/**
* Keeps the track of currently visible vertices in case later
* an "undo" operation is performed to restore the changes made
* by this instance
* @param vertices
*/
public void resetUndoList(Collection<GraphVertex> vertices) {
undoList = new HashSet<GraphVertex>();
for (GraphVertex currVer : vertices) {
if (currVer.isShowVertex()) {
undoList.add(currVer);
}
}
}
/**
* Resets the vertex display filter (Undo filtering).
* Shows all vertices within the zooming rectangle.
* If the rectangle margins are not specified,
* then this method considers the whole canvas as
* the rectangular area which hosts vertices and edges
*/
public void resetView(final List<GraphVertex> vertices) {
assert (undoList != null);
if (undoList.isEmpty()) { return; }
for (GraphVertex currVer : vertices) {
if (undoList.contains(currVer)) {
currVer.setShowVertex(true);
} else {
currVer.setShowVertex(false);
}
}
}
}