Package org.gephi.partition.impl

Source Code of org.gephi.partition.impl.PartitionControllerImpl

/*
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.partition.impl;

import java.util.ArrayList;
import java.util.List;
import org.gephi.data.attributes.api.AttributeEvent;
import org.gephi.data.attributes.api.AttributeTable;
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.api.AttributeUtils;
import org.gephi.data.attributes.api.Estimator;
import org.gephi.data.attributes.type.TimeInterval;
import org.gephi.dynamic.api.DynamicModel;
import org.gephi.graph.api.Graph;
import org.gephi.graph.api.GraphController;
import org.gephi.graph.api.GraphEvent;
import org.gephi.graph.api.GraphListener;
import org.gephi.graph.api.GraphModel;
import org.gephi.graph.api.HierarchicalGraph;
import org.gephi.graph.api.Node;
import org.gephi.partition.api.EdgePartition;
import org.gephi.partition.api.NodePartition;
import org.gephi.partition.api.Part;
import org.gephi.partition.api.Partition;
import org.gephi.partition.api.PartitionController;
import org.gephi.partition.api.PartitionModel;
import org.gephi.partition.spi.Transformer;
import org.gephi.partition.spi.TransformerBuilder;
import org.gephi.project.api.ProjectController;
import org.gephi.project.api.Workspace;
import org.gephi.project.api.WorkspaceListener;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;

/**
*
* @author Mathieu Bastian
*/
@ServiceProvider(service = PartitionController.class)
public class PartitionControllerImpl implements PartitionController, AttributeListener {

    private PartitionModelImpl model;
    private boolean refreshPartitions = true;

    public PartitionControllerImpl() {

        ProjectController pc = Lookup.getDefault().lookup(ProjectController.class);
        pc.addWorkspaceListener(new WorkspaceListener() {

            public void initialize(Workspace workspace) {
                workspace.add(new PartitionModelImpl());
            }

            public void select(Workspace workspace) {
                model = workspace.getLookup().lookup(PartitionModelImpl.class);
                if (model == null) {
                    model = new PartitionModelImpl();
                    workspace.add(model);
                }
                refreshPartitions = true;
                GraphModel gm = Lookup.getDefault().lookup(GraphController.class).getModel(workspace);
                trachViewChange(gm);
                AttributeModel attributeModel = Lookup.getDefault().lookup(AttributeController.class).getModel(workspace);
                attributeModel.addAttributeListener(PartitionControllerImpl.this);
            }

            public void unselect(Workspace workspace) {
                GraphModel gm = Lookup.getDefault().lookup(GraphController.class).getModel(workspace);
                untrackViewChange(gm);
                model = null;
                AttributeModel attributeModel = workspace.getLookup().lookup(AttributeModel.class);
                attributeModel.removeAttributeListener(PartitionControllerImpl.this);
            }

            public void close(Workspace workspace) {
            }

            public void disable() {
                untrackViewChange(null);
            }
        });
        if (pc.getCurrentWorkspace() != null) {
            refreshPartitions = true;
            model = pc.getCurrentWorkspace().getLookup().lookup(PartitionModelImpl.class);
            if (model == null) {
                model = new PartitionModelImpl();
                Workspace workspace = pc.getCurrentWorkspace();
                pc.getCurrentWorkspace().add(model);
                GraphModel gm = Lookup.getDefault().lookup(GraphController.class).getModel(workspace);
                trachViewChange(gm);

                AttributeModel attributeModel = Lookup.getDefault().lookup(AttributeController.class).getModel(workspace);
                attributeModel.addAttributeListener(PartitionControllerImpl.this);
            }
        }
    }
    private GraphListener graphListener;

    private void trachViewChange(final GraphModel graphModel) {
        untrackViewChange(graphModel);
        if (model.getVisibleViewId() == -1) {
            model.setVisibleViewId(graphModel.getVisibleView().getViewId());
        }
        graphListener = new GraphListener() {

            public void graphChanged(GraphEvent event) {
                if (event.is(GraphEvent.EventType.VISIBLE_VIEW)) {
                    if (model.getVisibleViewId() != graphModel.getVisibleView().getViewId()) {
                        //View has been updated
                        model.setVisibleViewId(graphModel.getVisibleView().getViewId());
                        setSelectedPartition(null);
                    }
                }
            }
        };

        graphModel.addGraphListener(graphListener);
    }

    private void untrackViewChange(GraphModel graphModel) {
        if (graphListener != null && graphModel != null) {
            graphModel.removeGraphListener(graphListener);
        }
        graphListener = null;
    }

    public void attributesChanged(AttributeEvent event) {
        refreshPartitions = true;
    }

    public void setSelectedPartition(final Partition partition) {
        if (partition == model.getSelectedPartition()) {
            return;
        }
        model.setWaiting(true);
        if (model.getSelectedPartitioning() == PartitionModel.NODE_PARTITIONING) {
            Thread t = new Thread(new Runnable() {

                public void run() {
                    if (partition != null) {
                        GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel();

                        DynamicModel dynamicModel = model.getDynamicModel();
                        TimeInterval timeInterval = dynamicModel != null ? dynamicModel.getVisibleInterval() : null;
                        Estimator estimator = AttributeUtils.getDefault().isDynamicNumberColumn(partition.getColumn()) ? model.getNumberEstimator() : model.getEstimator();
                        PartitionFactory.buildNodePartition((NodePartition) partition, graphModel.getGraphVisible(), timeInterval, estimator);
                    }
                    model.setNodePartition(partition);
                    if (model.getNodeTransformerBuilder() == null) {
                        //Select the first transformer
                        TransformerBuilder[] builders = Lookup.getDefault().lookupAll(TransformerBuilder.class).toArray(new TransformerBuilder[0]);
                        for (int i = 0; i < builders.length; i++) {
                            TransformerBuilder t = builders[i];
                            if (t instanceof TransformerBuilder.Node) {
                                model.setNodeBuilder(t);
                                break;
                            }
                        }
                    }
                    model.setWaiting(false);
                }
            }, "Partition Model refresh");
            t.start();
        } else {
            Thread t = new Thread(new Runnable() {

                public void run() {
                    if (partition != null) {
                        GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel();

                        DynamicModel dynamicModel = model.getDynamicModel();
                        TimeInterval timeInterval = dynamicModel != null ? dynamicModel.getVisibleInterval() : null;
                        Estimator estimator = AttributeUtils.getDefault().isDynamicNumberColumn(partition.getColumn()) ? model.getNumberEstimator() : model.getEstimator();
                        PartitionFactory.buildEdgePartition((EdgePartition) partition, graphModel.getGraphVisible(), timeInterval, estimator);
                    }
                    model.setEdgePartition(partition);
                    if (model.getEdgeTransformerBuilder() == null) {
                        //Select the first transformer
                        TransformerBuilder[] builders = Lookup.getDefault().lookupAll(TransformerBuilder.class).toArray(new TransformerBuilder[0]);
                        for (int i = 0; i < builders.length; i++) {
                            TransformerBuilder t = builders[i];
                            if (t instanceof TransformerBuilder.Edge) {
                                model.setEdgeBuilder(t);
                                break;
                            }
                        }
                    }
                    model.setWaiting(false);
                }
            }, "Partition Model refresh");
            t.start();
        }
    }

    public Partition buildPartition(AttributeColumn column, Graph graph) {
        DynamicModel dynamicModel = model.getDynamicModel();
        TimeInterval timeInterval = dynamicModel != null ? dynamicModel.getVisibleInterval() : null;

        if (AttributeUtils.getDefault().isNodeColumn(column)) {
            NodePartition partition = PartitionFactory.createNodePartition(column);
            Estimator estimator = AttributeUtils.getDefault().isDynamicNumberColumn(column) ? model.getNumberEstimator() : model.getEstimator();
            PartitionFactory.buildNodePartition(partition, graph, timeInterval, estimator);
            return partition;
        } else {
            EdgePartition partition = PartitionFactory.createEdgePartition(column);
            Estimator estimator = AttributeUtils.getDefault().isDynamicNumberColumn(column) ? model.getNumberEstimator() : model.getEstimator();
            PartitionFactory.buildEdgePartition(partition, graph, timeInterval, estimator);
            return partition;
        }
    }

    public void setSelectedPartitioning(final int partitioning) {
        model.setWaiting(true);

        Thread t = new Thread(new Runnable() {

            public void run() {
                model.setSelectedPartitioning(partitioning);
                model.setWaiting(false);
            }
        }, "Partition Model refresh");
        t.start();
    }

    public void setSelectedTransformerBuilder(final TransformerBuilder builder) {
        model.setWaiting(true);
        Thread t = new Thread(new Runnable() {

            public void run() {
                if (model.getSelectedPartitioning() == PartitionModel.NODE_PARTITIONING) {
                    model.setNodeBuilder(builder);
                } else {
                    model.setEdgeBuilder(builder);
                }
                model.setWaiting(false);
            }
        }, "Partition Model refresh");
        t.start();
    }

    public void refreshPartitions() {
        if (refreshPartitions) {
            refreshPartitions = false;
            AttributeController ac = Lookup.getDefault().lookup(AttributeController.class);
            GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel();

            //Nodes
            List<NodePartition> nodePartitions = new ArrayList<NodePartition>();
            AttributeTable nodeTable = ac.getModel().getNodeTable();
            Graph graph = graphModel.getGraphVisible();
            for (AttributeColumn column : nodeTable.getColumns()) {
                if (PartitionFactory.isPartitionColumn(column) && PartitionFactory.isNodePartitionColumn(column, graph)) {
                    nodePartitions.add(PartitionFactory.createNodePartition(column));
                } else if (PartitionFactory.isDynamicPartitionColumn(column)) {
                    DynamicModel dynamicModel = model.getDynamicModel();
                    TimeInterval timeInterval = dynamicModel != null ? dynamicModel.getVisibleInterval() : null;
                    Estimator estimator = AttributeUtils.getDefault().isDynamicNumberColumn(column) ? model.getNumberEstimator() : model.getEstimator();
                    if (PartitionFactory.isDynamicNodePartitionColumn(column, graph, timeInterval, estimator)) {
                        nodePartitions.add(PartitionFactory.createNodePartition(column));
                    }
                }
            }
            model.setNodePartitions(nodePartitions.toArray(new NodePartition[0]));

            //Edges
            List<EdgePartition> edgePartitions = new ArrayList<EdgePartition>();
            AttributeTable edgeClass = ac.getModel().getEdgeTable();
            for (AttributeColumn column : edgeClass.getColumns()) {
                if (PartitionFactory.isPartitionColumn(column) && PartitionFactory.isEdgePartitionColumn(column, graph)) {
                    edgePartitions.add(PartitionFactory.createEdgePartition(column));
                } else if (PartitionFactory.isDynamicPartitionColumn(column)) {
                    DynamicModel dynamicModel = model.getDynamicModel();
                    TimeInterval timeInterval = dynamicModel != null ? dynamicModel.getVisibleInterval() : null;
                    Estimator estimator = AttributeUtils.getDefault().isDynamicNumberColumn(column) ? model.getNumberEstimator() : model.getEstimator();
                    if (PartitionFactory.isDynamicEdgePartitionColumn(column, graph, timeInterval, estimator)) {
                        edgePartitions.add(PartitionFactory.createEdgePartition(column));
                    }
                }
            }
            model.setEdgePartitions(edgePartitions.toArray(new EdgePartition[0]));
        }
    }

    public void transform(Partition partition, Transformer transformer) {
        if (transformer != null && partition != null) {
            transformer.transform(partition);
        }
    }

    public boolean isGroupable(Partition partition) {
        if (partition instanceof NodePartition) {
            if (partition.getPartsCount() > 0) {
                NodePartition nodePartition = (NodePartition) partition;
                Node n0 = nodePartition.getParts()[0].getObjects()[0];
                GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel();
                HierarchicalGraph graph = graphModel.getHierarchicalGraphVisible();
                if (graph.contains(n0) && graph.getParent(n0) == null) {
                    return true;
                }
            }
        }
        return false;
    }

    public boolean isUngroupable(Partition partition) {
        if (partition instanceof NodePartition) {
            if (partition.getPartsCount() > 0) {
                NodePartition nodePartition = (NodePartition) partition;
                Node n0 = nodePartition.getParts()[0].getObjects()[0];
                GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel();
                HierarchicalGraph graph = graphModel.getHierarchicalGraphVisible();
                if (graph.contains(n0) && graph.getParent(n0) != null) {
                    return true;
                }
            }
        }
        return false;
    }

    public void group(Partition partition) {
        NodePartition nodePartition = (NodePartition) partition;
        GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel();
        HierarchicalGraph graph = graphModel.getHierarchicalGraphVisible();
        for (Part<Node> p : nodePartition.getParts()) {
            Node[] nodes = p.getObjects();
            List<Node> validNodes = new ArrayList<Node>();
            for (Node n : nodes) {
                if (graph.contains(n)) {
                    validNodes.add(n);
                }
            }
            if (!validNodes.isEmpty() && graph.getParent(validNodes.get(0)) == null) {
                float centroidX = 0;
                float centroidY = 0;
                float sizes = 0;
                float r = 0;
                float g = 0;
                float b = 0;
                int len = 0;
                for (Node n : validNodes) {
                    centroidX += n.getNodeData().x();
                    centroidY += n.getNodeData().y();
                    sizes += n.getNodeData().getSize();
                    r += n.getNodeData().r();
                    g += n.getNodeData().g();
                    b += n.getNodeData().b();
                    len++;
                }
                Node metaNode = graph.groupNodes(validNodes.toArray(new Node[0]));
                metaNode.getNodeData().setX(centroidX / len);
                metaNode.getNodeData().setY(centroidY / len);
                metaNode.getNodeData().setLabel(p.getDisplayName());
                metaNode.getNodeData().setSize(sizes / graph.getNodeCount() * 5f);
                metaNode.getNodeData().setColor(r / len, g / len, b / len);
            }
        }
    }

    public void ungroup(Partition partition) {
        NodePartition nodePartition = (NodePartition) partition;
        GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel();
        HierarchicalGraph graph = graphModel.getHierarchicalGraphVisible();
        for (Part<Node> p : nodePartition.getParts()) {
            Node[] nodes = p.getObjects();
            List<Node> validNodes = new ArrayList<Node>();
            for (Node n : nodes) {
                if (graph.contains(n)) {
                    validNodes.add(n);
                }
            }
            if (!validNodes.isEmpty()) {
                Node metaNode = graph.getParent(validNodes.get(0));
                if (metaNode != null) {
                    graph.ungroupNodes(metaNode);
                }
            }
        }
    }

    public void showPie(boolean showPie) {
        model.setPie(showPie);
    }

    public PartitionModel getModel() {
        return model;
    }
}
TOP

Related Classes of org.gephi.partition.impl.PartitionControllerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.