View Javadoc
1   /*
2    * Copyright (c) 2005, The JUNG Authors 
3    *
4    * All rights reserved.
5    *
6    * This software is open-source under the BSD license; see either
7    * "license.txt" or
8    * https://github.com/jrtom/jung/blob/master/LICENSE for a description.
9    * Created on Mar 8, 2005
10   *
11   */
12  package edu.uci.ics.jung.visualization.control;
13  
14  import java.awt.geom.Point2D;
15  
16  import edu.uci.ics.jung.visualization.Layer;
17  import edu.uci.ics.jung.visualization.VisualizationServer;
18  import edu.uci.ics.jung.visualization.transform.MutableTransformer;
19  
20  /** 
21   * A scaling control that has a crossover point.
22   * When the overall scale of the view and
23   * model is less than the crossover point, the scaling is applied
24   * to the view's transform and the graph nodes, labels, etc grow
25   * smaller. This preserves the overall shape of the graph.
26   * When the scale is larger than the crossover, the scaling is
27   * applied to the graph layout. The graph spreads out, but the
28   * vertices and labels grow no larger than their original size. 
29   * 
30   * @author Tom Nelson
31   */
32  public class CrossoverScalingControl implements ScalingControl {
33  
34      /**
35       * Point where scale crosses over from view to layout.
36       */
37      protected double crossover = 1.0;
38      
39      /**
40       * Sets the crossover point to the specified value.
41       * @param crossover the crossover point to use (defaults to 1.0)
42       */
43  	public void setCrossover(double crossover) {
44  	    this.crossover = crossover;
45  	}
46  
47      /**
48       * @return the current crossover value
49       */
50      public double getCrossover() {
51          return crossover;
52      }
53      
54  	public void scale(VisualizationServer<?,?> vv, float amount, Point2D at) {
55  	        
56  	    MutableTransformer layoutTransformer = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT);
57  	    MutableTransformer viewTransformer = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW);
58  	    double modelScale = layoutTransformer.getScale();
59  	    double viewScale = viewTransformer.getScale();
60  	    double inverseModelScale = Math.sqrt(crossover)/modelScale;
61  	    double inverseViewScale = Math.sqrt(crossover)/viewScale;
62  	    double scale = modelScale * viewScale;
63  	    
64  	    Point2D transformedAt = vv.getRenderContext().getMultiLayerTransformer().inverseTransform(Layer.VIEW, at);
65  	    
66          if((scale*amount - crossover)*(scale*amount - crossover) < 0.001) {
67              // close to the control point, return both Functions to a scale of sqrt crossover value
68              layoutTransformer.scale(inverseModelScale, inverseModelScale, transformedAt);
69              viewTransformer.scale(inverseViewScale, inverseViewScale, at);
70          } else if(scale*amount < crossover) {
71              // scale the viewTransformer, return the layoutTransformer to sqrt crossover value
72  	        viewTransformer.scale(amount, amount, at);
73  	        layoutTransformer.scale(inverseModelScale, inverseModelScale, transformedAt);
74  	    } else {
75              // scale the layoutTransformer, return the viewTransformer to crossover value
76  	        layoutTransformer.scale(amount, amount, transformedAt);
77  	        viewTransformer.scale(inverseViewScale, inverseViewScale, at);
78  	    }
79  	    vv.repaint();
80  	}
81  }