KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > progra > charting > CoordSystemUtilities


1 /*
2     JOpenChart Java Charting Library and Toolkit
3     Copyright (C) 2001 Sebastian Müller
4     http://jopenchart.sourceforge.net
5
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Lesser General Public
8     License as published by the Free Software Foundation; either
9     version 2.1 of the License, or (at your option) any later version.
10
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     Lesser General Public License for more details.
15
16     You should have received a copy of the GNU Lesser General Public
17     License along with this library; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20     CoordSystemUtilities.java
21     Created on 4. April 2002, 22:28
22  */

23
24 package de.progra.charting;
25
26 import java.awt.font.FontRenderContext JavaDoc;
27 import java.text.DecimalFormat JavaDoc;
28 import java.awt.geom.AffineTransform JavaDoc;
29 import java.awt.geom.Line2D JavaDoc;
30 import java.awt.geom.Point2D JavaDoc;
31 import java.awt.geom.Rectangle2D JavaDoc;
32 import java.awt.Color JavaDoc;
33 import java.awt.Font JavaDoc;
34 import java.awt.Graphics2D JavaDoc;
35 import java.awt.font.TextLayout JavaDoc;
36 import de.progra.charting.model.ChartDataModelConstraints;
37 import de.progra.charting.model.ChartDataModel;
38
39 /**
40  * This class provides some utility functions for a CoordSystem. They were
41  * externalized to make the CoordSystem class clearer.
42  * @author mueller
43  * @version 1.0
44  */

45 public class CoordSystemUtilities {
46
47         /** used for the offset on the y axis for the size of a "tick"*/
48     protected final int marginOffset = 6;
49     
50     protected CoordSystem c;
51     protected ChartDataModelConstraints constraints;
52     protected ChartDataModelConstraints constraints2;
53     protected ChartDataModel model;
54     
55     /** Creates a new instance of CoordSystemUtilities */
56     public CoordSystemUtilities(CoordSystem coord,
57                                 ChartDataModelConstraints constraints,
58                                 ChartDataModelConstraints constraints2,
59                                 ChartDataModel model) {
60         c = coord;
61         this.constraints = constraints;
62         this.constraints2 = constraints2;
63         this.model = model;
64     }
65     
66     /** Computes the left margin. */
67     public int computeLeftMargin() {
68         double xmin = constraints.getMinimumColumnValue();
69         double xmax = constraints.getMaximumColumnValue();
70         
71         if (xmin <= 0 && xmax > 0) {
72         xmin = Math.abs(xmin);
73         xmax = Math.abs(xmax);
74         
75         TextLayout JavaDoc layout = new TextLayout JavaDoc(c.getYAxisUnit(), c.getFont(),
76                            c.getFontRenderContext());
77         
78         // yaxis label width
79
int maxlmargin = computeYAxisLabelWidth() + marginOffset; // + yaxis title width
80

81         // unit width
82
maxlmargin = Math.max(maxlmargin, (int) layout.getBounds().getWidth() + marginOffset);
83         
84         
85         int margin = (int)(maxlmargin - (xmin / (xmin + xmax)) * (c.getBounds().getWidth() - c.getRightMargin()));
86         
87         margin += 5; // just for good looking
88

89         if(margin < c.MINIMALMARGIN)
90             margin = c.MINIMALMARGIN;
91         
92         return margin;
93     } else {
94         return c.MINIMALMARGIN;
95     }
96     }
97     
98     /** Computes the right margin. */
99     public int computeRightMargin() {
100     TextLayout JavaDoc layout = new TextLayout JavaDoc(c.getXAxisUnit(), c.getFont(),
101                         c.getFontRenderContext());
102     return Math.max((int)(layout.getBounds().getWidth() + (double)c.ARROWLENGTH / 3) , c.ARROWLENGTH);
103     }
104     
105     /** Computes the top margin. */
106     public int computeTopMargin() {
107     TextLayout JavaDoc layout = new TextLayout JavaDoc(c.getYAxisUnit(), c.getFont(),
108                        c.getFontRenderContext());
109     return Math.max((int)(layout.getBounds().getHeight() + (double)c.ARROWLENGTH / 3 + layout.getDescent()), c.ARROWLENGTH);
110     }
111     
112     /** Computes the bottom margin. */
113     public int computeBottomMargin() {
114     double ymin = constraints.getMinimumValue().doubleValue();
115         double ymax = constraints.getMaximumValue().doubleValue();
116     
117         if (ymin <= 0 && ymax > 0) {
118         ymin = Math.abs(ymin);
119         ymax = Math.abs(ymax);
120         
121         TextLayout JavaDoc layout = new TextLayout JavaDoc(c.getXAxisUnit(), c.getFont(),
122                             c.getFontRenderContext());
123         
124         // xaxis label height
125
int maxbmargin = computeXAxisLabelHeight() + marginOffset; // + xaxis title height
126

127         // unit height
128
maxbmargin = Math.max(maxbmargin, (int) layout.getBounds().getHeight() + marginOffset);
129         
130         
131         int margin = (int)(maxbmargin - (ymin / (ymin + ymax)) * (c.getBounds().getHeight() - c.getTopMargin()));
132         
133         margin += 10; // just for good looking
134

135         if(margin < c.MINIMALMARGIN)
136             margin = c.MINIMALMARGIN;
137         
138         return margin;
139     } else {
140         return c.MINIMALMARGIN;
141     }
142     }
143     
144     /** Computes the maximum height of all x-axis labels. */
145     public int computeXAxisLabelHeight() {
146         double min = constraints.getMinimumColumnValue();
147         double max = constraints.getMaximumColumnValue();
148         double tick = ChartUtilities.calculateTickSpacing(min, max);
149         double ypt = 0;
150         
151         int height = 0;
152         
153         if(constraints.getMinimumValue().doubleValue() > 0)
154             ypt = constraints.getMinimumValue().doubleValue();
155         else if(constraints.getMaximumValue().doubleValue() < 0)
156             ypt = constraints.getMaximumValue().doubleValue();
157         boolean paint = false;
158         
159         DecimalFormat JavaDoc df = c.getXDecimalFormat();
160         FontRenderContext JavaDoc frc = c.getFontRenderContext();
161         Font JavaDoc f = c.getFont();
162         
163         for(double d = min; d <= max; d += tick) {
164             if(paint) {
165                 String JavaDoc sb = df.format(d);
166                 Rectangle2D JavaDoc r = f.getStringBounds(sb, frc);
167                 
168                 height = Math.max(height, (int)r.getHeight());
169             }
170             paint = !paint;
171         }
172         
173         return height;
174     }
175     
176     /** Computes the maximum width of all y-axis labels. */
177     public int computeYAxisLabelWidth() {
178         double min = constraints.getMinimumValue().doubleValue();
179         double max = constraints.getMaximumValue().doubleValue();
180         double tick = ChartUtilities.calculateTickSpacing(min, max);
181         double xpt = 0;
182        
183         int width = 0;
184         
185         // shift the y-axis according to the max and min x-values
186
if(constraints.getMinimumColumnValue() > 0)
187             xpt = constraints.getMinimumColumnValue();
188         else if(constraints.getMaximumColumnValue() < 0 && c.getSecondYAxis() != null)
189             xpt = constraints.getMaximumColumnValue();
190         
191         boolean paint = false;
192         
193         DecimalFormat JavaDoc df = c.getYDecimalFormat();
194         FontRenderContext JavaDoc frc = c.getFontRenderContext();
195         Font JavaDoc f = c.getFont();
196         
197         for(double d = min; d <= max; d += tick) {
198             if(paint) {
199                 String JavaDoc sb = df.format(d);
200                 Rectangle2D JavaDoc r = f.getStringBounds(sb, frc);
201                 
202                 width = Math.max((int)r.getWidth(), width);
203             }
204             paint = !paint;
205         }
206         
207         return width;
208     }
209     
210     /** This method is called by paintDefault to paint the ticks on the
211      * x-axis for numerical x-axis values.
212      * @param g the Graphics2D context to paint in
213      */

214     public void drawNumericalXAxisTicks(Graphics2D JavaDoc g) {
215         AffineTransform JavaDoc at = c.getTransform(CoordSystem.FIRST_YAXIS);
216         
217         double min = constraints.getMinimumColumnValue();
218         double max = constraints.getMaximumColumnValue();
219         double tick = ChartUtilities.calculateTickSpacing(min, max);
220         double ypt = 0;
221         
222         if(constraints.getMinimumValue().doubleValue() > 0)
223             ypt = constraints.getMinimumValue().doubleValue();
224         else if(constraints.getMaximumValue().doubleValue() < 0)
225             ypt = constraints.getMaximumValue().doubleValue();
226         
227         Point2D JavaDoc p = new Point2D.Double JavaDoc(0.0, 0.0);
228         Point2D JavaDoc v;
229         Line2D JavaDoc ticks = new Line2D.Double JavaDoc(0.0, 0.0, 0.0, 0.0);
230         
231         DecimalFormat JavaDoc df = c.getXDecimalFormat();
232         FontRenderContext JavaDoc frc = c.getFontRenderContext();
233         Font JavaDoc f = c.getFont();
234         
235         boolean paint = false;
236         
237         g.setFont(f);
238         boolean paintLabels = c.isPaintLabels();
239         
240         for(double d = min; d <= max; d += tick) {
241             p.setLocation(d, ypt);
242             v = at.transform(p, null);
243             
244             ticks.setLine(v.getX(), v.getY() - marginOffset/2, v.getX(), v.getY() + marginOffset/2);
245             g.draw(ticks);
246             if(paint && paintLabels) {
247                 String JavaDoc sb = df.format(d);
248                 Rectangle2D JavaDoc r = f.getStringBounds(sb, frc);
249                 
250                 g.drawString(sb, (float)(v.getX() - r.getWidth() / 2),
251                             (float)(v.getY() + r.getHeight() + marginOffset));
252             }
253             paint = !paint;
254         }
255     }
256     
257     /** This method is called by paintDefault to paint the ticks on the
258      * x-axis for non-numerical x-axis values..
259      * @param g the Graphics2D context to paint in
260      */

261     public void drawXAxisTicks(Graphics2D JavaDoc g) {
262         AffineTransform JavaDoc at = c.getTransform(CoordSystem.FIRST_YAXIS);
263         
264         int min = (int)constraints.getMinimumColumnValue();
265         int max = (int)constraints.getMaximumColumnValue();
266         double tick = 1.0;
267         double ypt = 0;
268         
269         if(constraints.getMinimumValue().doubleValue() > 0)
270             ypt = constraints.getMinimumValue().doubleValue();
271         else if(constraints.getMaximumValue().doubleValue() < 0)
272             ypt = constraints.getMaximumValue().doubleValue();
273         
274         Point2D JavaDoc p = new Point2D.Double JavaDoc(0.0, 0.0);
275         Point2D JavaDoc v = null;
276         Point2D JavaDoc oldv = null;
277         
278         Line2D JavaDoc ticks = new Line2D.Double JavaDoc(0.0, 0.0, 0.0, 0.0);
279         
280         DecimalFormat JavaDoc df = c.getXDecimalFormat();
281         FontRenderContext JavaDoc frc = c.getFontRenderContext();
282         Font JavaDoc f = c.getFont();
283         
284         boolean paint = false;
285         boolean paintLabels = c.isPaintLabels();
286         g.setFont(f);
287         
288         for(int i = min - 1; i < max; i++) {
289             p.setLocation(i + 1, ypt);
290             
291             v = at.transform(p, null);
292             
293             ticks.setLine(v.getX(), v.getY() - marginOffset/2, v.getX(), v.getY() + marginOffset/2);
294             
295             if(i + 1 < max)
296                 g.draw(ticks);
297             
298             // Draw Strings between ticks
299
if(oldv != null && paintLabels) {
300                 String JavaDoc sb = (String JavaDoc)model.getColumnValueAt(i);
301                 Rectangle2D JavaDoc r = f.getStringBounds(sb, frc);
302                 
303                 g.drawString(sb, (float)(oldv.getX()+(v.getX() - oldv.getX()) / 2 - r.getWidth() / 2),
304                                 (float)(v.getY() + r.getHeight() + marginOffset));
305             }
306             
307             oldv = v;
308         }
309     }
310     
311     /** This method is called by paintDefault to paint the ticks on the
312      * y-axis.
313      * @param g the Graphics2D context in which to draw
314      */

315     public void drawYAxisTicks(Graphics2D JavaDoc g) {
316         AffineTransform JavaDoc at = c.getTransform(CoordSystem.FIRST_YAXIS);
317         
318         double min = constraints.getMinimumValue().doubleValue();
319         double max = constraints.getMaximumValue().doubleValue();
320         double tick = ChartUtilities.calculateTickSpacing(min, max);
321         double xpt = 0;
322        
323         // shift the y-axis according to the max and min x-values
324
if(constraints.getMinimumColumnValue() > 0)
325             xpt = constraints.getMinimumColumnValue();
326         else if(constraints.getMaximumColumnValue() < 0 && c.getSecondYAxis() != null)
327             xpt = constraints.getMaximumColumnValue();
328         
329         Point2D JavaDoc p = new Point2D.Double JavaDoc(0.0, 0.0);
330         Point2D JavaDoc v;
331         Line2D JavaDoc ticks = new Line2D.Double JavaDoc(0.0, 0.0, 0.0, 0.0);
332         boolean paint = false;
333         
334         DecimalFormat JavaDoc df = c.getYDecimalFormat();
335         FontRenderContext JavaDoc frc = c.getFontRenderContext();
336         Font JavaDoc f = c.getFont();
337         
338         Color JavaDoc backupColor = g.getColor();
339         g.setFont(f);
340         boolean paintLabels = c.isPaintLabels();
341         
342         for(double d = min; d <= max; d += tick) {
343             p.setLocation(xpt, d);
344             v = at.transform(p, null);
345             
346             ticks.setLine(v.getX() - marginOffset/2, v.getY(), v.getX() + marginOffset/2, v.getY());
347             
348             g.draw(ticks);
349             
350             if (d != min && !c.isPaintOnlyTick()) {
351                 Line2D JavaDoc xax = getXAxisLine2D();
352                 ticks.setLine(v.getX() + marginOffset/2, v.getY(), xax.getX2(), v.getY());
353                 g.setColor(Color.lightGray);
354                 g.draw(ticks);
355                 g.setColor(backupColor);
356             }
357             
358             if(paintLabels && (paint || !c.isPaintAltTick())) {
359                 String JavaDoc sb = df.format(d);
360                 Rectangle2D JavaDoc r = f.getStringBounds(sb, frc);
361                 
362                 g.drawString(sb, (float)(v.getX() - r.getWidth() - marginOffset),
363                             (float)(v.getY() + r.getHeight() / 2));
364             }
365             paint = !paint;
366         }
367     }
368     
369     /** Computes the Line2D object of the x-axis using the DataConstraints.*/
370     public Line2D JavaDoc getXAxisLine2D() {
371         double ypt = 0.0;
372         // shift the x-axis according to the max and min y-values
373
if(constraints.getMinimumValue().doubleValue() > 0)
374             ypt = constraints.getMinimumValue().doubleValue();
375         else if(constraints.getMaximumValue().doubleValue() < 0)
376             ypt = constraints.getMaximumValue().doubleValue();
377         
378         AffineTransform JavaDoc at = c.getTransform(CoordSystem.FIRST_YAXIS);
379         
380         Point2D JavaDoc l = at.transform(new Point2D.Double JavaDoc(constraints.getMinimumColumnValue(), ypt), null);
381         Point2D JavaDoc r = at.transform(new Point2D.Double JavaDoc(constraints.getMaximumColumnValue(), ypt), null);
382         
383         return new Line2D.Double JavaDoc(l, r);
384     }
385     
386     /** Computes the Line2D object of the y-axis using the DataConstraints.*/
387     public Line2D JavaDoc getYAxisLine2D() {
388         double xpt = 0.0;
389         
390         // shift the y-axis according to the max and min x-values
391
if(constraints.getMinimumColumnValue() > 0)
392             xpt = constraints.getMinimumColumnValue();
393         else if(constraints.getMaximumColumnValue() < 0 && c.getSecondYAxis() != null)
394             xpt = constraints.getMaximumColumnValue();
395         
396         AffineTransform JavaDoc at = c.getTransform(CoordSystem.FIRST_YAXIS);
397         
398         Point2D JavaDoc o = at.transform(new Point2D.Double JavaDoc(xpt, constraints.getMaximumValue().doubleValue()), null);
399         Point2D JavaDoc u = at.transform(new Point2D.Double JavaDoc(xpt, constraints.getMinimumValue().doubleValue()), null);
400         //System.out.println("** Y-Axis ("+o+", "+u+")");
401
return new Line2D.Double JavaDoc(o, u);
402     }
403     
404     /** Computes the Line2D object of the second y-axis using the DataConstraints.*/
405     public Line2D JavaDoc getSecondYAxisLine2D() {
406         double xpt = constraints2.getMaximumColumnValue();
407         
408         AffineTransform JavaDoc at = c.getTransform(CoordSystem.SECOND_YAXIS);
409         
410         Point2D JavaDoc o = at.transform(new Point2D.Double JavaDoc(xpt, constraints2.getMaximumValue().doubleValue()), null);
411         Point2D JavaDoc u = at.transform(new Point2D.Double JavaDoc(xpt, constraints2.getMinimumValue().doubleValue()), null);
412         
413         return new Line2D.Double JavaDoc(o, u);
414     }
415
416 }
417
Popular Tags