source: trunk/packages/vizservers/nanovis/Axis.h @ 1109

Last change on this file since 1109 was 1028, checked in by gah, 16 years ago

various cleanups

File size: 7.6 KB
Line 
1#ifndef _AXIS_H
2#define _AXIS_H
3
4#include "Chain.h"
5
6class Axis;
7
8class NaN {
9private:
10    double _x;
11public:
12    NaN(void) {
13        union DoubleValue {
14            unsigned int words[2];
15            double value;
16        } result;
17       
18#ifdef WORDS_BIGENDIAN
19        result.words[0] = 0x7ff80000;
20        result.words[1] = 0x00000000;
21#else
22        result.words[0] = 0x00000000;
23        result.words[1] = 0x7ff80000;
24#endif
25        _x = result.value;
26    }
27    operator const double() {
28        return _x;
29    }
30};
31
32extern NaN _NaN;
33
34class TickIter {
35    ChainLink *_linkPtr;
36public:
37    void SetStartingLink(ChainLink *linkPtr) {
38        _linkPtr = linkPtr;
39    }
40    bool Next(void) {
41        if (_linkPtr == NULL) {
42            return false;
43        }
44        _linkPtr = _linkPtr->Next();
45        return (_linkPtr != NULL);
46    }
47    float GetValue(void) {
48        union {
49            float x;
50            void *clientData;
51        } value;
52        value.clientData = _linkPtr->GetValue();
53        return value.x;
54    }
55};
56
57/*
58 * ----------------------------------------------------------------------
59 *
60 * Ticks --
61 *
62 *      Structure containing information where the ticks (major or
63 *      minor) will be displayed on the graph.
64 *
65 * ----------------------------------------------------------------------
66 */
67class Ticks {
68    bool _autoscale;            /* Indicates if the ticks are autoscaled. */
69    /*
70     * Tick locations may be generated in two fashions
71     */
72    /*   1. an array of values provided by the user. */
73    int _nTicks;                /* # of ticks on axis */
74    float *_ticks;              /* Array of tick values (alloc-ed).  Right now
75                                 * it's a float so we don't have to allocate
76                                 * store for the list of ticks generated.  In
77                                 * the future when we store both the tick
78                                 * label and the value in the list, we may
79                                 * extend this to a double.
80                                 */
81    /*
82     *   2. a defined sweep of initial, step, and nsteps.  This in turn
83     *      will generate the an array of values.
84     */
85    double _initial;            /* Initial value */
86    double _step;               /* Size of interval */
87    unsigned int _nSteps;       /* Number of intervals. */
88
89    /*
90     *This finally generates a list of ticks values that exclude duplicate
91     * minor ticks (that are always represented by major ticks).  In the
92     * future, the string representing the tick label will be stored in
93     * the chain.
94     */
95    Chain _chain;               
96
97    void SetTicks(void);        /* Routine used internally to create the array
98                                 * of ticks as defined by a given sweep. */
99    void *GetClientData(float x) {
100        union {
101            float x;
102            void *clientData;
103        } value;
104        value.x = x;
105        return value.clientData;
106    }
107
108public:
109    int reqNumTicks;            /* Default number of ticks to be displayed. */
110
111    Ticks(int numTicks) {
112        reqNumTicks = numTicks;
113        _ticks = NULL;
114        _nTicks = 0;
115        _autoscale = true;
116    }
117    ~Ticks(void) {
118        if (_ticks != NULL) {
119            delete [] _ticks;
120        }
121        _chain.Reset();
122       
123    }
124    void SetTicks(float *ticks, int nTicks) {
125        _ticks = ticks, _nTicks = nTicks;
126    }
127    int NumTicks(void) {
128        return _nTicks;
129    }
130    double GetTick(int i) {
131        if ((i < 0) || (i >= _nTicks)) {
132            return _NaN;
133        }
134        return _ticks[i];
135    }
136    void Reset(void) {
137        _chain.Reset();
138    }
139    float Step() {
140        return _step;
141    }
142    void Append (float x) {
143        _chain.Append(GetClientData(x));
144    }   
145    void SetValues(double initial, double step, unsigned int nSteps) {
146        _initial = initial, _step = step, _nSteps = nSteps;
147    }
148    bool IsAutoScale(void) {
149        return _autoscale;
150    }
151    void SweepTicks(void) {
152        if (_autoscale) {
153            if (_ticks != NULL) {
154                delete [] _ticks;
155            }
156            SetTicks();
157        }
158    }
159    bool FirstTick(TickIter &iter) {
160        ChainLink *linkPtr;
161
162        linkPtr = _chain.FirstLink();
163        iter.SetStartingLink(linkPtr);
164        return (linkPtr != NULL);
165    }
166};
167
168
169/*
170 * ----------------------------------------------------------------------
171 *
172 * Axis --
173 *
174 *      Structure contains options controlling how the axis will be
175 *      displayed.
176 *
177 * ----------------------------------------------------------------------
178 */
179class Axis {
180    /* Flags associated with the axis. */
181    enum AxisFlags {
182        AUTOSCALE=(1<<0),
183        DESCENDING=(1<<1),
184        LOGSCALE=(1<<2),
185        TIGHT_MIN=(1<<3),
186        TIGHT_MAX=(1<<4)
187    };
188
189    const char *_name;          /* Name of the axis. Malloc-ed */
190
191    unsigned int _flags;
192
193    const char *_title;         /* Title of the axis. */
194
195    const char *_units;         /* Units of the axis. */
196
197    double _valueMin, _valueMax; /* The limits of the data. */
198
199    double _reqMin, _reqMax;    /* Requested axis bounds. Consult the
200                                 * axisPtr->flags field for
201                                 * Axis::CONFIG_MIN and Axis::CONFIG_MAX
202                                 * to see if the requested bound have
203                                 * been set.  They override the
204                                 * computed range of the axis
205                                 * (determined by auto-scaling). */
206
207    double _min, _max;          /* Smallest and largest major tick values for
208                                 * the axis.  If loose, the tick values lie
209                                 * outside the range of data values.  If
210                                 * tight, they lie interior to the limits of
211                                 * the data. */
212
213    double _range;              /* Range of values on axis (_max - _min) */
214    double _scale;              /* Scale factor for axis (1.0/_range) */
215
216    double _reqStep;            /* If > 0.0, overrides the computed major tick
217                                 * interval.  Otherwise a stepsize is
218                                 * automatically calculated, based upon the
219                                 * range of elements mapped to the axis. The
220                                 * default value is 0.0. */
221
222    Ticks _major, _minor;
223
224    void LogScale(void);
225    void LinearScale(void);
226    bool InRange(double x);
227    void MakeTicks(void);
228
229public:
230    Axis(const char *name);
231    ~Axis(void) {
232        if (_name != NULL) {
233            free((void *)_name);
234        }
235        if (_units != NULL) {
236            free((void *)_units);
237        }
238        if (_title != NULL) {
239            free((void *)_title);
240        }
241    }
242
243    void ResetRange(void);
244    void FixRange(double min, double max);
245    void SetScale(double min, double max);
246    double Scale(void) {
247        return _scale;
248    }
249    double Range(void) {
250        return _range;
251    }
252    bool FirstMajor(TickIter &iter) {
253        return _major.FirstTick(iter);
254    }
255    bool FirstMinor(TickIter &iter) {
256        return _minor.FirstTick(iter);
257    }
258    void GetDataLimits(double &min, double &max) {
259        min = _valueMin, max = _valueMax;
260    }
261    double Map(double x);
262    double InvMap(double x);
263    const char *GetName(void) {
264        return (_name == NULL) ? "???" : _name;
265    }
266    void SetName(const char *name) {
267        if (_name != NULL) {
268            free((void *)_name);
269        }
270        _name = strdup(name);
271    }
272    const char *GetUnits(void) {
273        return (_units == NULL) ? "???" : _units;
274    }
275    void SetUnits(const char *units) {
276        if (_units != NULL) {
277            free((void *)_units);
278        }
279        _units = strdup(units);
280    }
281    const char *GetTitle(void) {
282        return (_title == NULL) ? "???" : _title;
283    }
284    void SetTitle(const char *title) {
285        if (_title != NULL) {
286            free((void *)_title);
287        }
288        _title = strdup(title);
289    }
290    void SetMin(double min) {
291        _reqMin = min;          // Setting to NaN resets min to "auto"
292    }
293    void SetMax(double min) {
294        _reqMin = min;          // Setting to NaN resets max to "auto"
295    }
296    void SetLimits(double min, double max) {
297        SetMin(min), SetMax(max);
298    }
299    void UnsetLimits() {
300        SetMin(_NaN), SetMax(_NaN);
301    }
302    void SetDescendingOption(bool value) {
303        if (value) {
304            _flags |= DESCENDING;
305        } else {
306            _flags &= ~DESCENDING;
307        }
308    }
309    void SetTightMinOption(bool value) {
310        if (value) {
311            _flags |= TIGHT_MIN;
312        } else {
313            _flags &= ~TIGHT_MIN;
314        }
315    }
316    void SetTightMaxOption(bool value) {
317        if (value) {
318            _flags |= TIGHT_MAX;
319        } else {
320            _flags &= ~TIGHT_MAX;
321        }
322    }
323    void SetLogScaleOption(bool value) {
324        if (value) {
325            _flags |= LOGSCALE;
326        } else {
327            _flags &= ~LOGSCALE;
328        }
329    }
330    void SetMajorStepOption(double value) {
331        _reqStep = value;       // Setting to 0.0 resets step to "auto"
332    }
333    void SetNumMinorTicksOption(int n) {
334        _minor.reqNumTicks = n;
335    }
336    void SetNumMajorTicksOption(int n) {
337        _major.reqNumTicks = n;
338    }
339};
340
341#endif /*_AXIS_H*/
Note: See TracBrowser for help on using the repository browser.