/*
* Copyright (c) 2005, 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 Mar 8, 2005
*
*/
package edu.uci.ics.jung.visualization.control;
import java.awt.geom.Point2D;
import edu.uci.ics.jung.visualization.Layer;
import edu.uci.ics.jung.visualization.VisualizationServer;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.transform.MutableTransformer;
/**
* A scaling control that has a crossover point.
* When the overall scale of the view and
* model is less than the crossover point, the scaling is applied
* to the view's transform and the graph nodes, labels, etc grow
* smaller. This preserves the overall shape of the graph.
* When the scale is larger than the crossover, the scaling is
* applied to the graph layout. The graph spreads out, but the
* vertices and labels grow no larger than their original size.
*
* @author Tom Nelson
*/
public class CrossoverScalingControl implements ScalingControl {
/**
* Point where scale crosses over from view to layout.
*/
protected double crossover = 1.0;
/**
* Sets the crossover point to the specified value.
*/
public void setCrossover(double crossover) {
this.crossover = crossover;
}
/**
* Returns the current crossover value.
*/
public double getCrossover() {
return crossover;
}
/**
* @see edu.uci.ics.jung.visualization.control.ScalingControl#scale(VisualizationViewer, float, Point2D)
*/
public void scale(VisualizationServer<?,?> vv, float amount, Point2D at) {
MutableTransformer layoutTransformer = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT);
MutableTransformer viewTransformer = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW);
double modelScale = layoutTransformer.getScale();
double viewScale = viewTransformer.getScale();
double inverseModelScale = Math.sqrt(crossover)/modelScale;
double inverseViewScale = Math.sqrt(crossover)/viewScale;
double scale = modelScale * viewScale;
Point2D transformedAt = vv.getRenderContext().getMultiLayerTransformer().inverseTransform(Layer.VIEW, at);
if((scale*amount - crossover)*(scale*amount - crossover) < 0.001) {
// close to the control point, return both transformers to a scale of sqrt crossover value
layoutTransformer.scale(inverseModelScale, inverseModelScale, transformedAt);
viewTransformer.scale(inverseViewScale, inverseViewScale, at);
} else if(scale*amount < crossover) {
// scale the viewTransformer, return the layoutTransformer to sqrt crossover value
viewTransformer.scale(amount, amount, at);
layoutTransformer.scale(inverseModelScale, inverseModelScale, transformedAt);
} else {
// scale the layoutTransformer, return the viewTransformer to crossover value
layoutTransformer.scale(amount, amount, transformedAt);
viewTransformer.scale(inverseViewScale, inverseViewScale, at);
}
vv.repaint();
}
}