KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > chart > plot > FastScatterPlot


1 /* ===========================================================
2  * JFreeChart : a free chart library for the Java(tm) platform
3  * ===========================================================
4  *
5  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jfreechart/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this library; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
24  * in the United States and other countries.]
25  *
26  * --------------------
27  * FastScatterPlot.java
28  * --------------------
29  * (C) Copyright 2002-2004, by Object Refinery Limited.
30  *
31  * Original Author: David Gilbert (for Object Refinery Limited);
32  * Contributor(s): Arnaud Lelievre;
33  *
34  * $Id: FastScatterPlot.java,v 1.11 2005/05/19 14:03:39 mungady Exp $
35  *
36  * Changes (from 29-Oct-2002)
37  * --------------------------
38  * 29-Oct-2002 : Added standard header (DG);
39  * 07-Nov-2002 : Fixed errors reported by Checkstyle (DG);
40  * 26-Mar-2003 : Implemented Serializable (DG);
41  * 19-Aug-2003 : Implemented Cloneable (DG);
42  * 08-Sep-2003 : Added internationalization via use of properties
43  * resourceBundle (RFE 690236) (AL);
44  * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
45  * 12-Nov-2003 : Implemented zooming (DG);
46  * 21-Jan-2004 : Update for renamed method in ValueAxis (DG);
47  * 26-Jan-2004 : Added domain and range grid lines (DG);
48  * 25-Feb-2004 : Replaced CrosshairInfo with CrosshairState (DG);
49  * 29-Sep-2004 : Removed hard-coded color (DG);
50  * 04-Oct-2004 : Reworked equals() method and renamed ArrayUtils
51  * --> ArrayUtilities (DG);
52  * 12-Nov-2004 : Implemented the new Zoomable interface (DG);
53  * 05-May-2005 : Updated draw() method parameters (DG);
54  *
55  */

56
57 package org.jfree.chart.plot;
58
59 import java.awt.AlphaComposite JavaDoc;
60 import java.awt.BasicStroke JavaDoc;
61 import java.awt.Color JavaDoc;
62 import java.awt.Composite JavaDoc;
63 import java.awt.Graphics2D JavaDoc;
64 import java.awt.Paint JavaDoc;
65 import java.awt.Shape JavaDoc;
66 import java.awt.Stroke JavaDoc;
67 import java.awt.geom.Line2D JavaDoc;
68 import java.awt.geom.Point2D JavaDoc;
69 import java.awt.geom.Rectangle2D JavaDoc;
70 import java.io.IOException JavaDoc;
71 import java.io.ObjectInputStream JavaDoc;
72 import java.io.ObjectOutputStream JavaDoc;
73 import java.io.Serializable JavaDoc;
74 import java.util.Iterator JavaDoc;
75 import java.util.List JavaDoc;
76 import java.util.ResourceBundle JavaDoc;
77
78 import org.jfree.chart.axis.AxisSpace;
79 import org.jfree.chart.axis.AxisState;
80 import org.jfree.chart.axis.ValueAxis;
81 import org.jfree.chart.axis.ValueTick;
82 import org.jfree.chart.event.PlotChangeEvent;
83 import org.jfree.data.Range;
84 import org.jfree.io.SerialUtilities;
85 import org.jfree.ui.RectangleEdge;
86 import org.jfree.ui.RectangleInsets;
87 import org.jfree.util.ArrayUtilities;
88 import org.jfree.util.ObjectUtilities;
89
90 /**
91  * A fast scatter plot.
92  */

93 public class FastScatterPlot extends Plot implements ValueAxisPlot,
94                                                      Zoomable,
95                                                      Cloneable JavaDoc, Serializable JavaDoc {
96
97     /** For serialization. */
98     private static final long serialVersionUID = 7871545897358563521L;
99     
100     /** The default grid line stroke. */
101     public static final Stroke JavaDoc DEFAULT_GRIDLINE_STROKE = new BasicStroke JavaDoc(0.5f,
102             BasicStroke.CAP_BUTT,
103             BasicStroke.JOIN_BEVEL,
104             0.0f,
105             new float[] {2.0f, 2.0f},
106             0.0f);
107
108     /** The default grid line paint. */
109     public static final Paint JavaDoc DEFAULT_GRIDLINE_PAINT = Color.lightGray;
110
111     /** The data. */
112     private float[][] data;
113
114     /** The x data range. */
115     private Range xDataRange;
116
117     /** The y data range. */
118     private Range yDataRange;
119
120     /** The domain axis (used for the x-values). */
121     private ValueAxis domainAxis;
122
123     /** The range axis (used for the y-values). */
124     private ValueAxis rangeAxis;
125
126     /** The paint used to plot data points. */
127     private transient Paint JavaDoc paint;
128
129     /** A flag that controls whether the domain grid-lines are visible. */
130     private boolean domainGridlinesVisible;
131
132     /** The stroke used to draw the domain grid-lines. */
133     private transient Stroke JavaDoc domainGridlineStroke;
134
135     /** The paint used to draw the domain grid-lines. */
136     private transient Paint JavaDoc domainGridlinePaint;
137
138     /** A flag that controls whether the range grid-lines are visible. */
139     private boolean rangeGridlinesVisible;
140
141     /** The stroke used to draw the range grid-lines. */
142     private transient Stroke JavaDoc rangeGridlineStroke;
143
144     /** The paint used to draw the range grid-lines. */
145     private transient Paint JavaDoc rangeGridlinePaint;
146
147     /** The resourceBundle for the localization. */
148     protected static ResourceBundle JavaDoc localizationResources =
149         ResourceBundle.getBundle("org.jfree.chart.plot.LocalizationBundle");
150
151     /**
152      * Creates an empty plot.
153      */

154     public FastScatterPlot() {
155         this(null, null, null);
156     }
157     
158     /**
159      * Creates a new fast scatter plot.
160      * <P>
161      * The data is an array of x, y values: data[0][i] = x, data[1][i] = y.
162      *
163      * @param data the data.
164      * @param domainAxis the domain (x) axis.
165      * @param rangeAxis the range (y) axis.
166      */

167     public FastScatterPlot(float[][] data,
168                            ValueAxis domainAxis, ValueAxis rangeAxis) {
169
170         super();
171
172         this.data = data;
173         this.xDataRange = calculateXDataRange(data);
174         this.yDataRange = calculateYDataRange(data);
175         this.domainAxis = domainAxis;
176         if (domainAxis != null) {
177             domainAxis.setPlot(this);
178             domainAxis.addChangeListener(this);
179         }
180
181         this.rangeAxis = rangeAxis;
182         if (rangeAxis != null) {
183             rangeAxis.setPlot(this);
184             rangeAxis.addChangeListener(this);
185         }
186
187         this.paint = Color.red;
188         
189         this.domainGridlinesVisible = true;
190         this.domainGridlinePaint = FastScatterPlot.DEFAULT_GRIDLINE_PAINT;
191         this.domainGridlineStroke = FastScatterPlot.DEFAULT_GRIDLINE_STROKE;
192
193         this.rangeGridlinesVisible = true;
194         this.rangeGridlinePaint = FastScatterPlot.DEFAULT_GRIDLINE_PAINT;
195         this.rangeGridlineStroke = FastScatterPlot.DEFAULT_GRIDLINE_STROKE;
196     
197     }
198
199     /**
200      * Returns a short string describing the plot type.
201      *
202      * @return A short string describing the plot type.
203      */

204     public String JavaDoc getPlotType() {
205         return localizationResources.getString("Fast_Scatter_Plot");
206     }
207
208     /**
209      * Returns the orientation of the plot.
210      *
211      * @return The orientation (always {@link PlotOrientation#VERTICAL}).
212      */

213     public PlotOrientation getOrientation() {
214         return PlotOrientation.VERTICAL;
215     }
216     
217     /**
218      * Returns the domain axis for the plot. If the domain axis for this plot
219      * is null, then the method will return the parent plot's domain axis (if
220      * there is a parent plot).
221      *
222      * @return The domain axis.
223      */

224     public ValueAxis getDomainAxis() {
225         return this.domainAxis;
226     }
227
228     /**
229      * Returns the range axis for the plot. If the range axis for this plot is
230      * null, then the method will return the parent plot's range axis (if
231      * there is a parent plot).
232      *
233      * @return The range axis.
234      */

235     public ValueAxis getRangeAxis() {
236         return this.rangeAxis;
237     }
238
239     /**
240      * Returns the paint used to plot data points.
241      *
242      * @return The paint.
243      */

244     public Paint JavaDoc getPaint() {
245         return this.paint;
246     }
247
248     /**
249      * Sets the color for the data points and sends a {@link PlotChangeEvent}
250      * to all registered listeners.
251      *
252      * @param paint the paint (<code>null</code> not permitted).
253      */

254     public void setPaint(Paint JavaDoc paint) {
255         if (paint == null) {
256             throw new IllegalArgumentException JavaDoc("Null 'paint' argument.");
257         }
258         this.paint = paint;
259         notifyListeners(new PlotChangeEvent(this));
260     }
261
262     /**
263      * Returns <code>true</code> if the domain gridlines are visible, and
264      * <code>false<code> otherwise.
265      *
266      * @return <code>true</code> or <code>false</code>.
267      */

268     public boolean isDomainGridlinesVisible() {
269         return this.domainGridlinesVisible;
270     }
271
272     /**
273      * Sets the flag that controls whether or not the domain grid-lines are
274      * visible. If the flag value is changed, a {@link PlotChangeEvent} is
275      * sent to all registered listeners.
276      *
277      * @param visible the new value of the flag.
278      */

279     public void setDomainGridlinesVisible(boolean visible) {
280         if (this.domainGridlinesVisible != visible) {
281             this.domainGridlinesVisible = visible;
282             notifyListeners(new PlotChangeEvent(this));
283         }
284     }
285
286     /**
287      * Returns the stroke for the grid-lines (if any) plotted against the
288      * domain axis.
289      *
290      * @return The stroke.
291      */

292     public Stroke JavaDoc getDomainGridlineStroke() {
293         return this.domainGridlineStroke;
294     }
295
296     /**
297      * Sets the stroke for the grid lines plotted against the domain axis.
298      * <p>
299      * If you set this to <code>null</code>, no grid lines will be drawn.
300      *
301      * @param stroke the stroke (<code>null</code> permitted).
302      */

303     public void setDomainGridlineStroke(Stroke JavaDoc stroke) {
304         this.domainGridlineStroke = stroke;
305         notifyListeners(new PlotChangeEvent(this));
306     }
307
308     /**
309      * Returns the paint for the grid lines (if any) plotted against the domain
310      * axis.
311      *
312      * @return The paint.
313      */

314     public Paint JavaDoc getDomainGridlinePaint() {
315         return this.domainGridlinePaint;
316     }
317
318     /**
319      * Sets the paint for the grid lines plotted against the domain axis.
320      * <p>
321      * If you set this to <code>null</code>, no grid lines will be drawn.
322      *
323      * @param paint the paint (<code>null</code> permitted).
324      */

325     public void setDomainGridlinePaint(Paint JavaDoc paint) {
326         this.domainGridlinePaint = paint;
327         notifyListeners(new PlotChangeEvent(this));
328     }
329
330     /**
331      * Returns <code>true</code> if the range axis grid is visible, and
332      * <code>false<code> otherwise.
333      *
334      * @return <code>true</code> or <code>false</code>.
335      */

336     public boolean isRangeGridlinesVisible() {
337         return this.rangeGridlinesVisible;
338     }
339
340     /**
341      * Sets the flag that controls whether or not the range axis grid lines are
342      * visible. If the flag value is changed, a {@link PlotChangeEvent} is
343      * sent to all registered listeners.
344      *
345      * @param visible the new value of the flag.
346      */

347     public void setRangeGridlinesVisible(boolean visible) {
348         if (this.rangeGridlinesVisible != visible) {
349             this.rangeGridlinesVisible = visible;
350             notifyListeners(new PlotChangeEvent(this));
351         }
352     }
353
354     /**
355      * Returns the stroke for the grid lines (if any) plotted against the range
356      * axis.
357      *
358      * @return The stroke.
359      */

360     public Stroke JavaDoc getRangeGridlineStroke() {
361         return this.rangeGridlineStroke;
362     }
363
364     /**
365      * Sets the stroke for the grid lines plotted against the range axis.
366      * <p>
367      * If you set this to <code>null</code>, no grid lines will be drawn.
368      *
369      * @param stroke the stroke (<code>null</code> permitted).
370      */

371     public void setRangeGridlineStroke(Stroke JavaDoc stroke) {
372         this.rangeGridlineStroke = stroke;
373         notifyListeners(new PlotChangeEvent(this));
374     }
375
376     /**
377      * Returns the paint for the grid lines (if any) plotted against the range
378      * axis.
379      *
380      * @return The paint.
381      */

382     public Paint JavaDoc getRangeGridlinePaint() {
383         return this.rangeGridlinePaint;
384     }
385
386     /**
387      * Sets the paint for the grid lines plotted against the range axis.
388      * <p>
389      * If you set this to <code>null</code>, no grid lines will be drawn.
390      *
391      * @param paint the paint (<code>null</code> permitted).
392      */

393     public void setRangeGridlinePaint(Paint JavaDoc paint) {
394         this.rangeGridlinePaint = paint;
395         notifyListeners(new PlotChangeEvent(this));
396     }
397
398     /**
399      * Draws the fast scatter plot on a Java 2D graphics device (such as the
400      * screen or a printer).
401      *
402      * @param g2 the graphics device.
403      * @param area the area within which the plot (including axis labels)
404      * should be drawn.
405      * @param anchor the anchor point (<code>null</code> permitted).
406      * @param parentState the state from the parent plot, if there is one.
407      * @param info collects chart drawing information (<code>null</code>
408      * permitted).
409      */

410     public void draw(Graphics2D JavaDoc g2, Rectangle2D JavaDoc area, Point2D JavaDoc anchor,
411                      PlotState parentState,
412                      PlotRenderingInfo info) {
413
414         // set up info collection...
415
if (info != null) {
416             info.setPlotArea(area);
417         }
418
419         // adjust the drawing area for plot insets (if any)...
420
RectangleInsets insets = getInsets();
421         insets.trim(area);
422
423         AxisSpace space = new AxisSpace();
424         space = this.domainAxis.reserveSpace(
425             g2, this, area, RectangleEdge.BOTTOM, space
426         );
427         space = this.rangeAxis.reserveSpace(
428             g2, this, area, RectangleEdge.LEFT, space
429         );
430         Rectangle2D JavaDoc dataArea = space.shrink(area, null);
431
432         if (info != null) {
433             info.setDataArea(dataArea);
434         }
435
436         // draw the plot background and axes...
437
drawBackground(g2, dataArea);
438
439         AxisState domainAxisState = null;
440         AxisState rangeAxisState = null;
441         if (this.domainAxis != null) {
442             domainAxisState = this.domainAxis.draw(
443                 g2, dataArea.getMaxY(), area, dataArea,
444                 RectangleEdge.BOTTOM, info
445             );
446         }
447         if (this.rangeAxis != null) {
448             rangeAxisState = this.rangeAxis.draw(
449                 g2, dataArea.getMinX(), area, dataArea,
450                 RectangleEdge.LEFT, info
451             );
452         }
453         drawDomainGridlines(g2, dataArea, domainAxisState.getTicks());
454         drawRangeGridlines(g2, dataArea, rangeAxisState.getTicks());
455         
456         Shape JavaDoc originalClip = g2.getClip();
457         Composite JavaDoc originalComposite = g2.getComposite();
458
459         g2.clip(dataArea);
460         g2.setComposite(
461             AlphaComposite.getInstance(
462                 AlphaComposite.SRC_OVER, getForegroundAlpha()
463             )
464         );
465
466         render(g2, dataArea, info, null);
467
468         g2.setClip(originalClip);
469         g2.setComposite(originalComposite);
470         drawOutline(g2, dataArea);
471
472     }
473
474     /**
475      * Draws a representation of the data within the dataArea region. The
476      * <code>info</code> and <code>crosshairState</code> arguments may be
477      * <code>null</code>.
478      *
479      * @param g2 the graphics device.
480      * @param dataArea the region in which the data is to be drawn.
481      * @param info an optional object for collection dimension information.
482      * @param crosshairState collects crosshair information (<code>null</code>
483      * permitted).
484      */

485     public void render(Graphics2D JavaDoc g2, Rectangle2D JavaDoc dataArea,
486                        PlotRenderingInfo info, CrosshairState crosshairState) {
487     
488  
489         //long start = System.currentTimeMillis();
490
//System.out.println("Start: " + start);
491
g2.setPaint(this.paint);
492
493         // if the axes use a linear scale, you can uncomment the code below and
494
// switch to the alternative transX/transY calculation inside the loop
495
// that follows - it is a little bit faster then.
496
//
497
// int xx = (int) dataArea.getMinX();
498
// int ww = (int) dataArea.getWidth();
499
// int yy = (int) dataArea.getMaxY();
500
// int hh = (int) dataArea.getHeight();
501
// double domainMin = this.domainAxis.getLowerBound();
502
// double domainLength = this.domainAxis.getUpperBound() - domainMin;
503
// double rangeMin = this.rangeAxis.getLowerBound();
504
// double rangeLength = this.rangeAxis.getUpperBound() - rangeMin;
505

506         if (this.data != null) {
507             for (int i = 0; i < this.data[0].length; i++) {
508                 float x = this.data[0][i];
509                 float y = this.data[1][i];
510                 
511                 //int transX = (int) (xx + ww * (x - domainMin) / domainLength);
512
//int transY = (int) (yy - hh * (y - rangeMin) / rangeLength);
513
int transX = (int) this.domainAxis.valueToJava2D(
514                     x, dataArea, RectangleEdge.BOTTOM
515                 );
516                 int transY = (int) this.rangeAxis.valueToJava2D(
517                     y, dataArea, RectangleEdge.LEFT
518                 );
519                 g2.fillRect(transX, transY, 1, 1);
520             }
521         }
522         //long finish = System.currentTimeMillis();
523
//System.out.println("Finish: " + finish);
524
//System.out.println("Time: " + (finish - start));
525

526     }
527
528     /**
529      * Draws the gridlines for the plot, if they are visible.
530      *
531      * @param g2 the graphics device.
532      * @param dataArea the data area.
533      * @param ticks the ticks.
534      */

535     protected void drawDomainGridlines(Graphics2D JavaDoc g2, Rectangle2D JavaDoc dataArea,
536                                        List JavaDoc ticks) {
537
538         // draw the domain grid lines, if any...
539
if (isDomainGridlinesVisible()) {
540             Stroke JavaDoc gridStroke = getDomainGridlineStroke();
541             Paint JavaDoc gridPaint = getDomainGridlinePaint();
542             if ((gridStroke != null) && (gridPaint != null)) {
543                 Iterator JavaDoc iterator = ticks.iterator();
544                 while (iterator.hasNext()) {
545                     ValueTick tick = (ValueTick) iterator.next();
546                     double v = this.domainAxis.valueToJava2D(
547                         tick.getValue(), dataArea, RectangleEdge.BOTTOM
548                     );
549                     Line2D JavaDoc line = new Line2D.Double JavaDoc(
550                         v, dataArea.getMinY(), v, dataArea.getMaxY()
551                     );
552                     g2.setPaint(gridPaint);
553                     g2.setStroke(gridStroke);
554                     g2.draw(line);
555                 }
556             }
557         }
558     }
559     
560     /**
561      * Draws the gridlines for the plot, if they are visible.
562      *
563      * @param g2 the graphics device.
564      * @param dataArea the data area.
565      * @param ticks the ticks.
566      */

567     protected void drawRangeGridlines(Graphics2D JavaDoc g2, Rectangle2D JavaDoc dataArea,
568                                       List JavaDoc ticks) {
569
570         // draw the range grid lines, if any...
571
if (isRangeGridlinesVisible()) {
572             Stroke JavaDoc gridStroke = getRangeGridlineStroke();
573             Paint JavaDoc gridPaint = getRangeGridlinePaint();
574             if ((gridStroke != null) && (gridPaint != null)) {
575                 Iterator JavaDoc iterator = ticks.iterator();
576                 while (iterator.hasNext()) {
577                     ValueTick tick = (ValueTick) iterator.next();
578                     double v = this.rangeAxis.valueToJava2D(
579                         tick.getValue(), dataArea, RectangleEdge.LEFT
580                     );
581                     Line2D JavaDoc line = new Line2D.Double JavaDoc(
582                         dataArea.getMinX(), v, dataArea.getMaxX(), v
583                     );
584                     g2.setPaint(gridPaint);
585                     g2.setStroke(gridStroke);
586                     g2.draw(line);
587                 }
588             }
589         }
590
591     }
592
593     /**
594      * Returns the range of data values to be plotted along the axis.
595      *
596      * @param axis the axis.
597      *
598      * @return The range.
599      */

600     public Range getDataRange(ValueAxis axis) {
601
602         Range result = null;
603         if (axis == this.domainAxis) {
604             result = this.xDataRange;
605         }
606         else if (axis == this.rangeAxis) {
607             result = this.yDataRange;
608         }
609         return result;
610     }
611
612     /**
613      * Calculates the X data range.
614      *
615      * @param data the data.
616      *
617      * @return The range.
618      */

619     private Range calculateXDataRange(float[][] data) {
620         
621         Range result = null;
622         
623         if (data != null) {
624             float lowest = Float.POSITIVE_INFINITY;
625             float highest = Float.NEGATIVE_INFINITY;
626             for (int i = 0; i < data[0].length; i++) {
627                 float v = data[0][i];
628                 if (v < lowest) {
629                     lowest = v;
630                 }
631                 if (v > highest) {
632                     highest = v;
633                 }
634             }
635             if (lowest <= highest) {
636                 result = new Range(lowest, highest);
637             }
638         }
639         
640         return result;
641         
642     }
643
644     /**
645      * Calculates the Y data range.
646      *
647      * @param data the data.
648      *
649      * @return The range.
650      */

651     private Range calculateYDataRange(float[][] data) {
652         
653         Range result = null;
654         
655         if (data != null) {
656             float lowest = Float.POSITIVE_INFINITY;
657             float highest = Float.NEGATIVE_INFINITY;
658             for (int i = 0; i < data[0].length; i++) {
659                 float v = data[1][i];
660                 if (v < lowest) {
661                     lowest = v;
662                 }
663                 if (v > highest) {
664                     highest = v;
665                 }
666             }
667             if (lowest <= highest) {
668                 result = new Range(lowest, highest);
669             }
670         }
671         return result;
672         
673     }
674
675     /**
676      * Multiplies the range on the domain axis/axes by the specified factor.
677      *
678      * @param factor the zoom factor.
679      * @param info the plot rendering info.
680      * @param source the source point.
681      */

682     public void zoomDomainAxes(double factor, PlotRenderingInfo info,
683                                Point2D JavaDoc source) {
684         this.domainAxis.resizeRange(factor);
685     }
686
687     /**
688      * Zooms in on the domain axes.
689      *
690      * @param lowerPercent the new lower bound as a percentage of the current
691      * range.
692      * @param upperPercent the new upper bound as a percentage of the current
693      * range.
694      * @param info the plot rendering info.
695      * @param source the source point.
696      */

697     public void zoomDomainAxes(double lowerPercent, double upperPercent,
698                                PlotRenderingInfo info, Point2D JavaDoc source) {
699         this.domainAxis.zoomRange(lowerPercent, upperPercent);
700     }
701
702     /**
703      * Multiplies the range on the range axis/axes by the specified factor.
704      *
705      * @param factor the zoom factor.
706      * @param info the plot rendering info.
707      * @param source the source point.
708      */

709     public void zoomRangeAxes(double factor,
710                               PlotRenderingInfo info, Point2D JavaDoc source) {
711         this.rangeAxis.resizeRange(factor);
712     }
713
714     /**
715      * Zooms in on the range axes.
716      *
717      * @param lowerPercent the new lower bound as a percentage of the current
718      * range.
719      * @param upperPercent the new upper bound as a percentage of the current
720      * range.
721      * @param info the plot rendering info.
722      * @param source the source point.
723      */

724     public void zoomRangeAxes(double lowerPercent, double upperPercent,
725                               PlotRenderingInfo info, Point2D JavaDoc source) {
726         this.rangeAxis.zoomRange(lowerPercent, upperPercent);
727     }
728
729     /**
730      * Returns <code>true</code>.
731      *
732      * @return A boolean.
733      */

734     public boolean isDomainZoomable() {
735         return true;
736     }
737     
738     /**
739      * Returns <code>true</code>.
740      *
741      * @return A boolean.
742      */

743     public boolean isRangeZoomable() {
744         return true;
745     }
746
747     /**
748      * Tests an object for equality with this instance.
749      *
750      * @param obj the object (<code>null</code> permitted).
751      *
752      * @return A boolean.
753      */

754     public boolean equals(Object JavaDoc obj) {
755         
756         if (obj == this) {
757             return true;
758         }
759         if (!super.equals(obj)) {
760             return false;
761         }
762         if (!(obj instanceof FastScatterPlot)) {
763             return false;
764         }
765
766         FastScatterPlot that = (FastScatterPlot) obj;
767         if (!ArrayUtilities.equal(this.data, that.data)) {
768             return false;
769         }
770         if (!ObjectUtilities.equal(this.domainAxis, that.domainAxis)) {
771             return false;
772         }
773         if (!ObjectUtilities.equal(this.rangeAxis, that.rangeAxis)) {
774             return false;
775         }
776         if (!ObjectUtilities.equal(this.paint, that.paint)) {
777             return false;
778         }
779             
780         if (this.domainGridlinesVisible != that.domainGridlinesVisible) {
781             return false;
782         }
783         if (!ObjectUtilities.equal(this.domainGridlinePaint,
784                 that.domainGridlinePaint)) {
785             return false;
786         }
787         if (!ObjectUtilities.equal(this.domainGridlineStroke,
788                 that.domainGridlineStroke)) {
789             return false;
790         }
791             
792         if (!this.rangeGridlinesVisible == that.rangeGridlinesVisible) {
793             return false;
794         }
795         if (!ObjectUtilities.equal(this.rangeGridlinePaint,
796                 that.rangeGridlinePaint)) {
797             return false;
798         }
799         if (!ObjectUtilities.equal(this.rangeGridlineStroke,
800                 that.rangeGridlineStroke)) {
801             return false;
802         }
803                           
804         return true;
805     }
806     
807     /**
808      * Returns a clone of the plot.
809      *
810      * @return A clone.
811      *
812      * @throws CloneNotSupportedException if some component of the plot does
813      * not support cloning.
814      */

815     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
816     
817         FastScatterPlot clone = (FastScatterPlot) super.clone();
818         
819         if (this.data != null) {
820             clone.data = ArrayUtilities.clone(this.data);
821         }
822         
823         if (this.domainAxis != null) {
824             clone.domainAxis = (ValueAxis) this.domainAxis.clone();
825             clone.domainAxis.setPlot(clone);
826             clone.domainAxis.addChangeListener(clone);
827         }
828         
829         if (this.rangeAxis != null) {
830             clone.rangeAxis = (ValueAxis) this.rangeAxis.clone();
831             clone.rangeAxis.setPlot(clone);
832             clone.rangeAxis.addChangeListener(clone);
833         }
834             
835         return clone;
836         
837     }
838
839     /**
840      * Provides serialization support.
841      *
842      * @param stream the output stream.
843      *
844      * @throws IOException if there is an I/O error.
845      */

846     private void writeObject(ObjectOutputStream JavaDoc stream) throws IOException JavaDoc {
847         stream.defaultWriteObject();
848         SerialUtilities.writePaint(this.paint, stream);
849         SerialUtilities.writeStroke(this.domainGridlineStroke, stream);
850         SerialUtilities.writePaint(this.domainGridlinePaint, stream);
851         SerialUtilities.writeStroke(this.rangeGridlineStroke, stream);
852         SerialUtilities.writePaint(this.rangeGridlinePaint, stream);
853     }
854
855     /**
856      * Provides serialization support.
857      *
858      * @param stream the input stream.
859      *
860      * @throws IOException if there is an I/O error.
861      * @throws ClassNotFoundException if there is a classpath problem.
862      */

863     private void readObject(ObjectInputStream JavaDoc stream)
864             throws IOException JavaDoc, ClassNotFoundException JavaDoc {
865         stream.defaultReadObject();
866
867         this.paint = SerialUtilities.readPaint(stream);
868         this.domainGridlineStroke = SerialUtilities.readStroke(stream);
869         this.domainGridlinePaint = SerialUtilities.readPaint(stream);
870
871         this.rangeGridlineStroke = SerialUtilities.readStroke(stream);
872         this.rangeGridlinePaint = SerialUtilities.readPaint(stream);
873
874         if (this.domainAxis != null) {
875             this.domainAxis.addChangeListener(this);
876         }
877
878         if (this.rangeAxis != null) {
879             this.rangeAxis.addChangeListener(this);
880         }
881     }
882     
883 }
884
Popular Tags