KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jrobin > graph > ValueAxisUnit


1 /* ============================================================
2  * JRobin : Pure java implementation of RRDTool's functionality
3  * ============================================================
4  *
5  * Project Info: http://www.jrobin.org
6  * Project Lead: Sasa Markovic (saxon@jrobin.org);
7  *
8  * (C) Copyright 2003, by Sasa Markovic.
9  *
10  * This library is free software; you can redistribute it and/or modify it under the terms
11  * of the GNU Lesser General Public License as published by the Free Software Foundation;
12  * either version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License along with this
19  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */

22 /*
23  * Created on 29-aug-2003
24  *
25  * To change the template for this generated file go to
26  * Window - Preferences - Java - Code Generation - Code and Comments
27  */

28 package org.jrobin.graph;
29
30 import org.jrobin.core.XmlWriter;
31
32 import java.util.*;
33
34 /**
35  * <p>Class used to determine the chart grid shown on the Y (value) axis.</p>
36  *
37  * @author Arne Vandamme (cobralord@jrobin.org)
38  */

39 class ValueAxisUnit
40 {
41     // ================================================================
42
// -- Members
43
// ================================================================
44
private double gridStep = 2;
45     private double labelStep = 10;
46     
47     // ================================================================
48
// -- Constructors
49
// ================================================================
50
/**
51      * Creates a ValueAxisUnit based on a minor and major grid step.
52      * Minor grid lines appear at <code>gridStep</code>, major grid lines accompanied by a label
53      * will appear every <code>labelStep</code> value.
54      * @param gridStep Value step on which a minor grid line will appear.
55      * @param labelStep Value step on which a major grid line with value label will appear.
56      */

57     ValueAxisUnit( double gridStep, double labelStep )
58     {
59         this.gridStep = gridStep;
60         this.labelStep = labelStep;
61     }
62     
63     double getGridStep() {
64         return gridStep;
65     }
66
67     double getLabelStep() {
68         return labelStep;
69     }
70
71
72     // ================================================================
73
// -- Protected methods
74
// ================================================================
75
/**
76      * Returns a set of markers making up the grid for the Y axis.
77      * All markers are situated in a given value range.
78      * @param lower Lower value of the value range.
79      * @param upper Upper value of the value range.
80      * @return List of markers as a ValueMarker array.
81      */

82     ValueMarker[] getValueMarkers( double lower, double upper )
83     {
84         double minPoint = 0.0;
85         double majPoint = 0.0;
86
87         // Find the first visible gridpoint
88
if ( lower > 0 )
89         {
90             minPoint = lower;
91             double mod = ( lower % labelStep );
92
93             if ( mod > 0 )
94                 majPoint = lower + (labelStep - mod );
95             else
96                 majPoint = lower;
97         }
98         else if ( lower < 0 )
99         {
100             minPoint = lower;
101             double mod = ( lower % labelStep );
102
103             if ( Math.abs(mod) > 0 )
104                 majPoint = lower - mod;
105             else
106                 majPoint = lower;
107         }
108
109         // Now get all value markers.
110
// Again we choose to use a series of loops as to avoid unnecessary drawing.
111
ArrayList markerList = new ArrayList();
112
113         while ( minPoint <= upper && majPoint <= upper )
114         {
115             if ( minPoint < majPoint )
116             {
117                 markerList.add( new ValueMarker(minPoint, false) );
118                 minPoint = round( minPoint + gridStep );
119             }
120             else
121             {
122                 if ( minPoint == majPoint ) // Special case, but will happen most of the time
123
{
124                     markerList.add( new ValueMarker(majPoint, true) );
125                     minPoint = round( minPoint + gridStep );
126                     majPoint = round( majPoint + labelStep );
127                 }
128                 else
129                 {
130                     markerList.add( new ValueMarker(majPoint, true) );
131                     majPoint = round( majPoint + labelStep );
132                 }
133             }
134         }
135
136         while ( minPoint <= upper )
137         {
138             markerList.add( new ValueMarker(minPoint, false) );
139             minPoint = round( minPoint + gridStep );
140         }
141
142         while ( majPoint <= upper )
143         {
144             markerList.add( new ValueMarker(majPoint, true) );
145             majPoint = round( majPoint + labelStep );
146         }
147
148         return (ValueMarker[]) markerList.toArray( new ValueMarker[0] );
149     }
150
151     /**
152      * Gets a rounded value that's slightly below the given exact value.
153      * The rounding is based on the given grid specifications of the axis.
154      * @param ovalue Original exact value.
155      * @return Rounded value lower than the given exact value.
156      */

157     double getNiceLower( double ovalue )
158     {
159         // Add some checks
160
double gridFactor = 1.0;
161         double mGridFactor = 1.0;
162
163         double gridStep = this.gridStep;
164         double mGridStep = this.labelStep;
165
166         while ( gridStep < 10.0 ) {
167             gridStep *= 10;
168             gridFactor *= 10;
169         }
170
171         while ( mGridStep < 10.0 ) {
172             mGridStep *= 10;
173             mGridFactor *= 10;
174         }
175
176         int sign = ( ovalue > 0 ? 1 : -1 );
177
178         long lGridStep = new Double JavaDoc( gridStep ).longValue();
179         long lmGridStep = new Double JavaDoc( mGridStep ).longValue();
180
181         long lValue = new Double JavaDoc(sign * ovalue * gridFactor).longValue();
182         long lmValue = new Double JavaDoc(sign * ovalue * mGridFactor).longValue();
183
184         long lMod = lValue % lGridStep;
185         long lmMod = lmValue % lmGridStep;
186
187         if ( ovalue < 0 )
188         {
189             if ( lmMod > ( mGridStep * 0.5 ) )
190                 return ((double) (sign*lmValue + lmMod - lmGridStep ) / mGridFactor);
191             else if ( lMod > 0 )
192                 return ((double) (sign*lValue + lMod - lGridStep) / gridFactor);
193             else
194                 return ((double) (sign*lValue - lGridStep) / gridFactor);
195         }
196         else
197         {
198             if ( lmMod < ( mGridStep * 0.5 ) )
199                 return ((double) (sign*lmValue - lmMod) / mGridFactor);
200             else if ( lMod > 0 )
201                 return ((double) (sign*lValue - lMod) / gridFactor);
202             else
203                 return ((double) (sign*lValue) / gridFactor);
204         }
205     }
206     
207     /**
208      * Gets a rounded value that's slightly above the given exact value.
209      * The rounding is based on the given grid specifications of the axis.
210      * @param ovalue Original exact value.
211      * @return Rounded value higher than the given exact value.
212      */

213     double getNiceHigher( double ovalue )
214     {
215         double gridFactor = 1.0;
216         double mGridFactor = 1.0;
217
218         double gridStep = this.gridStep;
219         double mGridStep = this.labelStep;
220
221         while ( gridStep < 10.0 ) {
222             gridStep *= 10;
223             gridFactor *= 10;
224         }
225
226         while ( mGridStep < 10.0 ) {
227             mGridStep *= 10;
228             mGridFactor *= 10;
229         }
230
231         int sign = ( ovalue > 0 ? 1 : -1 );
232
233         long lGridStep = new Double JavaDoc( gridStep ).longValue();
234         long lmGridStep = new Double JavaDoc( mGridStep ).longValue();
235
236         long lValue = new Double JavaDoc(sign * ovalue * gridFactor).longValue();
237         long lmValue = new Double JavaDoc(sign * ovalue * mGridFactor).longValue();
238
239         long lMod = lValue % lGridStep;
240         long lmMod = lmValue % lmGridStep;
241
242         if ( ovalue < 0 )
243         {
244             if ( lmMod < ( mGridStep * 0.5 ) )
245                 return ((double) (sign*lmValue + lmMod ) / mGridFactor);
246             else
247                 return ((double) (sign*lValue + lMod ) / gridFactor);
248         }
249         else
250         {
251             if ( lmMod > ( mGridStep * 0.5 ) )
252                 return ((double) ( sign * lmValue - lmMod + lmGridStep) / mGridFactor);
253             else
254                 return ((double) ( sign * lValue - lMod + lGridStep) / gridFactor);
255         }
256
257     }
258
259
260     // ================================================================
261
// -- Private methods
262
// ================================================================
263
/**
264      * Rounds a specific double value to 14 decimals. This is used to avoid strange double values due to the
265      * internal double representation of the JVM.
266      * @param value Original value to round.
267      * @return Value rounded to 14 decimals.
268      */

269     private double round( double value )
270     {
271         return round( value, 14 ); // Big precision
272
}
273     
274     /**
275      * Rounds a specific double value to a given number of decimals.
276      * @param value Original value to round.
277      * @param numDecs Number of decimals to round the value to.
278      * @return Value rounded to given number of decimals.
279      */

280     private double round( double value, int numDecs )
281     {
282         return new java.math.BigDecimal JavaDoc(value).setScale(numDecs , java.math.BigDecimal.ROUND_HALF_EVEN).doubleValue();
283     }
284
285     void exportXmlTemplate(XmlWriter xml) {
286         xml.startTag("value_axis");
287         xml.writeTag("grid_step", getGridStep());
288         xml.writeTag("label_step", getLabelStep());
289         xml.closeTag(); // value_axis
290
}
291 }
292
Popular Tags