KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > axis > SymbolicAxis


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this library; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
24  * in the United States and other countries.]
25  *
26  * -----------------
27  * SymbolicAxis.java
28  * -----------------
29  * (C) Copyright 2002-2005, by Object Refinery Limited and Contributors.
30  *
31  * Original Author: Anthony Boulestreau;
32  * Contributor(s): David Gilbert (for Object Refinery Limited);
33  *
34  *
35  * Changes (from 23-Jun-2001)
36  * --------------------------
37  * 29-Mar-2002 : First version (AB);
38  * 19-Apr-2002 : Updated formatting and import statements (DG);
39  * 21-Jun-2002 : Make change to use the class TickUnit - remove valueToString()
40  * method and add SymbolicTickUnit (AB);
41  * 25-Jun-2002 : Removed redundant code (DG);
42  * 25-Jul-2002 : Changed order of parameters in ValueAxis constructor (DG);
43  * 05-Sep-2002 : Updated constructor to reflect changes in the Axis class (DG);
44  * 08-Nov-2002 : Moved to new package com.jrefinery.chart.axis (DG);
45  * 14-Feb-2003 : Added back missing constructor code (DG);
46  * 26-Mar-2003 : Implemented Serializable (DG);
47  * 14-May-2003 : Renamed HorizontalSymbolicAxis --> SymbolicAxis and merged in
48  * VerticalSymbolicAxis (DG);
49  * 12-Aug-2003 : Fixed bug where refreshTicks() method has different signature
50  * to super class (DG);
51  * 29-Oct-2003 : Added workaround for font alignment in PDF output (DG);
52  * 02-Nov-2003 : Added code to avoid overlapping labels (MR);
53  * 07-Nov-2003 : Modified to use new tick classes (DG);
54  * 18-Nov-2003 : Fixed bug where symbols are not being displayed on the
55  * axis (DG);
56  * 24-Nov-2003 : Added fix for gridlines on zooming (bug id 834643) (DG);
57  * 21-Jan-2004 : Update for renamed method in ValueAxis (DG);
58  * 11-Mar-2004 : Modified the way the background grid color is being drawn, see
59  * this thread:
60  * http://www.jfree.org/phpBB2/viewtopic.php?p=22973 (DG);
61  * 16-Mar-2004 : Added plotState to draw() method (DG);
62  * 07-Apr-2004 : Modified string bounds calculation (DG);
63  * 28-Mar-2005 : Renamed autoRangeIncludesZero() --> getAutoRangeIncludesZero()
64  * and autoRangeStickyZero() --> getAutoRangeStickyZero() (DG);
65  *
66  */

67
68 package org.jfree.chart.axis;
69
70 import java.awt.BasicStroke JavaDoc;
71 import java.awt.Color JavaDoc;
72 import java.awt.Font JavaDoc;
73 import java.awt.Graphics2D JavaDoc;
74 import java.awt.Paint JavaDoc;
75 import java.awt.Shape JavaDoc;
76 import java.awt.geom.Rectangle2D JavaDoc;
77 import java.io.Serializable JavaDoc;
78 import java.text.NumberFormat JavaDoc;
79 import java.util.Arrays JavaDoc;
80 import java.util.Iterator JavaDoc;
81 import java.util.List JavaDoc;
82 import java.util.Vector JavaDoc;
83
84 import org.jfree.chart.event.AxisChangeEvent;
85 import org.jfree.chart.plot.Plot;
86 import org.jfree.chart.plot.PlotRenderingInfo;
87 import org.jfree.chart.plot.ValueAxisPlot;
88 import org.jfree.data.Range;
89 import org.jfree.text.TextUtilities;
90 import org.jfree.ui.RectangleEdge;
91 import org.jfree.ui.TextAnchor;
92
93 /**
94  * A standard linear value axis, for SYMBOLIC values.
95  *
96  * @author Anthony Boulestreau
97  */

98 public class SymbolicAxis extends NumberAxis implements Serializable JavaDoc {
99
100     /** For serialization. */
101     private static final long serialVersionUID = 7216330468770619716L;
102     
103     /** The default symbolic grid line paint. */
104     public static final Paint JavaDoc DEFAULT_SYMBOLIC_GRID_LINE_PAINT
105         = new Color JavaDoc(232, 234, 232, 128);
106
107     /** The list of symbolic value to display instead of the numeric values. */
108     private List JavaDoc symbolicValue;
109
110     /** List of the symbolic grid lines shapes. */
111     private List JavaDoc symbolicGridLineList = null;
112
113     /** Color of the dark part of the symbolic grid line. **/
114     private transient Paint JavaDoc symbolicGridPaint;
115
116     /** Flag that indicates whether or not symbolic grid lines are visible. */
117     private boolean symbolicGridLinesVisible;
118
119     /**
120      * Constructs a symbolic axis, using default attribute values where
121      * necessary.
122      *
123      * @param label the axis label (null permitted).
124      * @param sv the list of symbolic values to display instead of the numeric
125      * value.
126      */

127     public SymbolicAxis(String JavaDoc label, String JavaDoc[] sv) {
128
129         super(label);
130
131         //initialization of symbolic value
132
this.symbolicValue = Arrays.asList(sv);
133         this.symbolicGridLinesVisible = true;
134         this.symbolicGridPaint = DEFAULT_SYMBOLIC_GRID_LINE_PAINT;
135
136         setAutoTickUnitSelection(false, false);
137         setAutoRangeStickyZero(false);
138
139     }
140
141     /**
142      * Returns the list of the symbolic values to display.
143      *
144      * @return list of symbolic values.
145      */

146     public String JavaDoc[] getSymbolicValue() {
147
148         String JavaDoc[] strToReturn = new String JavaDoc[this.symbolicValue.size()];
149         strToReturn = (String JavaDoc[]) this.symbolicValue.toArray(strToReturn);
150         return strToReturn;
151     }
152
153     /**
154      * Returns the symbolic grid line color.
155      *
156      * @return The grid line color.
157      */

158     public Paint JavaDoc getSymbolicGridPaint() {
159         return this.symbolicGridPaint;
160     }
161
162     /**
163      * Returns <code>true</code> if the symbolic grid lines are showing, and
164      * <code>false</code> otherwise.
165      *
166      * @return <code>true</code> if the symbolic grid lines are showing, and
167      * <code>false</code> otherwise.
168      */

169     public boolean isGridLinesVisible() {
170         return this.symbolicGridLinesVisible;
171     }
172
173     /**
174      * Sets the visibility of the symbolic grid lines and notifies registered
175      * listeners that the axis has been modified.
176      *
177      * @param flag the new setting.
178      */

179     public void setSymbolicGridLinesVisible(boolean flag) {
180
181         if (this.symbolicGridLinesVisible != flag) {
182             this.symbolicGridLinesVisible = flag;
183             notifyListeners(new AxisChangeEvent(this));
184         }
185     }
186
187     /**
188      * This operation is not supported by the symbolic values.
189      *
190      * @param g2 the graphics device.
191      * @param drawArea the area in which the plot and axes should be drawn.
192      * @param plotArea the area in which the plot should be drawn.
193      */

194     protected void selectAutoTickUnit(Graphics2D JavaDoc g2, Rectangle2D JavaDoc drawArea,
195                                       Rectangle2D JavaDoc plotArea) {
196         throw new UnsupportedOperationException JavaDoc();
197     }
198
199     /**
200      * Draws the axis on a Java 2D graphics device (such as the screen or a
201      * printer).
202      *
203      * @param g2 the graphics device (<code>null</code> not permitted).
204      * @param cursor the cursor location.
205      * @param plotArea the area within which the plot and axes should be drawn
206      * (<code>null</code> not permitted).
207      * @param dataArea the area within which the data should be drawn
208      * (<code>null</code> not permitted).
209      * @param edge the axis location (<code>null</code> not permitted).
210      * @param plotState collects information about the plot
211      * (<code>null</code> permitted).
212      *
213      * @return The axis state (never <code>null</code>).
214      */

215     public AxisState draw(Graphics2D JavaDoc g2,
216                           double cursor,
217                           Rectangle2D JavaDoc plotArea,
218                           Rectangle2D JavaDoc dataArea,
219                           RectangleEdge edge,
220                           PlotRenderingInfo plotState) {
221
222         AxisState info = new AxisState(cursor);
223         if (isVisible()) {
224             info = super.draw(g2, cursor, plotArea, dataArea, edge, plotState);
225         }
226         if (this.symbolicGridLinesVisible) {
227             drawSymbolicGridLines(
228                 g2, plotArea, dataArea, edge, info.getTicks()
229             );
230         }
231         return info;
232
233     }
234
235     /**
236      * Draws the symbolic grid lines.
237      * <P>
238      * The colors are consecutively the color specified by
239      * <CODE>symbolicGridPaint<CODE>
240      * (<CODE>DEFAULT_SYMBOLIC_GRID_LINE_PAINT</CODE> by default) and white.
241      *
242      * @param g2 the graphics device.
243      * @param plotArea the area within which the chart should be drawn.
244      * @param dataArea the area within which the plot should be drawn (a
245      * subset of the drawArea).
246      * @param edge the axis location.
247      * @param ticks the ticks.
248      */

249     public void drawSymbolicGridLines(Graphics2D JavaDoc g2,
250                                       Rectangle2D JavaDoc plotArea,
251                                       Rectangle2D JavaDoc dataArea,
252                                       RectangleEdge edge,
253                                       List JavaDoc ticks) {
254
255         Shape JavaDoc savedClip = g2.getClip();
256         g2.clip(dataArea);
257         if (RectangleEdge.isTopOrBottom(edge)) {
258             drawSymbolicGridLinesHorizontal(
259                 g2, plotArea, dataArea, true, ticks
260             );
261         }
262         else if (RectangleEdge.isLeftOrRight(edge)) {
263             drawSymbolicGridLinesVertical(g2, plotArea, dataArea, true, ticks);
264         }
265         g2.setClip(savedClip);
266
267     }
268
269     /**
270      * Draws the symbolic grid lines.
271      * <P>
272      * The colors are consecutively the color specified by
273      * <CODE>symbolicGridPaint<CODE>
274      * (<CODE>DEFAULT_SYMBOLIC_GRID_LINE_PAINT</CODE> by default) and white.
275      * or if <CODE>firstGridLineIsDark</CODE> is <CODE>true</CODE> white and
276      * the color specified by <CODE>symbolicGridPaint<CODE>.
277      *
278      * @param g2 the graphics device.
279      * @param plotArea the area within which the chart should be drawn.
280      * @param dataArea the area within which the plot should be drawn
281      * (a subset of the drawArea).
282      * @param firstGridLineIsDark True: the first symbolic grid line take the
283      * color of <CODE>symbolicGridPaint<CODE>.
284      * False: the first symbolic grid line is white.
285      * @param ticks the ticks.
286      */

287     public void drawSymbolicGridLinesHorizontal(Graphics2D JavaDoc g2,
288                                                 Rectangle2D JavaDoc plotArea,
289                                                 Rectangle2D JavaDoc dataArea,
290                                                 boolean firstGridLineIsDark,
291                                                 List JavaDoc ticks) {
292
293         this.symbolicGridLineList = new Vector JavaDoc(ticks.size());
294         boolean currentGridLineIsDark = firstGridLineIsDark;
295         double yy = dataArea.getY();
296         double xx1, xx2;
297
298         //gets the outline stroke width of the plot
299
double outlineStrokeWidth;
300         if (getPlot().getOutlineStroke() != null) {
301             outlineStrokeWidth
302                 = ((BasicStroke JavaDoc) getPlot().getOutlineStroke()).getLineWidth();
303         }
304         else {
305             outlineStrokeWidth = 1d;
306         }
307
308         Iterator JavaDoc iterator = ticks.iterator();
309         ValueTick tick;
310         Rectangle2D JavaDoc symbolicGridLine;
311         while (iterator.hasNext()) {
312             tick = (ValueTick) iterator.next();
313             xx1 = valueToJava2D(
314                 tick.getValue() - 0.5d, dataArea, RectangleEdge.BOTTOM
315             );
316             xx2 = valueToJava2D(
317                 tick.getValue() + 0.5d, dataArea, RectangleEdge.BOTTOM
318             );
319             if (currentGridLineIsDark) {
320                 g2.setPaint(this.symbolicGridPaint);
321                 //g2.setXORMode((Color) this.symbolicGridPaint);
322
}
323             else {
324                 g2.setPaint(Color.white);
325                 //g2.setXORMode(Color.white);
326
}
327             symbolicGridLine = new Rectangle2D.Double JavaDoc(
328                 xx1, yy + outlineStrokeWidth,
329                 xx2 - xx1, dataArea.getMaxY() - yy - outlineStrokeWidth
330             );
331             g2.fill(symbolicGridLine);
332             this.symbolicGridLineList.add(symbolicGridLine);
333             currentGridLineIsDark = !currentGridLineIsDark;
334         }
335         g2.setPaintMode();
336     }
337
338     /**
339      * Get the symbolic grid line corresponding to the specified position.
340      *
341      * @param position position of the grid line, startinf from 0.
342      *
343      * @return The symbolic grid line corresponding to the specified position.
344      */

345     public Rectangle2D.Double JavaDoc getSymbolicGridLine(int position) {
346
347         if (this.symbolicGridLineList != null) {
348             return (Rectangle2D.Double JavaDoc) this.symbolicGridLineList.get(position);
349         }
350         else {
351             return null;
352         }
353
354     }
355
356     /**
357      * Rescales the axis to ensure that all data is visible.
358      */

359     protected void autoAdjustRange() {
360
361         Plot plot = getPlot();
362         if (plot == null) {
363             return; // no plot, no data
364
}
365
366         if (plot instanceof ValueAxisPlot) {
367
368             //ensure that all the symbolic value are displayed
369
double upper = this.symbolicValue.size() - 1;
370             double lower = 0;
371             double range = upper - lower;
372
373             // ensure the autorange is at least <minRange> in size...
374
double minRange = getAutoRangeMinimumSize();
375             if (range < minRange) {
376                 upper = (upper + lower + minRange) / 2;
377                 lower = (upper + lower - minRange) / 2;
378             }
379
380             //this ensure that the symbolic grid lines will be displayed
381
//correctly.
382
double upperMargin = 0.5;
383             double lowerMargin = 0.5;
384
385             if (getAutoRangeIncludesZero()) {
386                 if (getAutoRangeStickyZero()) {
387                     if (upper <= 0.0) {
388                         upper = 0.0;
389                     }
390                     else {
391                         upper = upper + upperMargin;
392                     }
393                     if (lower >= 0.0) {
394                         lower = 0.0;
395                     }
396                     else {
397                         lower = lower - lowerMargin;
398                     }
399                 }
400                 else {
401                     upper = Math.max(0.0, upper + upperMargin);
402                     lower = Math.min(0.0, lower - lowerMargin);
403                 }
404             }
405             else {
406                 if (getAutoRangeStickyZero()) {
407                     if (upper <= 0.0) {
408                         upper = Math.min(0.0, upper + upperMargin);
409                     }
410                     else {
411                         upper = upper + upperMargin * range;
412                     }
413                     if (lower >= 0.0) {
414                         lower = Math.max(0.0, lower - lowerMargin);
415                     }
416                     else {
417                         lower = lower - lowerMargin;
418                     }
419                 }
420                 else {
421                     upper = upper + upperMargin;
422                     lower = lower - lowerMargin;
423                 }
424             }
425
426             setRange(new Range(lower, upper), false, false);
427
428         }
429
430     }
431
432     /**
433      * Calculates the positions of the tick labels for the axis, storing the
434      * results in the tick label list (ready for drawing).
435      *
436      * @param g2 the graphics device.
437      * @param state the axis state.
438      * @param plotArea the area in which the plot (inlcuding axes) should be
439      * drawn.
440      * @param dataArea the area in which the data should be drawn.
441      * @param edge the location of the axis.
442      *
443      * @return A list of ticks.
444      */

445     public List JavaDoc refreshTicks(Graphics2D JavaDoc g2,
446                              AxisState state,
447                              Rectangle2D JavaDoc plotArea,
448                              Rectangle2D JavaDoc dataArea,
449                              RectangleEdge edge) {
450
451         List JavaDoc ticks = null;
452         if (RectangleEdge.isTopOrBottom(edge)) {
453             ticks = refreshTicksHorizontal(
454                 g2, state.getCursor(), plotArea, dataArea, edge
455             );
456         }
457         else if (RectangleEdge.isLeftOrRight(edge)) {
458             ticks = refreshTicksVertical(
459                 g2, state.getCursor(), plotArea, dataArea, edge
460             );
461         }
462         return ticks;
463
464     }
465
466     /**
467      * Calculates the positions of the tick labels for the axis, storing the
468      * results in the tick label list (ready for drawing).
469      *
470      * @param g2 the graphics device.
471      * @param cursor the cursor position for drawing the axis.
472      * @param plotArea the area in which the plot (inlcuding axes) should be
473      * drawn.
474      * @param dataArea the area in which the data should be drawn.
475      * @param edge the location of the axis.
476      *
477      * @return The ticks.
478      */

479     public List JavaDoc refreshTicksHorizontal(Graphics2D JavaDoc g2, double cursor,
480                                        Rectangle2D JavaDoc plotArea,
481                                        Rectangle2D JavaDoc dataArea,
482                                        RectangleEdge edge) {
483
484         List JavaDoc ticks = new java.util.ArrayList JavaDoc();
485
486         Font JavaDoc tickLabelFont = getTickLabelFont();
487         g2.setFont(tickLabelFont);
488
489         double size = getTickUnit().getSize();
490         int count = calculateVisibleTickCount();
491         double lowestTickValue = calculateLowestVisibleTickValue();
492
493         double previousDrawnTickLabelPos = 0.0;
494         double previousDrawnTickLabelLength = 0.0;
495
496         if (count <= ValueAxis.MAXIMUM_TICK_COUNT) {
497             for (int i = 0; i < count; i++) {
498                 double currentTickValue = lowestTickValue + (i * size);
499                 double xx = valueToJava2D(currentTickValue, dataArea, edge);
500                 String JavaDoc tickLabel;
501                 NumberFormat JavaDoc formatter = getNumberFormatOverride();
502                 if (formatter != null) {
503                     tickLabel = formatter.format(currentTickValue);
504                 }
505                 else {
506                     tickLabel = valueToString(currentTickValue);
507                 }
508                 
509                 // avoid to draw overlapping tick labels
510
Rectangle2D JavaDoc bounds = TextUtilities.getTextBounds(
511                     tickLabel, g2, g2.getFontMetrics()
512                 );
513                 double tickLabelLength = isVerticalTickLabels()
514                     ? bounds.getHeight() : bounds.getWidth();
515                 boolean tickLabelsOverlapping = false;
516                 if (i > 0) {
517                     double avgTickLabelLength = (previousDrawnTickLabelLength
518                         + tickLabelLength) / 2.0;
519                     if (Math.abs(xx - previousDrawnTickLabelPos)
520                             < avgTickLabelLength) {
521                         tickLabelsOverlapping = true;
522                     }
523                 }
524                 if (tickLabelsOverlapping) {
525                     tickLabel = ""; // don't draw this tick label
526
}
527                 else {
528                     // remember these values for next comparison
529
previousDrawnTickLabelPos = xx;
530                     previousDrawnTickLabelLength = tickLabelLength;
531                 }
532                 
533                 TextAnchor anchor = null;
534                 TextAnchor rotationAnchor = null;
535                 double angle = 0.0;
536                 if (isVerticalTickLabels()) {
537                     anchor = TextAnchor.CENTER_RIGHT;
538                     rotationAnchor = TextAnchor.CENTER_RIGHT;
539                     if (edge == RectangleEdge.TOP) {
540                         angle = Math.PI / 2.0;
541                     }
542                     else {
543                         angle = -Math.PI / 2.0;
544                     }
545                 }
546                 else {
547                     if (edge == RectangleEdge.TOP) {
548                         anchor = TextAnchor.BOTTOM_CENTER;
549                         rotationAnchor = TextAnchor.BOTTOM_CENTER;
550                     }
551                     else {
552                         anchor = TextAnchor.TOP_CENTER;
553                         rotationAnchor = TextAnchor.TOP_CENTER;
554                     }
555                 }
556                 Tick tick = new NumberTick(
557                     new Double JavaDoc(currentTickValue), tickLabel, anchor,
558                     rotationAnchor, angle
559                 );
560                 ticks.add(tick);
561             }
562         }
563         return ticks;
564
565     }
566
567     /**
568      * Calculates the positions of the tick labels for the axis, storing the
569      * results in the tick label list (ready for drawing).
570      *
571      * @param g2 the graphics device.
572      * @param cursor the cursor position for drawing the axis.
573      * @param plotArea the area in which the plot and the axes should be drawn.
574      * @param dataArea the area in which the plot should be drawn.
575      * @param edge the location of the axis.
576      *
577      * @return The ticks.
578      */

579     public List JavaDoc refreshTicksVertical(Graphics2D JavaDoc g2, double cursor,
580                                      Rectangle2D JavaDoc plotArea, Rectangle2D JavaDoc dataArea,
581                                      RectangleEdge edge) {
582
583         List JavaDoc ticks = new java.util.ArrayList JavaDoc();
584
585         Font JavaDoc tickLabelFont = getTickLabelFont();
586         g2.setFont(tickLabelFont);
587
588         double size = getTickUnit().getSize();
589         int count = calculateVisibleTickCount();
590         double lowestTickValue = calculateLowestVisibleTickValue();
591
592         double previousDrawnTickLabelPos = 0.0;
593         double previousDrawnTickLabelLength = 0.0;
594
595         if (count <= ValueAxis.MAXIMUM_TICK_COUNT) {
596             for (int i = 0; i < count; i++) {
597                 double currentTickValue = lowestTickValue + (i * size);
598                 double yy = valueToJava2D(currentTickValue, dataArea, edge);
599                 String JavaDoc tickLabel;
600                 NumberFormat JavaDoc formatter = getNumberFormatOverride();
601                 if (formatter != null) {
602                     tickLabel = formatter.format(currentTickValue);
603                 }
604                 else {
605                     tickLabel = valueToString(currentTickValue);
606                 }
607
608                 // avoid to draw overlapping tick labels
609
Rectangle2D JavaDoc bounds = TextUtilities.getTextBounds(
610                     tickLabel, g2, g2.getFontMetrics()
611                 );
612                 double tickLabelLength = isVerticalTickLabels()
613                     ? bounds.getWidth() : bounds.getHeight();
614                 boolean tickLabelsOverlapping = false;
615                 if (i > 0) {
616                     double avgTickLabelLength =
617                         (previousDrawnTickLabelLength + tickLabelLength) / 2.0;
618                     if (Math.abs(yy - previousDrawnTickLabelPos)
619                             < avgTickLabelLength) {
620                         tickLabelsOverlapping = true;
621                     }
622                     if (tickLabelsOverlapping) {
623                         tickLabel = ""; // don't draw this tick label
624
}
625                     else {
626                         // remember these values for next comparison
627
previousDrawnTickLabelPos = yy;
628                         previousDrawnTickLabelLength = tickLabelLength;
629                     }
630                 }
631                 TextAnchor anchor = null;
632                 TextAnchor rotationAnchor = null;
633                 double angle = 0.0;
634                 if (isVerticalTickLabels()) {
635                     anchor = TextAnchor.BOTTOM_CENTER;
636                     rotationAnchor = TextAnchor.BOTTOM_CENTER;
637                     if (edge == RectangleEdge.LEFT) {
638                         angle = -Math.PI / 2.0;
639                     }
640                     else {
641                         angle = Math.PI / 2.0;
642                     }
643                 }
644                 else {
645                     if (edge == RectangleEdge.LEFT) {
646                         anchor = TextAnchor.CENTER_RIGHT;
647                         rotationAnchor = TextAnchor.CENTER_RIGHT;
648                     }
649                     else {
650                         anchor = TextAnchor.CENTER_LEFT;
651                         rotationAnchor = TextAnchor.CENTER_LEFT;
652                     }
653                 }
654                 Tick tick = new NumberTick(
655                     new Double JavaDoc(currentTickValue), tickLabel, anchor,
656                     rotationAnchor, angle
657                 );
658                 ticks.add(tick);
659             }
660         }
661         return ticks;
662         
663     }
664
665     /**
666      * Converts a value to a string, using the list of symbolic values.
667      *
668      * @param value value to convert.
669      *
670      * @return The symbolic value.
671      */

672     public String JavaDoc valueToString(double value) {
673
674         String JavaDoc strToReturn;
675         try {
676             strToReturn = (String JavaDoc) this.symbolicValue.get((int) value);
677         }
678         catch (IndexOutOfBoundsException JavaDoc ex) {
679             strToReturn = "";
680         }
681         return strToReturn;
682     }
683
684     /**
685      * Draws the symbolic grid lines.
686      * <P>
687      * The colors are consecutively the color specified by
688      * <CODE>symbolicGridPaint<CODE>
689      * (<CODE>DEFAULT_SYMBOLIC_GRID_LINE_PAINT</CODE> by default) and white.
690      * or if <CODE>firstGridLineIsDark</CODE> is <CODE>true</CODE> white and
691      * the color specified by <CODE>symbolicGridPaint<CODE>.
692      *
693      * @param g2 the graphics device.
694      * @param drawArea the area within which the chart should be drawn.
695      * @param plotArea the area within which the plot should be drawn (a
696      * subset of the drawArea).
697      * @param firstGridLineIsDark True: the first symbolic grid line take the
698      * color of <CODE>symbolicGridPaint<CODE>.
699      * False: the first symbolic grid line is white.
700      * @param ticks a list of ticks.
701      */

702     public void drawSymbolicGridLinesVertical(Graphics2D JavaDoc g2,
703                                               Rectangle2D JavaDoc drawArea,
704                                               Rectangle2D JavaDoc plotArea,
705                                               boolean firstGridLineIsDark,
706                                               List JavaDoc ticks) {
707
708         this.symbolicGridLineList = new Vector JavaDoc(ticks.size());
709         boolean currentGridLineIsDark = firstGridLineIsDark;
710         double xx = plotArea.getX();
711         double yy1, yy2;
712
713         //gets the outline stroke width of the plot
714
double outlineStrokeWidth;
715         if (getPlot().getOutlineStroke() != null) {
716             outlineStrokeWidth
717                 = ((BasicStroke JavaDoc) getPlot().getOutlineStroke()).getLineWidth();
718         }
719         else {
720             outlineStrokeWidth = 1d;
721         }
722
723         Iterator JavaDoc iterator = ticks.iterator();
724         ValueTick tick;
725         Rectangle2D JavaDoc symbolicGridLine;
726         while (iterator.hasNext()) {
727             tick = (ValueTick) iterator.next();
728             yy1 = valueToJava2D(
729                 tick.getValue() + 0.5d, plotArea, RectangleEdge.LEFT
730             );
731             yy2 = valueToJava2D(
732                 tick.getValue() - 0.5d, plotArea, RectangleEdge.LEFT
733             );
734             if (currentGridLineIsDark) {
735                 g2.setPaint(this.symbolicGridPaint);
736                 //g2.setXORMode((Color) getSymbolicGridPaint());
737
}
738             else {
739                 g2.setPaint(Color.white);
740                 //g2.setXORMode(Color.white);
741
}
742             symbolicGridLine = new Rectangle2D.Double JavaDoc(xx + outlineStrokeWidth,
743                 yy1, plotArea.getMaxX() - xx - outlineStrokeWidth, yy2 - yy1);
744             g2.fill(symbolicGridLine);
745             this.symbolicGridLineList.add(symbolicGridLine);
746             currentGridLineIsDark = !currentGridLineIsDark;
747         }
748         g2.setPaintMode();
749     }
750
751 }
752
Popular Tags