/* * 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) {} } }