edu.uci.ics.jung.algorithms.layout.CircleLayout.java Source code

Java tutorial

Introduction

Here is the source code for edu.uci.ics.jung.algorithms.layout.CircleLayout.java

Source

/*
 * Copyright (c) 2003, the JUNG Project and the Regents of the University 
 * of California
 * All rights reserved.
 *
 * This software is open-source under the BSD license; see either
 * "license.txt" or
 * http://jung.sourceforge.net/license.txt for a description.
 */
/*
 * Created on Dec 4, 2003
 */
package edu.uci.ics.jung.algorithms.layout;

import java.awt.Dimension;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections15.Factory;
import org.apache.commons.collections15.map.LazyMap;

import edu.uci.ics.jung.graph.Graph;

/**
 * A {@code Layout} implementation that positions vertices equally spaced on a regular circle.
 *
 * @author Masanori Harada
 */
public class CircleLayout<V, E> extends AbstractLayout<V, E> {

    private double radius;
    private List<V> vertex_ordered_list;

    Map<V, CircleVertexData> circleVertexDataMap = LazyMap.decorate(new HashMap<V, CircleVertexData>(),
            new Factory<CircleVertexData>() {
                public CircleVertexData create() {
                    return new CircleVertexData();
                }
            });

    /**
     * Creates an instance for the specified graph.
     */
    public CircleLayout(Graph<V, E> g) {
        super(g);
    }

    /**
     * Returns the radius of the circle.
     */
    public double getRadius() {
        return radius;
    }

    /**
     * Sets the radius of the circle.  Must be called before
     * {@code initialize()} is called.
     */
    public void setRadius(double radius) {
        this.radius = radius;
    }

    /**
     * Sets the order of the vertices in the layout according to the ordering
     * specified by {@code comparator}.
     */
    public void setVertexOrder(Comparator<V> comparator) {
        if (vertex_ordered_list == null)
            vertex_ordered_list = new ArrayList<V>(getGraph().getVertices());
        Collections.sort(vertex_ordered_list, comparator);
    }

    /**
     * Sets the order of the vertices in the layout according to the ordering
     * of {@code vertex_list}.
     */
    public void setVertexOrder(List<V> vertex_list) {
        if (!vertex_list.containsAll(getGraph().getVertices()))
            throw new IllegalArgumentException("Supplied list must include " + "all vertices of the graph");
        this.vertex_ordered_list = vertex_list;
    }

    public void reset() {
        initialize();
    }

    public void initialize() {
        Dimension d = getSize();

        if (d != null) {
            if (vertex_ordered_list == null)
                setVertexOrder(new ArrayList<V>(getGraph().getVertices()));

            double height = d.getHeight();
            double width = d.getWidth();

            if (radius <= 0) {
                radius = 0.45 * (height < width ? height : width);
            }

            int i = 0;
            for (V v : vertex_ordered_list) {
                Point2D coord = transform(v);

                double angle = (2 * Math.PI * i) / vertex_ordered_list.size();

                coord.setLocation(Math.cos(angle) * radius + width / 2, Math.sin(angle) * radius + height / 2);

                CircleVertexData data = getCircleData(v);
                data.setAngle(angle);
                i++;
            }
        }
    }

    protected CircleVertexData getCircleData(V v) {
        return circleVertexDataMap.get(v);
    }

    protected static class CircleVertexData {
        private double angle;

        protected double getAngle() {
            return angle;
        }

        protected void setAngle(double angle) {
            this.angle = angle;
        }

        @Override
        public String toString() {
            return "CircleVertexData: angle=" + angle;
        }
    }
}