source: ether_statistics/service/implementation/gov/noaa/pmel/sgt/Graph.java @ 569

Last change on this file since 569 was 569, checked in by vmipsl, 12 years ago

Nouveau projet

File size: 8.8 KB
Line 
1/*
2 * $Id: Graph.java,v 1.12 2003/08/22 23:02:32 dwd Exp $
3 *
4 * This software is provided by NOAA for full, free and open release.  It is
5 * understood by the recipient/user that NOAA assumes no liability for any
6 * errors contained in the code.  Although this software is released without
7 * conditions or restrictions in its use, it is expected that appropriate
8 * credit be given to its author and to the National Oceanic and Atmospheric
9 * Administration should the software be included by the recipient as an
10 * element in other product development.
11 */
12package gov.noaa.pmel.sgt;
13
14import gov.noaa.pmel.sgt.dm.SGTData;
15import gov.noaa.pmel.util.Range2D;
16import gov.noaa.pmel.util.SoTRange;
17import gov.noaa.pmel.util.SoTValue;
18
19import java.awt.*;
20import java.beans.PropertyChangeListener;
21
22/**
23 * Abstract base class for all graphics drawn on a <code>Layer</code>.  The
24 * <code>Graph</code> class defines the interfaces for the user to physical
25 * coordinate, user to device, and physical to user coordinate systems.
26 * <p/>
27 * The following demonstrates how a {@link CartesianGraph} may be
28 * used.
29 * <p/>
30 * <pre>
31 *   // Create a CartesianGraph and transforms.
32 *
33 *    CartesianGraph graph;
34 *    LinearTransform xt, yt;
35 *    Range2D xPhysRange, xUserRange;
36 *    Range2D yPhysRange, yUserRange;
37 *    Point2D.Double origin;
38 *
39 *    graph = new CartesianGraph("Point Graph");
40 *    layer.setGraph(graph);
41 *    xt = new LinearTransform(xPhysRange, xUserRange);
42 *    yt = new LinearTransform(yPhysRange, yUserRange);
43 *    graph.setXTransform(xt);
44 *    graph.setYTransform(yt);
45 *    origin = new Point2D.Double(xUserRange.start,
46 *                                yUserRange.start);
47 *
48 *     // Create the bottom axis, set its range in user units
49 *     // and its origin. Add the axis to the graph.
50 *
51 *    PlainAxis xbot;
52 *
53 *    xbot = new PlainAxis("Botton Axis");
54 *    xbot.setRangeU(xUserRange);
55 *    xbot.setLocationU(origin);
56 *    graph.addXAxis(xbot);
57 *
58 *     // Create the left axis, set its range in user units
59 *     // and its origin. Add the axis to the graph.
60 *
61 *    PlainAxis yleft;
62 *
63 *    yleft = new PlainAxis("Left Axis");
64 *    yleft.setRangeU(yUserRange);
65 *    yleft.setLocationU(origin);
66 *    graph.addYAxis(yleft);
67 *
68 *     // Create a PointAttribute for the display of the
69 *     // Collection of points. The points will be marked
70 *     // with a red triangle and labelled at the NE corner
71 *     // in blue.
72 *
73 *    PointAttribute pattr;
74 *
75 *    pattr = new PointAttribute(10, Color.red);
76 *
77 *     // Associate the attribute and the point Collection
78 *     // with the graph.
79 *
80 *    graph.setData(col, pattr);
81 * </pre>
82 *
83 * @author Donald Denbo
84 * @version $Revision: 1.12 $, $Date: 2003/08/22 23:02:32 $
85 * @see Layer
86 * @see LinearTransform
87 * @see PlainAxis
88 * @see SGLabel
89 * @see CartesianGraph
90 * @since 1.0
91 */
92public abstract class Graph
93        implements PropertyChangeListener
94{
95    private String ident_;
96    /**
97     * @directed
98     * @label layer
99     */
100    protected Layer layer_;
101
102    /**
103     * Default constructor.
104     */
105    public Graph()
106    {
107        this( "" );
108    }
109
110    /**
111     * Constructor for <code>Graph</code> class.
112     *
113     * @param id identifier
114     */
115    public Graph( String id )
116    {
117        ident_ = id;
118    }
119
120    /**
121     * Copy the <code>Graph</code> object and all attached classes.
122     */
123    public abstract Graph copy();
124
125    /**
126     * Get the <code>Graph</code> identifier
127     *
128     * @return ident
129     */
130    public String getId()
131    {
132        return ident_;
133    }
134
135    //
136    abstract void draw( Graphics g );
137
138    //
139    void setLayer( Layer l )
140    {
141        layer_ = l;
142    }
143
144    /**
145     * Get the associated <code>Layer</code>.
146     *
147     * @return <code>Layer</code> object
148     */
149    public Layer getLayer()
150    {
151        return layer_;
152    }
153
154    /**
155     * Return parent pane.
156     *
157     * @since 2.0
158     */
159    public AbstractPane getPane()
160    {
161        return layer_.getPane();
162    }
163
164    /**
165     * Used internally by sgt.
166     *
167     * @since 2.0
168     */
169    public void modified( String mess )
170    {
171        if( layer_ != null )
172            layer_.modified( mess );
173    }
174
175    /**
176     * Compute a "nice" range from a range and number of intervals.
177     *
178     * @param range min and max values
179     * @param num   number of intervals
180     * @return "nice" range
181     */
182    public static Range2D computeRange( Range2D range, int num )
183    {
184        return computeRange( range.start, range.end, num );
185    }
186
187    /**
188     * Compute a "nice" range from a range and number of intervals.
189     *
190     * @param range min and max values
191     * @param num   number of intervals
192     * @return "nice" range
193     * @since 2.0
194     */
195    public static SoTRange computeRange( SoTRange range, int num )
196    {
197        if( !range.isTime() )
198        {
199            SoTRange.Double drange = (SoTRange.Double) range;
200            return new SoTRange.Double( computeRange( drange.start,
201                    drange.end, num ) );
202        }
203        return null;
204    }
205
206    /**
207     * VMIPSL
208     * Compute a time range when the start and the end are similar
209     *
210     * @param timeRange
211     * @param num
212     * @return
213     */
214    public static SoTRange computeTimeRange( final SoTRange timeRange, final int num )
215    {
216        if( timeRange.isTime() )
217        {
218            final SoTValue soTValueStart = timeRange.getStart();
219            final SoTValue soTValueEnd = timeRange.getEnd();
220            ( (SoTValue.Time) soTValueStart ).setValue( timeRange.getStart().getLongTime() - num );
221            ( (SoTValue.Time) soTValueEnd ).setValue( timeRange.getEnd().getLongTime() + num );
222            return new SoTRange.Time( soTValueStart.getLongTime(), soTValueEnd.getLongTime() );
223        }
224        return null;
225    }
226
227    /**
228     * Compute a "nice" range from the minimum, maximum, and number of intervals.
229     *
230     * @param min minimum value
231     * @param max maximum value
232     * @param num number of intervals
233     * @return "nice" range
234     */
235    public static Range2D computeRange( double min, double max, int num )
236    {
237        int interval = Math.abs( num );
238        double temp, pow, delta;
239        int nt;
240        boolean reversed = false;
241        //
242        // check inputs to make sure that they are valid
243        //
244        if( min == max )
245        {
246            if( min == 0.0 )
247            {
248                min = -1.0;
249                max = 1.0;
250            }
251            else
252            {
253                min = 0.9 * max;
254                max = 1.1 * max;
255            }
256        }
257        if( min > max )
258        {
259            temp = min;
260            min = max;
261            max = temp;
262            reversed = true;
263        }
264        if( interval == 0 ) interval = 1;
265        //
266        // find the approximate size of the interval
267        //
268        temp = ( max - min ) / (double) interval;
269        if( temp == 0.0 ) temp = max;
270        if( temp == 0.0 )
271        {
272            min = -1.0;
273            max = 1.0;
274            temp = 2.0 / (double) interval;
275        }
276        //
277        // scale the interval size by powers of ten to a value between
278        // one and ten
279        //
280        nt = (int) log10( temp );
281        if( temp < 1.0 ) nt--;
282        pow = Math.pow( 10.0, (double) nt );
283        temp = temp / pow;
284        //
285        // find the closest permissible value for the interval size
286        //
287        if( temp < 1.414213562 )
288        {
289            delta = pow;
290        }
291        else if( temp < 3.162277660 )
292        {
293            delta = 2.0 * pow;
294        }
295        else if( temp < 7.071067812 )
296        {
297            delta = 5.0 * pow;
298        }
299        else
300        {
301            delta = 10.0 * pow;
302        }
303        //
304        // calculate the minimum value of the range
305        //
306        temp = min / delta;
307        nt = (int) temp;
308        if( temp < 0.0 ) nt--;
309        min = delta * nt;
310        //
311        // calculate the maximum value of the range
312        //
313        temp = max / delta;
314        nt = (int) temp;
315        if( temp > 0.0 ) nt++;
316        max = delta * nt;
317        //
318        if( reversed )
319        {
320            temp = min;
321            min = max;
322            max = temp;
323            delta = -delta;
324        }
325        return new Range2D( min, max, delta );
326    }
327
328    static final double log10( double x )
329    {
330        return 0.4342944819 * Math.log( x );
331    }
332
333    //
334    abstract Object getObjectAt( Point pt );
335
336    /**
337     * Get a <code>String</code> representation of the
338     * <code>Graph</code>.
339     *
340     * @return <code>String</code> representation
341     */
342    public String toString()
343    {
344        String name = getClass().getName();
345        return name.substring( name.lastIndexOf( "." ) + 1 ) + ": " + ident_;
346    }
347
348    /**
349     * Find data at a <code>Point</code>
350     *
351     * @since 3.0
352     */
353    public abstract SGTData getDataAt( Point pt );
354}
355
356
357
Note: See TracBrowser for help on using the repository browser.