/* Copyright 2008-2010 Gephi Authors : Mathieu Bastian <mathieu.bastian@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.desktop.clustering; import java.util.logging.Level; import java.util.logging.Logger; import org.gephi.clustering.api.Cluster; import org.gephi.clustering.api.ClusteringController; import org.gephi.clustering.api.ClusteringModel; import org.gephi.clustering.spi.Clusterer; import org.gephi.clustering.spi.ClustererBuilder; import org.gephi.data.attributes.api.AttributeColumn; import org.gephi.data.attributes.api.AttributeController; import org.gephi.data.attributes.api.AttributeModel; import org.gephi.data.attributes.api.AttributeOrigin; import org.gephi.data.attributes.api.AttributeType; import org.gephi.graph.api.Graph; import org.gephi.graph.api.GraphController; import org.gephi.graph.api.GraphModel; import org.gephi.graph.api.HierarchicalGraph; import org.gephi.graph.api.Node; import org.gephi.project.api.ProjectController; import org.gephi.utils.longtask.spi.LongTask; import org.gephi.utils.longtask.api.LongTaskErrorHandler; import org.gephi.utils.longtask.api.LongTaskExecutor; import org.gephi.visualization.VizController; import org.gephi.visualization.api.selection.SelectionManager; import org.openide.awt.StatusDisplayer; import org.openide.util.Lookup; import org.openide.util.lookup.ServiceProvider; /** * * @author Mathieu Bastian */ @ServiceProvider(service = ClusteringController.class) public class ClusteringControllerImpl implements ClusteringController { private LongTaskExecutor executor; private LongTaskErrorHandler errorHandler; public ClusteringControllerImpl() { executor = new LongTaskExecutor(true, "Clusterer", 10); errorHandler = new LongTaskErrorHandler() { public void fatalError(Throwable t) { Logger.getLogger("").log(Level.SEVERE, "", t.getCause() != null ? t.getCause() : t); } }; executor.setDefaultErrorHandler(errorHandler); } public void clusterize(final Clusterer clusterer) { //Get Graph GraphController gc = Lookup.getDefault().lookup(GraphController.class); final GraphModel graphModel = gc.getModel(); //Model final ClusteringModel model = Lookup.getDefault().lookup(ProjectController.class).getCurrentWorkspace().getLookup().lookup(ClusteringModel.class); //LongTask LongTask task = null; if (clusterer instanceof LongTask) { task = (LongTask) clusterer; } executor.execute(task, new Runnable() { public void run() { model.setRunning(true); clusterer.execute(graphModel); writeColumns(clusterer); model.setRunning(false); } }); } public void cancelClusterize(Clusterer clusterer) { executor.cancel(); } private void writeColumns(Clusterer clusterer) { Cluster[] clusters = clusterer.getClusters(); if (clusters != null && clusters.length > 0) { ClustererBuilder builder = getBuilder(clusterer); AttributeModel am = Lookup.getDefault().lookup(AttributeController.class).getModel(); String id = "clustering_" + builder.getName(); String title = "Clustering (" + builder.getName() + ")"; AttributeColumn col = am.getNodeTable().getColumn(id); if (col == null) { col = am.getNodeTable().addColumn(id, title, AttributeType.INT, AttributeOrigin.COMPUTED, null); StatusDisplayer.getDefault().setStatusText("A new column \"" + title + "\" has been created"); } for (int i = 0; i < clusters.length; i++) { Integer clusterId = new Integer(i); for (Node n : clusters[i].getNodes()) { n.getNodeData().getAttributes().setValue(col.getIndex(), clusterId); } } } } public void selectCluster(Cluster cluster) { SelectionManager selectionManager = VizController.getInstance().getSelectionManager(); selectionManager.resetSelection(); selectionManager.selectNodes(cluster.getNodes()); } public void groupCluster(Cluster cluster) { GraphModel gm = Lookup.getDefault().lookup(GraphController.class).getModel(); if (gm != null) { HierarchicalGraph graph = gm.getHierarchicalGraphVisible(); Node[] newGroup = cluster.getNodes(); float centroidX = 0; float centroidY = 0; int len = 0; Node group = graph.groupNodes(newGroup); cluster.setMetaNode(group); group.getNodeData().setLabel("Group"); group.getNodeData().setSize(10f); for (Node child : newGroup) { centroidX += child.getNodeData().x(); centroidY += child.getNodeData().y(); len++; } centroidX /= len; centroidY /= len; group.getNodeData().setX(centroidX); group.getNodeData().setY(centroidY); } } public void ungroupCluster(Cluster cluster) { GraphModel gm = Lookup.getDefault().lookup(GraphController.class).getModel(); if (gm != null) { HierarchicalGraph graph = gm.getHierarchicalGraphVisible(); graph.ungroupNodes(cluster.getMetaNode()); cluster.setMetaNode(null); } } public boolean canGroup(Cluster cluster) { return cluster.getMetaNode() == null; } public boolean canUngroup(Cluster cluster) { return cluster.getMetaNode() != null; } private ClustererBuilder getBuilder(Clusterer clusterer) { for (ClustererBuilder b : Lookup.getDefault().lookupAll(ClustererBuilder.class)) { if (b.getClustererClass().equals(clusterer.getClass())) { return b; } } return null; } }