KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > faceless > graph2 > NumericAxis


1 // $Id: NumericAxis.java,v 1.9 2005/06/06 17:10:48 mike Exp $
2

3 package org.faceless.graph2;
4
5 import java.text.NumberFormat JavaDoc;
6 import java.util.Locale JavaDoc;
7
8 /**
9  * The most common type of Axis, a NumericAxis is used to display numbers, either
10  * as integers, real numbers, percentages, currency amounts or any type of format
11  * that can be created with a {@link NumberFormat}.
12  */

13 public class NumericAxis extends Axis
14 {
15     private NumberFormat JavaDoc f;
16     private final int density;
17     private boolean stretch, integer;
18
19     /**
20      * Return a NumericAxis that formats it's values as integers
21      */

22     public static final NumericAxis getIntegerAxis()
23     {
24     return new NumericAxis(NumberFormat.getIntegerInstance());
25     }
26
27     /**
28      * Return a NumericAxis that formats it's values as real numbers
29      */

30     public static final NumericAxis getFloatingPointAxis()
31     {
32     return new NumericAxis(NumberFormat.getNumberInstance());
33     }
34
35     /**
36      * Return a NumericAxis that formats it's values as currencies in
37      * the specified locale.
38      * @param locale which Locale to use for currencies, or <code>null</code> to use the default locale
39      */

40     public static final NumericAxis getCurrencyAxis(Locale JavaDoc locale)
41     {
42     return new NumericAxis(NumberFormat.getCurrencyInstance(locale==null ? Locale.getDefault() : locale));
43     }
44
45     /**
46      * Create a new NumericAxis with the specified format and the default density.
47      * @param format the format to use to display the values
48      */

49     public NumericAxis(NumberFormat JavaDoc format)
50     {
51     this(format, DENSITY_NORMAL);
52     }
53
54     /**
55      * Create a new NumericAxis with the specified format and densty
56      * @param format the format to use to display the values
57      * @param density the density to use - one of {@link Axis#DENSITY_NORMAL}, {@link Axis#DENSITY_SPARSE} or {@link Axis#DENSITY_MINIMAL}
58      */

59     public NumericAxis(NumberFormat JavaDoc format, int density)
60     {
61     setFormat(format);
62     this.density = density;
63         stretch = true;
64     }
65
66     void setFormat(NumberFormat JavaDoc format)
67     {
68         f=format;
69     this.integer = format(1).equals(format(1.4));
70     }
71
72     boolean isInteger() { return integer; }
73
74     public String JavaDoc format(double in)
75     {
76     if (in==-0.0) in=0;
77     synchronized(f) {
78         return f.format(in);
79     }
80     }
81
82     /**
83      * Whether to "stretch" the ends of the graph to a "useful" value or
84      * not. For instance, when this setting is on, plotting values from
85      * 0 to 98 will result in an axis that runs from 0 to 100. Turning
86      * it off means the top of the graph stops at exactly 98. This
87      * setting is on by default
88      * @param stretch whether to stretch the ends of the graph
89      */

90     public void setStretchEnds(boolean stretch)
91     {
92         this.stretch = stretch;
93     }
94
95     /**
96      * <p>
97      * Which steps between min and max should be marked with a tooth.
98      * This method returns the default settings, which is to calculate
99      * a number of "useful" values between min and max, possibly rounding
100      * those two values up or down to fit the scale. The number of values
101      * returned depends on the density setting.
102      * </p>
103      */

104     public double[] steps(double min, double max)
105     {
106     double[] out;
107     double ss = stepSize(min, max);
108     if (integer) ss = Math.ceil(ss);
109
110     if (ss==0) {
111         out = new double[1];
112         out[0] = min;
113     } else {
114         double newmin = Math.floor(min/ss)*ss;
115         double newmax = Math.ceil(max/ss)*ss;
116         if (!stretch) {
117             if (newmin+ss-min < min-newmin) newmin+=ss;
118             if (max-newmax+ss < newmax-max) newmax-=ss;
119         }
120         int num = (int)Math.floor((newmax+(ss/5)-newmin)/ss);
121         out = new double[num+1];
122         for (int i=0;i<out.length;i++) {
123         out[i] = newmin+(ss*i);
124         if (integer) out[i] = Math.floor(out[i]);
125         }
126         if (!stretch) {
127         out[0] = min;
128         out[out.length-1] = max;
129         }
130     }
131     return out;
132     }
133
134     private static final double diffs[] = { 0, 1, 2, 5, 5, 5, 5, 5, 10, 10, 10 };
135     private double stepSize(double min, double max)
136     {
137     double diff = Math.abs(max-min);
138     if (diff==0) return 0;
139     diff/=density;
140
141     double mul=1;
142     while (diff<1) {
143         mul *= 10;
144         diff *= 10;
145     }
146
147     while (diff>10) {
148         mul /= 10;
149         diff /= 10;
150     }
151
152     diff = Math.round(diff);
153     diff = diffs[(int)diff]/mul;
154
155     return diff;
156     }
157 }
158
Popular Tags