sizeawarecirclelayout.java

来自「Semantic Web Ontology Editor」· Java 代码 · 共 166 行

JAVA
166
字号
/*
 * Created on Oct 25, 2005
 */
package org.mindswap.swoop.utils.graph.hierarchy.layout;

import java.awt.Dimension;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.mindswap.swoop.utils.graph.hierarchy.OntologyGraphNode;
import org.mindswap.swoop.utils.graph.hierarchy.OntologyWithClassHierarchyGraph;

import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.utils.Pair;
import edu.uci.ics.jung.utils.UserData;
import edu.uci.ics.jung.visualization.AbstractLayout;
import edu.uci.ics.jung.visualization.Coordinates;


/**
 * @author Dave Wang
 *
 * Code taken, modified from edu.uci.ics.jung.visualization.contrib.CircleLayout
 * 
 * Positions vertices equally spaced on a regular circle.
 * Does not respect filter calls.
 *
 */
public class SizeAwareCircleLayout extends AbstractLayout {
	private static final Object CIRCLE_KEY = "swoop.Circle_Visualization_Key";
	private Pair key;
	private double radius;

	public SizeAwareCircleLayout(Graph g) {
		super(g);
		key = new Pair(this, CIRCLE_KEY);
	}

	public String getStatus() {
		return "SizeAwareCircleLayout";
	}
	
	/**
	 * This one is not incremental.
	 */
	public boolean isIncremental() 
	{ return false; }

	/**
	 * Returns true;
	 */
	public boolean incrementsAreDone() 
	{ return true; }

	public double getRadius() 
	{ return radius; }

	public void setRadius(double radius) 
	{ this.radius = radius; }

	/**
	 * Specifies the order of vertices.  The first element of the
	 * specified array will be positioned with angle 0 (on the X
	 * axis), and the second one will be positioned with angle 1/n,
	 * and the third one will be positioned with angle 2/n, and so on.
	 * <p>
	 * The default implemention shuffles elements randomly.
	 */
	public void orderVertices(Vertex[] vertices) 
	{
		List list = Arrays.asList(vertices);
		Collections.shuffle(list);
	}

	/**
	 * Returns a visualization-specific key (that is, specific both
	 * to this instance and <tt>AbstractLayout</tt>) that can be used
	 * to access UserData related to the <tt>AbstractLayout</tt>.
	 */
	public Object getKey() {
		if (key == null)
			key = new Pair(this, CIRCLE_KEY);
		return key;
	}

	protected void initialize_local_vertex(Vertex v) {
		if (v.getUserDatum(getKey()) == null) {
			v.addUserDatum(getKey(), new CircleVertexData(), UserData.REMOVE);
		}
	}

	protected void initialize_local() {}

	protected void initializeLocations() {
		super.initializeLocations();

		Vertex[] vertices =
		(Vertex[]) getVisibleVertices().toArray(new Vertex[0]);
		orderVertices(vertices);

		int max1 = 0;
		int max2 = 0;
		for ( int i = 0; i < vertices.length; i++ )
		{
			Vertex v = vertices[i];
			int r = ((OntologyGraphNode) v.getUserDatum(OntologyWithClassHierarchyGraph.DATA)).getRadius();
			if ( r > max1 )
			{
				max2 = max1;
				max1 = r;
			}
			else if ( r > max2 )
				max2 = r;
		}
		
		radius = max1 + max2;
		
		Dimension d = getCurrentSize();
		double height = d.getHeight();
		double width = d.getWidth();

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

		for (int i = 0; i < vertices.length; i++) {
			Coordinates coord = getCoordinates(vertices[i]);

			double angle = (2 * Math.PI * i) / vertices.length;
			coord.setX(Math.cos(angle) * radius + width / 2);
			coord.setY(Math.sin(angle) * radius + height / 2);

			CircleVertexData data = getCircleData(vertices[i]);
			data.setAngle(angle);
		}
	}

	public CircleVertexData getCircleData(Vertex v) {
		return (CircleVertexData) (v.getUserDatum(getKey()));
	}

	/**
	 * Do nothing.
	 */
	public void advancePositions() 
	{ }

	public static class CircleVertexData {
		private double angle;

		public double getAngle() {
			return angle;
		}

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

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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?