/*
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.ranking.impl;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import org.gephi.data.attributes.api.AttributeEvent;
import org.gephi.ranking.api.RankingModel;
import org.gephi.ranking.api.NodeRanking;
import org.gephi.ranking.api.EdgeRanking;
import org.gephi.ranking.api.Ranking;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.gephi.data.attributes.api.AttributeColumn;
import org.gephi.data.attributes.api.AttributeController;
import org.gephi.data.attributes.api.AttributeListener;
import org.gephi.data.attributes.api.AttributeModel;
import org.gephi.data.attributes.type.TimeInterval;
import org.gephi.dynamic.api.DynamicController;
import org.gephi.dynamic.api.DynamicModel;
import org.gephi.graph.api.DirectedGraph;
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.project.api.ProjectController;
import org.gephi.project.api.Workspace;
import org.gephi.project.api.WorkspaceListener;
import org.openide.util.Lookup;
/**
*
* @author Mathieu Bastian
*/
public class RankingModelImpl implements RankingModel, AttributeListener {
private final List<ChangeListener> listeners = new ArrayList<ChangeListener>();
private DynamicModel dynamicModel;
public RankingModelImpl() {
final ProjectController pc = Lookup.getDefault().lookup(ProjectController.class);
final AttributeController ac = Lookup.getDefault().lookup(AttributeController.class);
pc.addWorkspaceListener(new WorkspaceListener() {
public void initialize(Workspace workspace) {
}
public void select(Workspace workspace) {
AttributeModel attributeModel = workspace.getLookup().lookup(AttributeModel.class);
attributeModel.addAttributeListener(RankingModelImpl.this);
}
public void unselect(Workspace workspace) {
AttributeModel attributeModel = workspace.getLookup().lookup(AttributeModel.class);
attributeModel.removeAttributeListener(RankingModelImpl.this);
dynamicModel = null;
}
public void close(Workspace workspace) {
}
public void disable() {
dynamicModel = null;
}
});
if (pc.getCurrentWorkspace() != null) {
AttributeModel attributeModel = pc.getCurrentWorkspace().getLookup().lookup(AttributeModel.class);
attributeModel.addAttributeListener(RankingModelImpl.this);
}
}
private Timer refreshTimer; //hack
public void attributesChanged(AttributeEvent event) {
if (event.getEventType().equals(AttributeEvent.EventType.ADD_COLUMN) || event.getEventType().equals(AttributeEvent.EventType.REMOVE_COLUMN)) {
if (refreshTimer != null) {
refreshTimer.restart();
} else {
refreshTimer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireChangeEvent();
}
});
refreshTimer.setRepeats(false);
refreshTimer.start();
}
}
}
public NodeRanking getDegreeRanking() {
GraphModel model = Lookup.getDefault().lookup(GraphController.class).getModel();
Graph graph = model.getGraphVisible();
NodeRanking degreeRanking = RankingFactory.getNodeDegreeRanking(graph);
if (degreeRanking.getMinimumValue() != null && degreeRanking.getMaximumValue() != null && !degreeRanking.getMinimumValue().equals(degreeRanking.getMaximumValue())) {
return degreeRanking;
}
return null;
}
public NodeRanking getInDegreeRanking() {
GraphModel model = Lookup.getDefault().lookup(GraphController.class).getModel();
DirectedGraph graph = model.getDirectedGraphVisible();
NodeRanking degreeRanking = RankingFactory.getNodeInDegreeRanking(graph);
if (degreeRanking.getMinimumValue() != null && degreeRanking.getMaximumValue() != null && !degreeRanking.getMinimumValue().equals(degreeRanking.getMaximumValue())) {
return degreeRanking;
}
return null;
}
public NodeRanking getOutDegreeRanking() {
GraphModel model = Lookup.getDefault().lookup(GraphController.class).getModel();
DirectedGraph graph = model.getDirectedGraphVisible();
NodeRanking degreeRanking = RankingFactory.getNodeOutDegreeRanking(graph);
if (degreeRanking.getMinimumValue() != null && degreeRanking.getMaximumValue() != null && !degreeRanking.getMinimumValue().equals(degreeRanking.getMaximumValue())) {
return degreeRanking;
}
return null;
}
public NodeRanking getNodeAttributeRanking(AttributeColumn column) {
GraphModel model = Lookup.getDefault().lookup(GraphController.class).getModel();
Graph graph = model.getGraphVisible();
if (RankingFactory.isNumberColumn(column)) {
NodeRanking r = RankingFactory.getNodeAttributeRanking(column, graph);
if (r.getMinimumValue() != null && r.getMaximumValue() != null && !r.getMinimumValue().equals(r.getMaximumValue())) {
return r;
}
} else if (RankingFactory.isDynamicNumberColumn(column) && getDynamicModel() != null) {
TimeInterval visibleInterval = dynamicModel.getVisibleInterval();
NodeRanking r = RankingFactory.getNodeDynamicAttributeRanking(column, graph, visibleInterval, dynamicModel.getNumberEstimator());
if (r.getMinimumValue() != null && r.getMaximumValue() != null && !r.getMinimumValue().equals(r.getMaximumValue())) {
return r;
}
}
return null;
}
public EdgeRanking getEdgeAttributeRanking(AttributeColumn column) {
GraphModel model = Lookup.getDefault().lookup(GraphController.class).getModel();
Graph graph = model.getGraphVisible();
if (RankingFactory.isNumberColumn(column)) {
EdgeRanking r = RankingFactory.getEdgeAttributeRanking(column, graph);
if (r.getMinimumValue() != null && r.getMaximumValue() != null && !r.getMinimumValue().equals(r.getMaximumValue())) {
return r;
}
} else if (RankingFactory.isDynamicNumberColumn(column) && getDynamicModel() != null) {
TimeInterval visibleInterval = dynamicModel.getVisibleInterval();
EdgeRanking r = RankingFactory.getEdgeDynamicAttributeRanking(column, graph, visibleInterval, dynamicModel.getNumberEstimator());
if (r.getMinimumValue() != null && r.getMaximumValue() != null && !r.getMinimumValue().equals(r.getMaximumValue())) {
return r;
}
}
return null;
}
public NodeRanking[] getNodeRanking() {
AttributeController attributeController = Lookup.getDefault().lookup(AttributeController.class);
List<Ranking> rankingList = new ArrayList<Ranking>();
GraphModel model = Lookup.getDefault().lookup(GraphController.class).getModel();
Graph graph = model.getGraphVisible();
//Topology
NodeRanking degreeRanking = RankingFactory.getNodeDegreeRanking(graph);
if (degreeRanking.getMinimumValue() != null && degreeRanking.getMaximumValue() != null && !degreeRanking.getMinimumValue().equals(degreeRanking.getMaximumValue())) {
rankingList.add(degreeRanking);
}
if (model.isDirected()) {
DirectedGraph directedGraph = model.getDirectedGraphVisible();
NodeRanking inDegreeRanking = RankingFactory.getNodeInDegreeRanking(directedGraph);
if (inDegreeRanking.getMinimumValue() != null && inDegreeRanking.getMaximumValue() != null && !inDegreeRanking.getMinimumValue().equals(inDegreeRanking.getMaximumValue())) {
rankingList.add(inDegreeRanking);
}
NodeRanking outDegreeRanking = RankingFactory.getNodeOutDegreeRanking(directedGraph);
if (outDegreeRanking.getMinimumValue() != null && outDegreeRanking.getMaximumValue() != null && !outDegreeRanking.getMinimumValue().equals(outDegreeRanking.getMaximumValue())) {
rankingList.add(outDegreeRanking);
}
}
if (model.isHierarchical()) {
HierarchicalGraph hierarchicalGraph = model.getHierarchicalGraphVisible();
NodeRanking childrenRanking = RankingFactory.getNodeChildrenCountRanking(hierarchicalGraph);
if (childrenRanking.getMinimumValue() != null && childrenRanking.getMaximumValue() != null && !childrenRanking.getMinimumValue().equals(childrenRanking.getMaximumValue())) {
rankingList.add(childrenRanking);
}
}
//Attributes
int nativeCount = rankingList.size();
for (AttributeColumn column : attributeController.getModel().getNodeTable().getColumns()) {
if (RankingFactory.isNumberColumn(column)) {
NodeRanking r = RankingFactory.getNodeAttributeRanking(column, graph);
if (r.getMinimumValue() != null && r.getMaximumValue() != null && !r.getMinimumValue().equals(r.getMaximumValue())) {
rankingList.add(r);
}
} else if (RankingFactory.isDynamicNumberColumn(column) && getDynamicModel() != null) {
TimeInterval visibleInterval = dynamicModel.getVisibleInterval();
NodeRanking r = RankingFactory.getNodeDynamicAttributeRanking(column, graph, visibleInterval, dynamicModel.getNumberEstimator());
if (r.getMinimumValue() != null && r.getMaximumValue() != null && !r.getMinimumValue().equals(r.getMaximumValue())) {
rankingList.add(r);
}
}
}
NodeRanking[] rankingArray = rankingList.toArray(new NodeRanking[0]);
Arrays.sort(rankingArray, nativeCount, rankingArray.length, new Comparator<NodeRanking>() {
public int compare(NodeRanking a, NodeRanking b) {
return (a.toString().compareTo(b.toString()));
}
});
return rankingArray;
}
public EdgeRanking[] getEdgeRanking() {
AttributeController attributeController = Lookup.getDefault().lookup(AttributeController.class);
Graph graph = Lookup.getDefault().lookup(GraphController.class).getModel().getGraphVisible();
List<Ranking> rankingList = new ArrayList<Ranking>();
for (AttributeColumn column : attributeController.getModel().getEdgeTable().getColumns()) {
if (RankingFactory.isNumberColumn(column)) {
EdgeRanking r = RankingFactory.getEdgeAttributeRanking(column, graph);
if (r.getMinimumValue() != null && r.getMaximumValue() != null && !r.getMinimumValue().equals(r.getMaximumValue())) {
rankingList.add(r);
}
} else if (RankingFactory.isDynamicNumberColumn(column) && getDynamicModel() != null) {
TimeInterval visibleInterval = dynamicModel.getVisibleInterval();
EdgeRanking r = RankingFactory.getEdgeDynamicAttributeRanking(column, graph, visibleInterval, dynamicModel.getNumberEstimator());
if (r.getMinimumValue() != null && r.getMaximumValue() != null && !r.getMinimumValue().equals(r.getMaximumValue())) {
rankingList.add(r);
}
}
}
return rankingList.toArray(new EdgeRanking[0]);
}
public DynamicModel getDynamicModel() {
if (dynamicModel == null) {
DynamicController dynamicController = Lookup.getDefault().lookup(DynamicController.class);
if (dynamicController != null) {
dynamicModel = dynamicController.getModel();
}
}
return dynamicModel;
}
public void addChangeListener(ChangeListener changeListener) {
if (!listeners.contains(changeListener)) {
listeners.add(changeListener);
}
}
public void removeChangeListener(ChangeListener changeListener) {
listeners.remove(changeListener);
}
public void fireChangeEvent() {
ChangeEvent changeEvent = new ChangeEvent(this);
for (ChangeListener changeListener : listeners) {
changeListener.stateChanged(changeEvent);
}
}
}