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