/*
* 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.clustering;
import java.util.List;
import org.sosy_lab.ccvisu.clustering.interfaces.Clusterer;
import org.sosy_lab.ccvisu.graph.GraphData;
import org.sosy_lab.ccvisu.graph.Group;
import org.sosy_lab.util.Colors;
import org.sosy_lab.util.ProgressingBase;
/**
* Abstract base class for all clustering algorithms of CCVisu.
*/
public abstract class ClustererBase extends ProgressingBase implements Clusterer, Runnable {
/** The representation of the graph that should be clustered. */
protected GraphData graphData;
/**
* Constructor.
* @param graphData Graph that should be clustered.
*/
public ClustererBase(GraphData graphData) {
this.graphData = graphData;
}
@Override
public final List<Group> createClustersOfLayout(GraphData graphData)
throws InterruptedException {
assert(graphData != null);
this.graphData = graphData;
List<Group> clusters = null;
try {
// Do the clustering...
try {
// Clear the old clustering.
graphData.clearGroups();
// Make the new clustering.
clusters = internalCreateClustersOfLayout();
// Remove empty clusters
// and assign colors to the clusters...
List<Colors> colors = Colors.getMaxDistanceColors(clusters.size());
for (int i = clusters.size() - 1; i > -1; i--) {
Group cluster = clusters.get(i);
cluster.setColor(colors.get(i).get());
if (cluster.getNodes().size() == 0) {
clusters.remove(i);
}
}
} catch (InterruptedException e) {
graphData.clearGroups();
throw e;
}
}
finally {
// Inform about finished process.
setProgress(0, 0, "Clustering finished.");
}
// Return the list of created clusters.
return clusters;
}
@Override
public void runClusteringAndUpdateGroups(GraphData graphData)
throws InterruptedException {
List<Group> clusters = createClustersOfLayout(graphData);
// Update the graph group list.
for (int i = clusters.size() - 1; i > -1; i--) {
Group cluster = clusters.get(i);
cluster.setName(String.format("Cluster %d", i+1));
graphData.addGroup(cluster);
}
}
/**
* Method that does the clustering of the graph.
* Has to be overwritten by the ancestor.
*
* @return List of found partitions.
*
* @throws InterruptedException
*/
protected abstract List<Group> internalCreateClustersOfLayout()
throws InterruptedException;
@Override
public void run() {
try {
runClusteringAndUpdateGroups(graphData);
} catch (InterruptedException ignored) {}
}
}