KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > monitorenter > gui > chart > labelformatters > LabelFormatterAutoUnits


1 /*
2  * LabelFormatterAutoUnits.java, <enter purpose here>.
3  * Copyright (C) 2006 Achim Westermann, Achim.Westermann@gmx.de
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * If you modify or optimize the code in a useful way please let me know.
20  * Achim.Westermann@gmx.de
21  */

22 package info.monitorenter.gui.chart.labelformatters;
23
24 import info.monitorenter.gui.chart.IAxis;
25 import info.monitorenter.util.Range;
26 import info.monitorenter.util.units.AUnit;
27 import info.monitorenter.util.units.UnitFactory;
28 import info.monitorenter.util.units.UnitSystemSI;
29
30 import java.text.NumberFormat JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.Map JavaDoc;
34
35 /**
36  * A formatter that adds a "unit-functionality" to a given
37  * {@link info.monitorenter.gui.chart.ILabelFormatter}.
38  * <p>
39  *
40  * The formatted Strings will be divided by a factor according to the automatic
41  * chosen unit.
42  * <p>
43  *
44  * @author <a HREF="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
45  *
46  * @version $Revision: 1.1 $
47  *
48  */

49 public class LabelFormatterAutoUnits extends ALabelFormatter {
50
51   /**
52    * Performance improvement: Maps the units to use to the powers of 10 of their
53    * factor <nobr>(1*10^x = unit.factor) </nobr>.
54    * <p>
55    *
56    * This is used to modifiy the result of {@link #getMaxAmountChars()} as this
57    * unit factor will increase or decrease the characters to display.
58    * <p>
59    *
60    */

61   private static final Map JavaDoc UNITS_2_POWER = new HashMap JavaDoc();
62
63   static {
64     Iterator JavaDoc itUnits = UnitFactory.getInstance().getUnits(UnitSystemSI.getInstance()).iterator();
65     AUnit unit;
66     double factor = 0;
67     int power;
68     while (itUnits.hasNext()) {
69       power = 0;
70       unit = (AUnit) itUnits.next();
71       factor = unit.getFactor();
72       if (factor > 1) {
73         while (factor > 1) {
74           factor /= 10;
75           power++;
76         }
77
78       } else if (factor < 1) {
79         while (factor < 1) {
80           factor *= 10;
81           power--;
82         }
83       }
84       LabelFormatterAutoUnits.UNITS_2_POWER.put(unit, new Integer JavaDoc(power));
85     }
86   }
87
88   /**
89    * The decorated instance.
90    */

91   private ALabelFormatter m_delegate;
92
93   /**
94    * The internal unit.
95    * <p>
96    *
97    * In this implementation it is only used for finding labels that match the
98    * ticks.
99    * <p>
100    *
101    * @see #setMajorTickSpacing(double)
102    * @see #setMinorTickSpacing(double)
103    */

104   private AUnit m_unit = UNIT_UNCHANGED;
105
106   /**
107    * Creates an instance that will add "unit-functionality" to the given
108    * formatter.
109    * <p>
110    *
111    * @param delegate
112    * the formatter that will be decorated with units.
113    */

114   public LabelFormatterAutoUnits(final ALabelFormatter delegate) {
115     super();
116     this.m_delegate = delegate;
117   }
118
119   /**
120    * Internally sets the correct <code>{@link Unit}</code> corresponding to
121    * the range of this axis.
122    * <p>
123    *
124    * This is used in this implementations for calculation of the labels.
125    * <p>
126    *
127    * @param min
128    * the minimum value of the axis.
129    * @param max
130    * the maximum value of the axis.
131    *
132    * @see #getScaleValues()
133    * @see #setMajorTickSpacing(double)
134    * @see #setMinorTickSpacing(double)
135    */

136   private final void chooseUnit(final double min, final double max) {
137     double range = this.getAxis().getRange().getExtent();
138     if (range == 0) {
139       range = 1;
140     }
141     this.m_unit = UnitFactory.getInstance().getUnit(range, UnitSystemSI.getInstance());
142     if (range / this.m_unit.getFactor() < 3) {
143       this.m_unit = this.m_unit.getNexLowerUnit();
144     }
145   }
146
147   /**
148    * @see java.lang.Object#equals(java.lang.Object)
149    */

150   public boolean equals(final Object JavaDoc obj) {
151     return this.m_delegate.equals(obj);
152   }
153
154   /**
155    * @see info.monitorenter.gui.chart.ILabelFormatter#format(double)
156    */

157   public String JavaDoc format(final double value) {
158     double tmp = value / this.m_unit.getFactor();
159     return this.m_delegate.format(tmp);
160   }
161
162   /**
163    * @see ALabelFormatter#getAxis()
164    */

165   public IAxis getAxis() {
166     return this.m_delegate.getAxis();
167   }
168
169   /**
170    * @see ALabelFormatter#getMaxAmountChars()
171    */

172   public int getMaxAmountChars() {
173     // find the fractions by using range information:
174
int fractionDigits = 0;
175     Range range = this.getAxis().getRange();
176     double dRange = range.getExtent() / this.m_unit.getFactor();
177     if (dRange < 1) {
178       if (dRange == 0) {
179         fractionDigits = 1;
180       } else {
181         if (dRange == 0) {
182           fractionDigits = 1;
183         } else {
184           // find the power
185
while (dRange < 1) {
186             dRange *= 10;
187             fractionDigits++;
188           }
189         }
190       }
191     } else {
192       if (dRange < 10) {
193         fractionDigits = 2;
194       } else if (dRange < 100) {
195         fractionDigits = 1;
196       } else {
197         fractionDigits = 0;
198       }
199     }
200
201     // find integer digits by using longest value:
202
int integerDigits = 0;
203     double max = range.getMax() / (this.m_unit.getFactor());
204     double min = Math.abs(range.getMin()) / (this.m_unit.getFactor());
205     if (max == 0 && min == 0) {
206       integerDigits = 1;
207     } else if (max < min) {
208       while (min > 1) {
209         min /= 10;
210         integerDigits++;
211       }
212     } else {
213       while (max > 1) {
214         max /= 10;
215         integerDigits++;
216       }
217     }
218     // check if the internal numberformat would cut values and cause rendering
219
// errors:
220
if (this.m_delegate instanceof LabelFormatterNumber) {
221
222       NumberFormat JavaDoc nf = ((LabelFormatterNumber) this.m_delegate).getNumberFormat();
223       if (integerDigits > nf.getMaximumIntegerDigits()) {
224         nf.setMaximumIntegerDigits(integerDigits);
225       }
226       if (fractionDigits > nf.getMaximumFractionDigits()) {
227         nf.setMaximumFractionDigits(fractionDigits);
228       }
229     }
230     // <sign> integerDigits <dot> fractionDigits:
231
return 1 + integerDigits + 1 + fractionDigits;
232
233   }
234
235   /**
236    * @see info.monitorenter.gui.chart.ILabelFormatter#getMaxAmountChars()
237    */

238   public double getMinimumValueShiftForChange() {
239     return this.m_delegate.getMinimumValueShiftForChange() * this.m_unit.getFactor();
240   }
241
242   /**
243    * @see info.monitorenter.gui.chart.ILabelFormatter#getNextEvenValue(double,
244    * boolean)
245    */

246   public double getNextEvenValue(final double value, final boolean ceiling) {
247     return this.m_delegate.getNextEvenValue(value, ceiling);
248   }
249
250   /**
251    * @see info.monitorenter.gui.chart.ILabelFormatter#getUnit()
252    */

253   public AUnit getUnit() {
254     return this.m_unit;
255   }
256
257   /**
258    * @see java.lang.Object#hashCode()
259    */

260   public int hashCode() {
261     return this.m_delegate.hashCode();
262   }
263
264   /**
265    * @see info.monitorenter.gui.chart.ILabelFormatter#initPaintIteration()
266    */

267   public void initPaintIteration() {
268     Range domain = this.m_delegate.getAxis().getRange();
269     this.chooseUnit(domain.getMin(), domain.getMax());
270   }
271
272   /**
273    * @see info.monitorenter.gui.chart.ILabelFormatter#parse(String)
274    */

275   public Number JavaDoc parse(final String JavaDoc formatted) throws NumberFormatException JavaDoc {
276     double parsed = this.m_delegate.parse(formatted).doubleValue();
277     parsed *= this.m_unit.getFactor();
278     return new Double JavaDoc(parsed);
279   }
280
281   /**
282    * @see ALabelFormatter#setAxis(IAxis)
283    */

284   public void setAxis(final IAxis axis) {
285
286     this.m_delegate.setAxis(axis);
287   }
288
289   /**
290    * @see java.lang.Object#toString()
291    */

292   public String JavaDoc toString() {
293     return this.m_delegate.toString();
294   }
295 }
296
Popular Tags