001    /*
002     * Copyright 2007,2008 John C. Gunther
003     * 
004     * Licensed under the Apache License, Version 2.0 (the
005     * "License"); you may not use this file except in compliance
006     * with the License. You may obtain a copy of the License at:
007     * 
008     *  http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing,
011     * software distributed under the License is distributed on an
012     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013     * either express or implied. See the License for the specific
014     * language governing permissions and limitations under the
015     * License.
016     * 
017     */
018    package com.googlecode.gchart.client;
019    
020    import java.util.ArrayList;
021    import java.util.Date;
022    
023    import com.google.gwt.i18n.client.DateTimeFormat;
024    import com.google.gwt.i18n.client.NumberFormat;
025    import com.google.gwt.user.client.DOM;
026    import com.google.gwt.user.client.Event;
027    import com.google.gwt.user.client.ui.*;
028    
029    /**
030     * A GChart can represent and display a line chart, a bar chart,
031     * a pie chart, an area chart, or a chart that contains arbitrary
032     * combinations of line, bar, pie, and/or area based curves.
033     * 
034     * <p>
035     * For detailed examples, with screen shots, visit the
036     * <a href="package-summary.html#ChartGallery">
037     * Chart Gallery</a>. 
038     * 
039     * <p>
040     * For detailed instructions on how to integrate Client-side GChart
041     * into your GWT application, see
042     * <a href="package-summary.html#InstallingGChart">
043     * Installing Client-side GChart</a>.
044     * 
045     * <p>
046     * <b>CSS Style Rule</b>
047     * <ul>
048     * .gchart-GChart { the GChart's primary top-level styles }</li>
049     * </ul>
050     *
051     *
052     * It is sometimes more natural to consider certain CSS
053     * attributes as properties of a GChart Java object. So, GChart
054     * supports "CSS convenience methods" that let you (optionally) use
055     * Java to specify GChart CSS attributes such as
056     * <tt>border-color</tt> and <tt>background-color</tt>. See
057     * {@link #USE_CSS USE_CSS} for a detailed description of these
058     * CSS convenience methods, and how to assure that they don't
059     * interfere with more traditional, CSS attribute-based,
060     * specifications.
061     *
062     * 
063     **/ 
064    
065    public class GChart extends Composite {
066     
067       /**
068        ** Defines the location of a data point's annotation
069        ** (text label) relative to the location of that point's
070        ** symbol. The default annotation location is {@link
071        ** AnnotationLocation#SOUTH SOUTH}. See
072        ** the "Field Summary" section below for the list of the
073        ** available annotation locations.
074        ** <p>
075        ** 
076        ** You can further adjust the position of a point's
077        ** annotation by specifying non-zero positional shifts via
078        ** the <tt>setAnnotationXShift</tt> and
079        ** <tt>setAnnotationYShift</tt> methods.
080        **
081        ** @see Point#setAnnotationLocation Point.setAnnotationLocation
082        ** @see Point#setAnnotationXShift Point.setAnnotationXShift
083        ** @see Point#setAnnotationYShift Point.setAnnotationYShift
084        ** 
085        **/ 
086       public static final class AnnotationLocation {
087          /**
088           ** Specifies that a point's annotation (label) should
089           ** be positioned so as to be centered on the symbol
090           ** used to represent the point.
091           **
092           ** @see Point#setAnnotationLocation setAnnotationLocation
093           **/
094          public static final AnnotationLocation CENTER =
095            new AnnotationLocation(0,0);
096    
097          /**
098           ** Specifies that a point's annotation (label) should
099           ** be centered on the center-point of the
100           ** arc side of a pie slice.
101           ** <p>
102           **
103           ** You can move a pie slice's annotation a specific number
104           ** of pixels radially away from (or towards) the pie
105           ** center by passing a positive (or negative) argument to
106           ** the associated <tt>Point</tt>'s
107           ** <tt>setAnnotationXShift</tt> method.
108           ** 
109           **
110           ** 
111           ** <p> This is pie-friendly synonym for, and when used
112           ** with non-pie symbol types will behave exactly the same
113           ** as, <tt>AnnotationLocation.CENTER</tt>
114           **
115           ** @see #OUTSIDE_PIE_ARC OUTSIDE_PIE_ARC
116           ** @see #INSIDE_PIE_ARC INSIDE_PIE_ARC
117           ** @see Point#setAnnotationLocation setAnnotationLocation
118           ** @see AnnotationLocation#CENTER CENTER
119           ** 
120           **/
121          public static final AnnotationLocation ON_PIE_ARC = CENTER;
122          
123          /**
124           ** Specifies that a point's annotation (label) should
125           ** be positioned just to the right of, and vertically
126           ** centered on, the symbol used to represent the
127           ** point.
128           **
129           ** @see Point#setAnnotationLocation
130           **/
131          public static final AnnotationLocation EAST =
132             new AnnotationLocation(1, 0);
133    
134          /**
135           ** Specifies that a point's annotation (label) should be
136           ** placed just to the left of, and centered vertically on,
137           ** horizontal bars that grow left from a vertical
138           ** baseline, and just to the right of, and centered
139           ** vertically on, horizontal bars that grow right from a
140           ** vertical baseline.
141           **
142           ** <p>
143           **
144           ** This another name for
145           ** <tt>AnnotationLocation.EAST</tt>. Its sole purpose is
146           ** to clarify/document the behavior of this location type
147           ** when used in conjunction with curves that employ the
148           ** <tt>HBAR_BASELINE_*</tt> family of symbol types.
149           **
150           ** @see Point#setAnnotationLocation setAnnotationLocation
151           ** @see SymbolType#HBAR_BASELINE_CENTER SymbolType.HBAR_BASELINE_CENTER
152           ** 
153           **/
154          public static final AnnotationLocation 
155              FARTHEST_FROM_VERTICAL_BASELINE = EAST;
156          
157    
158    
159          /**
160           ** Specifies that a point's annotation (label) should
161           ** be positioned just above, and horizontally centered on,
162           ** the symbol used to represent the point.
163           **
164           ** @see Point#setAnnotationLocation setAnnotationLocation
165           **/
166          public static final AnnotationLocation NORTH =
167              new AnnotationLocation(0,-1);
168    
169          /**
170           ** Specifies that a point's annotation (label) should be
171           ** placed just above, and centered horizontally on,
172           ** vertical bars that grow down from a horizontal
173           ** baseline, and just below, and centered horizontally on,
174           ** vertical bars that grow up from a horizontal baseline.
175           **
176           ** <p>
177           **
178           ** This another name for
179           ** <tt>AnnotationLocation.NORTH</tt>. Its sole purpose is
180           ** to clarify/document the behavior of this location type
181           ** when used in conjunction with curves that employ 
182           ** <tt>VBAR_BASELINE_*</tt> symbol types.
183           **
184           ** @see Point#setAnnotationLocation setAnnotationLocation
185           ** @see SymbolType#VBAR_BASELINE_CENTER SymbolType.VBAR_BASELINE_CENTER
186           ** 
187           **/
188          public static final AnnotationLocation 
189              CLOSEST_TO_HORIZONTAL_BASELINE = NORTH;
190          
191          /**
192           ** Specifies that a point's annotation (label) should
193           ** be positioned just inside, and centered on, the
194           ** arc side of a pie slice.
195           ** <p>
196           ** 
197           ** You can move a pie slice's annotation a specific number
198           ** of pixels radially away from (or towards) the pie
199           ** center by passing a positive (or negative) argument to
200           ** the associated <tt>Point</tt>'s
201           ** <tt>setAnnotationXShift</tt> method.
202           ** 
203           ** <p> This is pie-friendly synonym for, and when used
204           ** with non-pie symbol types will behave exactly the same
205           ** as, <tt>AnnotationLocation.NORTH</tt>
206           **      
207           ** @see #OUTSIDE_PIE_ARC OUTSIDE_PIE_ARC
208           ** @see #ON_PIE_ARC ON_PIE_ARC
209           ** @see Point#setAnnotationLocation setAnnotationLocation
210           ** @see AnnotationLocation#NORTH NORTH
211           **/
212          public static final AnnotationLocation INSIDE_PIE_ARC = NORTH;
213    
214          /**
215           ** Specifies that a point's annotation (label) should
216           ** be positioned just to the right of and above,
217           ** the symbol used to represent the
218           ** point.
219           **
220           ** @see Point#setAnnotationLocation
221           **/
222          public static final AnnotationLocation NORTHEAST =
223            new AnnotationLocation(1, -1);
224    
225          /**
226           ** Specifies that a point's annotation (label) should
227           ** be positioned just to the left of and above,
228           ** the symbol used to represent the
229           ** point.
230           **
231           ** @see Point#setAnnotationLocation
232           **/
233          public static final AnnotationLocation NORTHWEST =
234            new AnnotationLocation(-1, -1);
235    
236          
237          /**
238           ** Specifies that a point's annotation (label) should
239           ** be positioned just below, and horizontally centered on,
240           ** the symbol used to represent the point.
241           **
242           ** @see Point#setAnnotationLocation setAnnotationLocation
243           **/
244          public static final AnnotationLocation SOUTH =
245              new AnnotationLocation(0, 1);
246    
247          /**
248           ** Specifies that a point's annotation (label) should be
249           ** placed just below, and centered horizontally on,
250           ** vertical bars that grow down from a horizontal
251           ** baseline, and just above, and centered horizontally on,
252           ** vertical bars that grow up from a horizontal baseline.
253           **
254           ** <p>
255           **
256           ** This another name for
257           ** <tt>AnnotationLocation.SOUTH</tt>. Its sole purpose is
258           ** to clarify/document the behavior of this location type
259           ** when used in conjunction with curves that employ
260           ** <tt>VBAR_BASELINE_*</tt> symbol types.
261           **
262           ** @see Point#setAnnotationLocation setAnnotationLocation
263           ** @see SymbolType#VBAR_BASELINE_CENTER SymbolType.VBAR_BASELINE_CENTER
264           ** 
265           **/
266          public static final AnnotationLocation
267              FARTHEST_FROM_HORIZONTAL_BASELINE = SOUTH;
268          
269          /**
270           ** Specifies that a point's annotation (label) should
271           ** be positioned just outside, and centered on, the
272           ** arc side of a pie slice.
273           ** <p>
274           ** 
275           ** You can move a pie slice's annotation a specific number
276           ** of pixels radially away from (or towards) the pie
277           ** center by passing a positive (or negative) argument to
278           ** the associated <tt>Point</tt>'s
279           ** <tt>setAnnotationXShift</tt> method.
280           ** 
281           ** <p> This is pie-friendly synonym for, and when used
282           ** with non-pie symbol types will behave exactly the same
283           ** as, <tt>AnnotationLocation.SOUTH</tt>
284           **
285           ** @see #INSIDE_PIE_ARC INSIDE_PIE_ARC
286           ** @see #ON_PIE_ARC ON_PIE_ARC
287           ** @see Point#setAnnotationLocation setAnnotationLocation
288           ** @see Point#setAnnotationXShift setAnnotationXShift
289           ** @see AnnotationLocation#SOUTH SOUTH
290           **/
291          public static final AnnotationLocation OUTSIDE_PIE_ARC = SOUTH;
292          
293          /**
294           ** Specifies that a point's annotation (label) should
295           ** be positioned just to the right of and below,
296           ** the symbol used to represent the
297           ** point.
298           **
299           ** @see Point#setAnnotationLocation setAnnotationLocation
300           **/
301          public static final AnnotationLocation SOUTHEAST =
302            new AnnotationLocation(1, 1);
303          /**
304           ** Specifies that a point's annotation (label) should
305           ** be positioned just to the left of and below,
306           ** the symbol used to represent the
307           ** point.
308           **
309           ** @see Point#setAnnotationLocation setAnnotationLocation
310           **/
311          public static final AnnotationLocation SOUTHWEST =
312            new AnnotationLocation(-1, 1);
313    
314          /**
315           ** Specifies that a point's annotation (label) should
316           ** be positioned just to the left of, and vertically
317           ** centered on, the symbol used to represent the
318           ** point.
319           **
320           ** @see Point#setAnnotationLocation setAnnotationLocation
321           **/
322          public static final AnnotationLocation WEST =
323            new AnnotationLocation(-1, 0);
324    
325          /**
326           ** Specifies that a point's annotation (label) should be
327           ** placed just to the right of, and centered vertically
328           ** on, horizontal bars that grow left from a vertical
329           ** baseline, and just to the left of, and centered
330           ** vertically on, horizontal bars that grow right from a
331           ** vertical baseline.
332           **
333           ** <p>
334           **
335           ** This another name for
336           ** <tt>AnnotationLocation.WEST</tt>. Its sole purpose is
337           ** to clarify/document the behavior of this location type
338           ** when used in conjunction with curves that employ the
339           ** <tt>HBAR_BASELINE_*</tt> symbol types.
340           **
341           ** @see Point#setAnnotationLocation setAnnotationLocation
342           ** @see SymbolType#HBAR_BASELINE_CENTER SymbolType.HBAR_BASELINE_CENTER
343           ** 
344           **/
345           
346          public static final AnnotationLocation 
347             CLOSEST_TO_VERTICAL_BASELINE = WEST;
348          
349          // these multiply the width and height of the annotation and
350          // the symbol it is attached to in order to define the
351          // center of the annotation (see equations in later code)
352          private int heightMultiplier;
353          private int widthMultiplier;
354          private AnnotationLocation(int widthMultiplier,
355                                 int heightMultiplier) {
356            validateMultipliers(widthMultiplier, heightMultiplier);
357            this.widthMultiplier = widthMultiplier;
358            this.heightMultiplier = heightMultiplier;
359          }
360          AnnotationLocation() {this(0, 0);}
361          // Negative width or height "turn the symbol inside-out",
362          // requiring a corresponding change in annotation location
363          // (this is only needed for baseline-based bar symbols)
364          static AnnotationLocation transform(AnnotationLocation a,
365                                              double symWidth,
366                                              double symHeight) {
367            int wSign = GChart.sign(symWidth);
368            int hSign = GChart.sign(symHeight);
369            AnnotationLocation result = a;
370            if (wSign < 0 || hSign < 0) 
371              result = new AnnotationLocation(wSign*a.widthMultiplier,
372                                              hSign*a.heightMultiplier);
373            return result;
374          }
375          // These define the alignment of the label within it's
376          // containing 1 x 1 Grid. For example, if this
377          // containing grid is to the left of the labeled
378          // symbol (widthMultiplier==-1) the horizontal
379          // alignment will be ALIGN_RIGHT, so as to bring the
380          // contained label flush against the left edge of the
381          // labeled symbol.
382          HasHorizontalAlignment.HorizontalAlignmentConstant
383                getHorizontalAlignment() {
384             HasHorizontalAlignment.HorizontalAlignmentConstant result;
385             if (widthMultiplier == -1)
386                result = HasHorizontalAlignment.ALIGN_RIGHT;
387             else if (widthMultiplier == 0)
388                result = HasHorizontalAlignment.ALIGN_CENTER;
389             else if (widthMultiplier == 1)
390                result = HasHorizontalAlignment.ALIGN_LEFT;
391             else
392                throw new IllegalStateException(
393                   "Invalid widthMultiplier: " + widthMultiplier +
394                   " 1, 0, or -1 were expected.");
395             return result;
396          }
397    
398          /* Given the x-coordinate at the center of the symbol
399           * that this annotation annotates, the annotation's
400           * width, and the symbol's width, this method returns
401           * the x-coordinate of the upper left corner of
402           * this annotation.
403           */
404          int getUpperLeftX(double x, double w, double symbolW) {
405             int result = (int) Math.round(x +
406               (widthMultiplier * (w + symbolW) - w)/2.0);
407             return result;
408          }
409    
410          /* analogous to getUpperLeftX, except for the y-coordinate */
411          int getUpperLeftY(double y, double h, double symbolH) {
412             int result = (int) Math.round(y +
413               (heightMultiplier * (h + symbolH) - h)/2.0);
414             return result;
415          }
416    
417          HasVerticalAlignment.VerticalAlignmentConstant
418                getVerticalAlignment() {
419             HasVerticalAlignment.VerticalAlignmentConstant result;
420             if (heightMultiplier == -1)
421                result = HasVerticalAlignment.ALIGN_BOTTOM;
422             else if (heightMultiplier == 0)
423                result = HasVerticalAlignment.ALIGN_MIDDLE;
424             else if (heightMultiplier == 1)
425                result = HasVerticalAlignment.ALIGN_TOP;
426             else
427                throw new IllegalStateException(
428                   "Invalid heightMultiplier: " + heightMultiplier +
429                   " -1, 0, or 1 were expected.");
430             return result;
431          }
432    
433    
434          AnnotationLocation
435              decodePieLocation(AnnotationLocation outside,
436                                AnnotationLocation inside) {
437            AnnotationLocation result;
438            if (heightMultiplier == -1)
439                result = inside;
440             else if (heightMultiplier == 0)
441                result = AnnotationLocation.CENTER;
442             else if (heightMultiplier == 1)
443                result = outside;
444             else
445                throw new IllegalStateException(
446                   "Invalid heightMultiplier: " + heightMultiplier +
447                   " -1, 0, or 1 were expected.");
448             return result;
449          }
450    
451          
452       }
453    
454      /**
455       ** Represents an axis of the chart, for example, the x,
456       ** y, or y2 axis. An axis consists of the axis itself,
457       ** along with its tick marks, tick labels and gridlines.
458       **
459       ** @see XAxis XAxis
460       ** @see YAxis YAxis
461       ** @see Y2Axis Y2Axis
462       ** @see #getXAxis getXAxis 
463       ** @see #getYAxis getYAxis
464       ** @see #getY2Axis getY2Axis
465       ** 
466       **
467       **/ 
468      public abstract class Axis {
469         // holds info needed to render a single axis tick
470         private class TickInfo {
471            double position;  // along the tick axis in model units
472            String tickLabel;
473            TickInfo(double position, String tickLabel) {
474               this.position = position;
475               this.tickLabel = tickLabel;
476            }
477         }
478         protected class AxisLimits { 
479          double max; double min; 
480         }
481         private Widget axisLabel;
482         private boolean hasGridlines = false;
483         private int tickCount = DEFAULT_TICK_COUNT;
484         private ArrayList tickInfo = new ArrayList();
485         protected double axisMax = Double.NaN;
486         // axes will auto-scale if min or max are NaN.
487         protected double axisMin = Double.NaN;
488    // this symbol facilitates rendering of gridlines & axes
489         protected Symbol gridSymbol;
490         protected String tickLabelFontColor = DEFAULT_TICK_LABEL_FONT_COLOR;
491         // In CSS font-size pixels. These define the height of each
492    // character; our code relies on the rule of thumb that
493    // character width is approximately 3/5th this height to
494    // obtain a reasonably tight upper bound on tick label widths. 
495         protected int tickLabelFontSize = DEFAULT_TICK_LABEL_FONTSIZE;
496         protected String tickLabelFontStyle = "normal";
497         protected String tickLabelFontWeight = "normal";
498    
499         protected String tickLabelFormat = DEFAULT_TICK_LABEL_FORMAT;
500         protected int tickLabelThickness = GChart.NAI;
501         protected int ticksPerLabel = 1;
502         protected int tickLength = DEFAULT_TICK_LENGTH;
503         
504         // this symbol facilitates rendering of labeled tick-marks
505         protected Symbol tickSymbol;
506         protected int tickThickness = DEFAULT_TICK_THICKNESS;
507    
508         // is axis itself visible (has no impact on axis tick visibility)
509         boolean axisVisible = true;
510         /**
511          * Adds a tick on this axis at the specified position.
512          * Note that explicitly adding a single tick via this method
513          * will eliminate any implicitly generated ticks associated with the
514          * <tt>setTickCount</tt> method.
515          * <p>
516          * The label associated with this tick will be generated by
517          * applying the format specified via <tt>setTickLabelFormat</tt>
518          * to the specified position.
519          * <p>
520          * Equivalent to <tt>addTick(tickPosition, null)</tt>.
521          * 
522          * @param tickPosition the position, in model units,
523          *   along this axis at which this tick is displayed.
524          *   For example, if the axis range goes from 0 to 100,
525          *   a tick at position 50 would appear in the middle of
526          *   the axis.
527          *
528          * @see #clearTicks clearTicks
529          * @see #addTick(double,String) addTick(double,String)
530          * @see #setTickCount setTickCount
531          * @see #setTickLabelFormat setTickLabelFormat
532          * @see #setTickLabelFontStyle setTickLabelFontStyle
533          * @see #setTickLabelFontColor setTickLabelFontColor
534          * @see #setTickLabelFontWeight setTickLabelFontWeight
535          * @see #setTickLabelFontSize setTickLabelFontSize
536          * 
537          */
538         public void addTick(double tickPosition) {
539            addTick(tickPosition, null);  
540         }
541         /**
542          * Adds a tick at the specified position with the specified
543          * label on this axis.
544          * <p>
545          * Note that explicitly adding a single tick via this method
546          * will eliminate any auto-generated ticks associated with the
547          * <tt>setTickCount</tt> method. 
548          * 
549          * <p>
550          * Use this method to specify unusually spaced
551          * tick marks with labels that do not directly
552          * reflect the position (for example, for a logarithmic axis,
553          * or for a bar chart with special keyword-type labels).
554          * 
555          * @param tickPosition the position, in model units, along
556          *   this axis at which the tick is displayed.
557          *   For example, if the axis range goes from 0 to 1,
558          *   a tick at position 0.5 would appear in the middle of
559          *   the axis.
560          * @param tickLabel the label for this tick. HTML is not
561          *    supported in tick labels, though you can change
562          *    the font via the <tt>setTickLabelFont*</tt> family
563          *    of methods.
564          *
565          * @see #clearTicks clearTicks
566          * @see #addTick(double) addTick(double)
567          * @see #setTickCount setTickCount
568          * @see #setTickLabelFormat setTickLabelFormat
569          * @see #setTickLabelFontSize setTickLabelFontSize
570          * @see #setTickLabelFontStyle setTickLabelFontStyle
571          * @see #setTickLabelFontColor setTickLabelFontColor
572          * @see #setTickLabelFontWeight setTickLabelFontWeight
573          * 
574          */
575         public void addTick(double tickPosition, String tickLabel) {
576           tickCount = 0; // eliminates any auto-generated ticks   
577           tickInfo.add(new TickInfo(tickPosition, tickLabel));  
578         }
579         /**
580          * Erases all ticks that were explicitly specified via
581          * <tt>addTick</tt>, and also sets the tick count to 0.
582          * <p>
583          * @see #setTickCount setTickCount
584          * @see #addTick(double) addTick(double)
585          * @see #addTick(double,String) addTick(double,String)
586          * 
587          */
588         public void clearTicks() {
589            tickCount = 0;
590            tickInfo.clear();
591         }
592         // these are used in formatting tick positions into tick labels:
593         private NumberFormat numberFormat =
594            NumberFormat.getFormat(DEFAULT_TICK_LABEL_FORMAT);
595         private DateTimeFormat dateFormat =
596            DateTimeFormat.getShortDateTimeFormat();
597         private final int NUMBER_FORMAT_TYPE = 0;
598         private final int DATE_FORMAT_TYPE = 1;
599         private final int LOG10INVERSE_FORMAT_TYPE = 2;
600         private final int LOG2INVERSE_FORMAT_TYPE = 3;
601         private int tickLabelFormatType = NUMBER_FORMAT_TYPE;
602         /**
603         * 
604         * Applies this axis' tick label format to format a given value.
605         * 
606         * @return the value formated as per this axis' currently specified 
607         * tick label format.
608         * 
609         * @see  #setTickLabelFormat(String) setTickLabelFormat
610         * 
611         */
612         public String formatNumberAsTickLabel(double value) {
613           String result = null;
614           switch (tickLabelFormatType) {
615             case DATE_FORMAT_TYPE:
616               Date transDate = new Date((long) value);
617               result = dateFormat.format(transDate);
618               break;
619             case LOG10INVERSE_FORMAT_TYPE:
620               value = Math.pow(10., value);
621               result = numberFormat.format(value);
622               break;
623             case LOG2INVERSE_FORMAT_TYPE:
624               value = Math.pow(2., value);
625               result = numberFormat.format(value);
626               break;
627             default:  
628               result = numberFormat.format(value);
629               break;
630           }
631           
632           return result;
633        }
634    
635         /** Returns the previously specified label of this axis.
636          **
637          ** @return the Widget used as the label of this axis
638          **
639          ** @see #setAxisLabel setAxisLabel
640          ** 
641          */
642         public Widget getAxisLabel() {
643           return axisLabel;
644         }
645         
646         /**
647          ** Returns the maximum value displayed on this axis.
648          ** If the explicitly specified maximum value is
649          ** undefined (<tt>Double.NaN</tt>) the maximum value returned
650          ** by this function is calculated as the maximum of
651          ** all of the values either displayed on this axis via
652          ** points on a curve, or explicitly specified via tick
653          ** positions. 
654          **
655          ** @return maximum value visible on this axis, in
656          ** "model units" (arbitrary, application-specific,
657          ** units)
658          **
659          ** @see #setAxisMax setAxisMax
660          ** @see #getDataMin getDataMin
661          ** @see #getDataMax getDataMax
662          **/ 
663         public double getAxisMax() {
664            if (!Double.isNaN(axisMax)) {
665               return axisMax;
666            }
667            else if (tickCount > 0) { // ignores previous explicit ticks
668              return getDataMax();
669            }
670            else {
671               return Math.max(getDataMax(), getTickMax());           
672            }
673         }
674         /**
675          **
676          ** Returns the minimum value displayed on this axis.
677          ** If the minimum value is undefined (<tt>Double.NaN</tt>) the
678          ** minimum value returned by this function is the
679          ** minimum of all of the values either displayed on
680          ** this axis via points on a curve, or explicitly specified
681          ** via tick positions.
682          **
683          ** @return minimum value visible on this axis, in
684          ** "model units" (arbitrary, application-specific,
685          ** units)
686          **
687          ** @see #setAxisMin setAxisMin
688          **/ 
689         public double getAxisMin() {
690            if (!Double.isNaN(axisMin)) {
691               return axisMin; // explicitly set
692            }
693            else if (tickCount > 0) { // ignore any previous ticks
694               return getDataMin();
695            }
696            else {  
697               return Math.min(getDataMin(), getTickMin());           
698            }
699         }
700    
701       /** Is axis line visible on the chart? Note that
702        ** this property only determines the visibility of the axis line
703        ** itself. It does not control the visibility of the
704        ** tick marks or tick labels along this axis.
705        ** <p>
706        **
707        ** @return true if the axis line is visible, false otherwise.
708        **
709        ** @see #setAxisVisible setAxisVisible
710        ** 
711        **/ 
712         public boolean getAxisVisible() {
713           return axisVisible;
714         }
715    
716    
717         
718         /** Returns the maximum data value associated with values
719         ** represented on this axis. For example, for the left
720         ** y-axis, this would be the largest y-value of all points
721         ** contained in curves that are displayed on the left y-axis.
722         ** 
723         ** @return the maximum value associated with values
724         **   mapped onto this axis.
725         **
726         ** @see #getDataMin getDataMin
727         ** @see #getAxisMax getAxisMax
728         ** @see #getAxisMin getAxisMin
729         ** 
730          */
731        public abstract double getDataMax();
732         /** Returns the minimum data value associated with values
733         ** represented on this axis. For example, for the left
734         ** y-axis, this would be the smallest y-value of all points
735         ** contained in curves that are displayed on the left y-axis.
736         **
737         ** @return the minumum value associated with values
738         **   mapped onto this axis.
739         **
740         ** @see #getDataMax getDataMax
741         ** @see #getAxisMax getAxisMax
742         ** @see #getAxisMin getAxisMax
743         **
744          */
745        public abstract double getDataMin();
746         
747         /** Returns the gridline setting previously made with
748          ** <tt>setHasGridlines</tt>.
749          **
750          ** @return true if gridlines have been enabled, false if not.
751          **
752          ** @see #setHasGridlines setHasGridlines
753          ** 
754          **/
755         public boolean getHasGridlines() {
756            return hasGridlines;
757         }
758         /**
759          ** Returns the number of ticks on this axis.
760          **
761          ** @return the number of ticks on this axis.
762          **
763          ** @see #setTickCount setTickCount
764          ** @see #addTick(double) addTick(double)
765          ** @see #addTick(double,String) addTick(double,String)
766          ** @see #clearTicks clearTicks
767          ** 
768          **/
769         public int getTickCount() {
770            if (tickCount == 0)
771               return tickInfo.size();
772            else
773               return tickCount;
774         }
775         /**
776          ** Returns the CSS font-weight specification to be used
777          ** by this axis' tick labels.
778          **
779          ** @return font-weight of this axis' tick labels
780          **
781          ** @see #setTickLabelFontWeight setTickLabelFontWeight
782          **/ 
783         public String getTickLabelFontWeight() {
784            return tickLabelFontWeight;
785         }
786         /**
787          ** Returns the color of the font used to display the
788          **    text of the tick labels on this axis.
789          **   
790          **   
791          ** @return CSS color string defining the color of the text of
792          **    the tick labels for this axis.
793          **
794          ** @see #setTickLabelFontColor setTickLabelFontColor
795          **
796          ** @see #DEFAULT_TICK_LABEL_FONT_COLOR DEFAULT_TICK_LABEL_FONT_COLOR
797          **
798          **
799          ** 
800          **/ 
801         public String getTickLabelFontColor() {
802            return tickLabelFontColor;
803         }
804    
805         /**
806          ** Returns the font-style of font used to render tick labels on this
807          ** axis (typically either "italic" or "normal")  
808          **
809          ** 
810          **
811          ** @return the CSS font-style in which tick labels of this axis
812          **   are rendered.
813          **
814          ** @see #setTickLabelFontStyle setTickLabelFontStyle
815          **/ 
816         public String getTickLabelFontStyle() {
817            return tickLabelFontStyle;
818         }
819         /** Returns the font size, in pixels, used for tick labels
820          ** on this axis.
821          **
822          ** @return the tick label font size in pixels
823          **
824          ** @see #setTickLabelFontSize setTickLabelFontSize
825          **/ 
826         public int getTickLabelFontSize() {
827            return tickLabelFontSize;
828         }
829    
830         /**
831         ** Returns the tick label numeric format string for this
832         ** axis.
833         **
834         ** @return numeric format used to generate tick labels.
835         **
836         ** @see #setTickLabelFormat setTickLabelFormat
837         ** 
838         **/ 
839        public String getTickLabelFormat() {
840           return tickLabelFormat;
841        }
842        /** Returns the thickness of the band adjacent to
843         ** this axis that GChart will
844         ** allocate to hold this axis' tick labels.
845         ** <p>
846         **
847         ** @return width of band, in pixels, GChart will reserve
848         **   for this axis' tick labels.
849         **   
850         ** @see #setTickLabelThickness setTickLabelThickness
851         ** 
852         **/ 
853        public int getTickLabelThickness() {
854          int maxLength = 0;
855          int result;
856          if (tickLabelThickness != GChart.NAI)
857            result = tickLabelThickness;
858          else {
859           maybePopulateTicks();
860           for (int i=0; i < tickInfo.size(); i++) {
861              if (getTickText(i) != null)
862                maxLength = Math.max(maxLength, getTickText(i).length());
863           }
864           result = (int) Math.round(maxLength * tickLabelFontSize *
865                    TICK_CHARWIDTH_TO_FONTSIZE_LOWERBOUND);
866          }
867          return result;
868        }
869    
870    
871        /**
872         ** Returns the ratio of the number of ticks to the number of
873         ** labeled ticks. 
874         **
875         ** @return number of ticks per label.
876         **
877         ** @see #setTicksPerLabel setTicksPerLabel
878         **
879         **/
880        public int getTicksPerLabel() {
881          return ticksPerLabel;
882        }
883    
884         /**
885         * Returns the length of ticks for this axis.
886         *
887         * @return the length of this axis' ticks, in pixels.
888         *
889         * @see #setTickLength setTickLength
890         */
891        public int getTickLength() {
892           return tickLength;
893        }
894    
895        /**
896         * Returns the thickness of ticks for this axis.
897         *
898         * @return the thickness of this axis' ticks, in pixels.
899         *
900         * @see #setTickThickness setTickThickness
901         * @see #getTickLength getTickLength
902         */
903        public int getTickThickness() {
904           return tickThickness;
905        }
906    
907         /**
908          * Convenience method equivalent to
909          * <tt>setAxisLabel(new HTML(html))</tt>
910          *
911          * @param html HTML text used to define the axis label
912          * 
913          * @see #setAxisLabel(Widget) setAxisLabel(Widget)
914          */
915         public void setAxisLabel(String html) {
916           this.axisLabel = new HTML(html);
917         }
918    
919         /** Specifies the label of this axis.
920          **
921          ** @param axisLabel a Widget to use as the label of this axis.
922          **
923          ** @see #getAxisLabel getAxisLabel
924          */
925         
926         public void setAxisLabel(Widget axisLabel) {
927           this.axisLabel = axisLabel;
928         }
929    
930         /**
931          ** Specifies the maximum value of this axis.
932          ** Points with associated coordinates greater than this
933          ** will not be shown.
934          ** <p>
935          ** 
936          ** If <tt>Double.NaN</tt> is specified, this maximum
937          ** is computed as described in <tt>getAxisMax</tt>.
938          **
939          ** @param max maximum value visible on this axis, in "model units"
940          ** (arbitrary, application-specific, units) or <tt>Double.NaN</tt>
941          ** to use an auto-computed maximum.
942          **
943          ** @see #getAxisMax getAxisMax
944          ** @see #getDataMin getDataMin
945          ** @see #getDataMax getDataMax
946          ** 
947          **/ 
948         public void setAxisMax(double max) {
949            this.axisMax = max;
950         }
951         /**
952          ** Specifies the minimum value of this axis.
953          ** Points with associated coordinates less than this
954          ** will not be shown. 
955          ** <p>
956          ** 
957          ** If <tt>Double.NaN</tt> is specified, this minimum
958          ** is auto-computed as described in <tt>getAxisMin</tt>.
959          ** 
960          ** @param min minumum value visible on this axis, in "model units"
961          ** (arbitrary, application-specific, units), or Double.NaN
962          ** to use an auto-computed minimum.
963          **
964          ** @see #getAxisMin getAxisMin
965          ** @see #getDataMin getDataMin
966          ** @see #getDataMax getDataMax
967          ** 
968          **/ 
969         public void setAxisMin(double min) {
970            this.axisMin = min;
971         }
972    
973      /**
974       ** Defines if this axis is visible. Note that
975       ** this property only defines the visibility of the axis line
976       ** itself, it does not control the visibility of
977       ** tick marks or tick labels associated with the axis.
978       ** 
979       ** <p>
980       ** <i>Tip:</i>Tick marks can be made invisible by using
981       ** <tt>setTickThickness</tt> to set the tick thickness
982       ** to 0. Tick labels can be made invisible by using
983       ** <tt>setTickLabelFontColor</tt> and setting the
984       ** color so that it matches the chart's background color.
985       ** <p>
986       ** 
987       ** @param axisVisible false to hide axis, true to show it.
988       **
989       ** @see #setTickThickness setTickThickness
990       ** @see #setTickLabelFontColor setTickLabelFontColor
991       ** @see #getAxisVisible getAxisVisible
992       **/ 
993       public void setAxisVisible(boolean axisVisible) {
994          this.axisVisible = axisVisible;
995       }
996       
997         
998         /**
999          ** Specifies if this axis should have gridlines. When an
1000          ** axis has gridlines, each tick mark is in effect extended
1001          ** across the entire chart.
1002          **
1003          ** @param hasGridlines true to display gridlines,
1004          ** false (the default) to not display them.
1005          **
1006          ** @see #getHasGridlines getHasGridlines
1007          ** 
1008          **/ 
1009         public void setHasGridlines(boolean hasGridlines) {
1010            this.hasGridlines = hasGridlines;
1011         }
1012         /** Sets the number of ticks to be placed on this axis. The
1013          ** default tick count is 10. Ticks are always evenly
1014          ** spaced across the axis, unless explicitly
1015          ** specified via <tt>addTick</tt>.
1016          ** <p>
1017          ** Note that setting the tick count overrides (erases)
1018          ** any ticks explicitly specified via <tt>addTick</tt>.
1019          ** 
1020          ** @param tickCount the number of ticks for this axis. 
1021          ** 
1022          ** @see #getTickCount getTickCount
1023          ** @see #addTick(double) addTick(double)
1024          ** @see #addTick(double,String) addTick(double, String)
1025          ** @see #setTickLabelFormat setTickLabelFormat
1026          ** @see #setTickLabelFontSize setTickLabelFontSize
1027          ** @see #setTickLabelFontStyle setTickLabelFontStyle
1028          ** @see #setTickLabelFontColor setTickLabelFontColor
1029          ** @see #setTickLabelFontWeight setTickLabelFontWeight
1030          **
1031          **/
1032         public void setTickCount(int tickCount) {
1033            tickInfo.clear();    // eliminate user specified ticks
1034            this.tickCount = tickCount;
1035         }
1036    
1037         
1038         /**
1039          ** Specifies the weight of the font used in the labels of the
1040          ** legend.
1041          ** 
1042          ** @param cssWeight the weight of the font, such as bold,
1043          **    normal, light, 100, 200, ... 900 
1044          **
1045          ** @see #getTickLabelFontWeight getTickLabelFontWeight  
1046          ** @see #setTickLabelFormat setTickLabelFormat
1047          ** @see #setTickCount setTickCount
1048          ** @see #addTick(double) addTick(double)
1049          ** @see #addTick(double,String) addTick(double,String)
1050          ** @see #setTickLabelFontStyle setTickLabelFontStyle
1051          ** @see #setTickLabelFontColor setTickLabelFontColor
1052          ** @see #setTickLabelFontSize setTickLabelFontSize
1053          **/ 
1054         public void setTickLabelFontWeight(String cssWeight) {
1055            tickLabelFontWeight = cssWeight;
1056         }
1057         /**
1058          ** Specifies the color of the font used to rended tick labels
1059          ** for this axis.
1060          ** 
1061          ** <p>
1062          ** For more information on standard CSS color
1063          ** specifications see the discussion in
1064          ** {@link Symbol#setBackgroundColor Symbol.setBackgroundColor}.
1065          ** <p>
1066          **        
1067          ** @param cssColor color of the font used to display this
1068          **    axes' tick labels, in standard CSS format.
1069          **
1070          ** @see #getTickLabelFontColor getTickLabelFontColor  
1071          ** @see #setTickLabelFormat setTickLabelFormat
1072          ** @see #setTickCount setTickCount
1073          ** @see #addTick(double) addTick(double)
1074          ** @see #addTick(double,String) addTick(double,String)
1075          ** @see #setTickLabelFontStyle setTickLabelFontStyle
1076          ** @see #setTickLabelFontWeight setTickLabelFontWeight
1077          ** @see #setTickLabelFontSize setTickLabelFontSize
1078          **/ 
1079         public void setTickLabelFontColor(String cssColor) {
1080            tickLabelFontColor = cssColor;
1081         }
1082    
1083         /**
1084          ** Specifies the CSS font-style of this
1085          ** axis' tick labels.
1086          **
1087          ** @param cssStyle any valid CSS font-style, namely,
1088          **   normal, italic, oblique, or inherit.
1089          **
1090          ** @see #getTickLabelFontStyle getTickLabelFontStyle  
1091          ** @see #setTickLabelFormat setTickLabelFormat
1092          ** @see #setTickCount setTickCount
1093          ** @see #addTick(double) addTick(double)
1094          ** @see #addTick(double,String) addTick(double,String)
1095          ** @see #setTickLabelFontColor setTickLabelFontColor
1096          ** @see #setTickLabelFontWeight setTickLabelFontWeight
1097          ** @see #setTickLabelFontSize setTickLabelFontSize
1098          **/ 
1099         public void setTickLabelFontStyle(String cssStyle) {
1100            tickLabelFontStyle = cssStyle;
1101         }
1102    
1103         /**
1104          ** Sets the tick label font size for tick labels on this
1105          ** axis, in pixels.
1106          **
1107          ** @param tickLabelFontSize the font size of tick labels
1108          **   displayed on this axis.
1109          **
1110          ** @see #getTickLabelFontSize getTickLabelFontSize
1111          ** @see #setTickLabelFormat setTickLabelFormat
1112          ** @see #setTickCount setTickCount
1113          ** @see #addTick(double) addTick(double)
1114          ** @see #addTick(double,String) addTick(double,String)
1115          ** @see #setTickLabelFontStyle setTickLabelFontStyle
1116          ** @see #setTickLabelFontColor setTickLabelFontColor
1117          ** @see #setTickLabelFontWeight setTickLabelFontWeight
1118          ** @see GChart#DEFAULT_TICK_LABEL_FONTSIZE DEFAULT_TICK_LABEL_FONTSIZE
1119          ** 
1120          **/ 
1121    
1122         public void setTickLabelFontSize(int tickLabelFontSize) {
1123            this.tickLabelFontSize = tickLabelFontSize;
1124         }
1125    
1126         /**
1127         * Specifies a format string to be used in
1128         * converting the numeric values associated with each
1129         * tick on this axis into tick labels.  This string must
1130         * follow the conventions of the number format patterns
1131         * used by the GWT <tt>NumberFormat</tt> class, <i>with three
1132         * exceptions:</i>
1133         * <p>
1134         * <ol>
1135         * 
1136         *  <li><i>Log10 inverse prefix</i>: If the string begins
1137         *  with the prefix <tt>=10^</tt> the value is replaced with
1138         *  <tt>pow(10.,value)</tt> and the so-transformed value is
1139         *  then formatted using the part of the format string that
1140         *  comes after this prefix, which must be a valid GWT 
1141         *  <tt>NumberFormat</tt> pattern (e.g. "##.##").
1142         *  <p>
1143         *  For an example of how to use this prefix to create a
1144         *  semi-log plot, see <a
1145         *  href="package-summary.html#GChartExample04">the
1146         *  Chart Gallery's GChartExample04</a>.
1147         *  <p>
1148         *
1149         *  <li><i>Log2 inverse prefix</i>: If the string begins with
1150         *  the prefix <tt>=2^</tt> the value is replaced with
1151         *  <tt>pow(2.,value)</tt> and the so-transformed value is
1152         *  then formatted using the part of the format string that
1153         *  comes after this prefix, which must be a valid GWT
1154         *  <tt>NumberFormat</tt> pattern.
1155         *  <p>
1156         *  
1157         *  <li><i>Date casting prefix</i>: If the string begins with
1158         *  the prefix <tt>=(Date)</tt> the value is replaced with
1159         *  <tt>new Date((long) value)</tt> and the so-transformed
1160         *  value is then formatted using the format string that
1161         *  comes after this prefix, which must be a valid GWT
1162         *  <tt>DateTimeFormat</tt> pattern (e.g. "yyyy-MM-dd&nbsp;HH:mm").
1163         *  For the special case format string of "=(Date)"
1164         *  (just the date casting prefix) GChart uses the
1165         *  <tt>DateTimeFormat</tt> returned by GWT's
1166         *  <tt>DateTimeFormat.getShortDateTimeFormat</tt> method.  <p>
1167         *  
1168         *  Note that the values associated with this Axis must
1169         *  represent the number of milliseconds since January 1,
1170         *  1970 (in the GMT time zone) whenever this date
1171         *  casting prefix is used.  <p>
1172         *
1173         *  
1174         *  For example, if the x-axis tick label format were
1175         *  "=(Date)MMM-dd-yyyy HH", then, for a tick located at the
1176         *  x position of 0, the tick label would be "Jan-01-1970 00"
1177         *  (on a client in the GMT time zone) and for a tick located
1178         *  at the x position of 25*60*60*1000 (one day + one hour,
1179         *  in milliseconds) the tick label would be "Jan-02-1970 01"
1180         *  (again, on a GMT-based client). Results would be
1181         *  shifted appropriately on clients in different time zones.
1182         *  <p>
1183         *
1184         *  Note that if your chart is based on absolute, GMT-based,
1185         *  millisecond times then date labels will change when your
1186         *  chart is displayed on clients in different time zones.
1187         *  Sometimes, this is what you want. To keep the date labels
1188         *  the same in all time zones, convert date labels into Java
1189         *  <tt>Date</tt> objects in your client-side code, then use
1190         *  the <tt>Date.getTime</tt> method, also in your
1191         *  client-side code, to convert those dates into the
1192         *  millisecond values GChart requires.  The <a
1193         *  href="package-summary.html#GChartExample12"> Chart
1194         *  Gallery's GChartExample12</a> illustrates how to use this
1195         *  second approach to produce a time series chart whose
1196         *  date-time labels are the same in all time zones.
1197         *  
1198         *  <p>
1199         *  
1200         *  <blockquote><small>
1201         *  
1202         *  Ben Martin describes an alternative (and more flexible)
1203         *  approach to formatting time series tick labels in his <a
1204         *  href="http://www.linux.com/feature/132854">GChart
1205         *  tutorial</a>. Ben's article, along with Malcolm Gorman's
1206         *  related <a
1207         *  href="http://groups.google.com/group/Google-Web-Toolkit/msg/6125ce39fd2339ac">
1208         *  GWT forum post</a> were the origin of this date
1209         *  casting prefix. Thanks! </small></blockquote>
1210         *    
1211         * </ol>
1212         * <p>
1213         * 
1214         * 
1215         * <p> Though HTML text is not supported, you can change the
1216         * size, weight, style, and color of tick label text via the
1217         * <tt>setTickLabelFont*</tt> family of methods.
1218         * 
1219         * @param format an appropriately prefixed
1220         *   GWT <tt>NumberFormat</tt> compatible or
1221         *   GWT <tt>DateTimeFormat</tt> compatible format string that
1222         *   defines how to convert tick values into tick labels.
1223         *
1224         * @see #setTickCount setTickCount
1225         * @see #addTick(double) addTick(double)
1226         * @see #addTick(double,String) addTick(double,String)
1227         * @see #setTickLabelFontSize setTickLabelFontSize
1228         * @see #setTickLabelFontStyle setTickLabelFontStyle
1229         * @see #setTickLabelFontColor setTickLabelFontColor
1230         * @see #setTickLabelFontWeight setTickLabelFontWeight
1231         *
1232         * @see #getTickLabelFormat getTickLabelFormat
1233         */
1234         public void setTickLabelFormat(String format) {
1235           // interpret prefix and create an appropriate formatter
1236           if (format.startsWith("=(Date)")) {
1237             String transFormat = format.substring("=(Date)".length());
1238             if (transFormat.equals("")) // so "=(Date)" works
1239               dateFormat = DateTimeFormat.getShortDateTimeFormat();
1240             else // e.g. "=(Date)mm/dd/yy hh:mm"
1241               dateFormat = DateTimeFormat.getFormat(transFormat);
1242             tickLabelFormatType = DATE_FORMAT_TYPE;
1243           }
1244           else if (format.startsWith("=10^")) {
1245             String transFormat = format.substring("=10^".length());
1246             numberFormat = NumberFormat.getFormat(transFormat);
1247             tickLabelFormatType = LOG10INVERSE_FORMAT_TYPE;
1248           }
1249           else if (format.startsWith("=2^")) {
1250             String transFormat = format.substring("=2^".length());
1251             numberFormat = NumberFormat.getFormat(transFormat);
1252             tickLabelFormatType = LOG2INVERSE_FORMAT_TYPE;
1253           }
1254           else {
1255             numberFormat = NumberFormat.getFormat(format);
1256             tickLabelFormatType = NUMBER_FORMAT_TYPE;
1257           }
1258           // remember original format (for use with the getter)
1259           tickLabelFormat = format;
1260         }
1261    
1262         /** Specifies the thickness of the region adjacent to
1263          ** this axis that GChart will reserve for purposes of
1264          ** holding this axis' tick labels.  <p>
1265          ** <p>
1266          **
1267          ** For vertical axes, this represents the width of the
1268          ** widest tick label, for horizontal axes, this represents
1269          ** the height of highest tick label.
1270          ** 
1271          ** By default, this property has the special "undefined"
1272          ** value <tt>GChart.NAI</tt>. With this value, the
1273          ** companion method
1274          ** <tt>getTickLabelThicknessUpperBound</tt> automatically
1275          ** estimates (and returns) this thickness using the
1276          ** following formulas: <p>
1277          **
1278          ** 
1279          ** <pre>
1280          ** For vertical axes:
1281          ** 
1282          **   0.7 * getTickLabelFontSize() * 
1283          **      (the number of characters in the longest tick label)
1284          **
1285          ** For horizontal (x) axes:
1286          **
1287          **   1.0 * getTickLabelFontSize()
1288          **      
1289          ** </pre>
1290          ** <p>
1291          **
1292          ** These defaults will usually allocate sufficient space to
1293          ** produce an acceptable gap between an axis' tick labels
1294          ** and the label for the axis itself. This method is
1295          ** intended for those special cases where you need more
1296          ** precise control over this gap.
1297          ** 
1298          ** <p>
1299          **
1300          ** <i>Tip:</i> It is sometimes easier to just set the tick
1301          ** label thickness to 0, and then introduce any spacing
1302          ** required via appropriate padding applied to the axis
1303          ** label widget itself.
1304          ** 
1305          ** <p>
1306          ** 
1307          ** @see #getTickLabelThickness getTickLabelThickness
1308          ** @see #getTickLabelFontSize getTickLabelFontSize
1309          ** @see #setAxisLabel setAxisLabel
1310          ** @see GChart#NAI NAI
1311          ** 
1312          **/
1313         public void setTickLabelThickness(int tickLabelThickness) {
1314           this.tickLabelThickness = tickLabelThickness;
1315         }
1316         /** Specifies the ratio of the number of tick marks on the
1317          ** axis, to the number of labeled tick marks on the axis.
1318          ** <p>
1319          ** 
1320          ** For example, with the default value of 1, every tick is
1321          ** labeled, whereas with a <tt>ticksPerLabel</tt> setting
1322          ** of 2, only the first, third, fifth, etc. ticks are
1323          ** labeled.
1324          ** 
1325          ** <p>
1326          ** 
1327          ** This setting is only used when tick labels
1328          ** are specified implicitly via <tt>setTickCount</tt>. It
1329          ** is ignored when tick positions and their labels are
1330          ** explicitly specified via <tt>addTick</tt>.
1331          **
1332          ** @see #setTickCount setTickCount
1333          ** @see #addTick(double) addTick(double)
1334          ** @see #addTick(double,String) addTick(double,String)
1335          **
1336          **/ 
1337         public void setTicksPerLabel(int ticksPerLabel) {
1338           if (ticksPerLabel <= 0)
1339             throw new IllegalArgumentException(
1340               "ticksPerLabel must be > 0");
1341           this.ticksPerLabel = ticksPerLabel;
1342         }
1343    
1344         /**
1345         * Sets this axes' tick length. Set the tick length to zero to
1346         * eliminate the tick entirely.
1347         * <p>
1348         * Note that GChart ticks are always "outside" ticks.
1349         *
1350         * @param tickLength the length of the tick.
1351         *
1352         * @see #getTickLength getTickLength
1353         * 
1354         */
1355        abstract public void setTickLength(int tickLength);
1356         /**
1357         * Sets this axes' tick thickness.
1358         * <p>
1359         * <i>Tip:</i> Set the tick thickness to zero to
1360         * to hide the tick but retain the spacing between tick labels
1361         * and the axis due to the ticks' length.
1362         * <p>
1363