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

Last change on this file since 3423 was 3362, checked in by ldelgass, 11 years ago

Merge nanovis2 branch to trunk

  • Property svn:eol-style set to native
File size: 7.9 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2#ifndef AXIS_H
3#define AXIS_H
4
5#include <stdlib.h>
6#include <string.h>
7
8#include <cmath>
9#include <limits>
10
11#include "Chain.h"
12
13#ifndef NAN
14#define NAN (std::numeric_limits<double>::quiet_NaN())
15#endif
16
17class Axis;
18
19class TickIter
20{
21public:
22    void setStartingLink(ChainLink *linkPtr)
23    {
24        _linkPtr = linkPtr;
25    }
26
27    bool next()
28    {
29        if (_linkPtr == NULL) {
30            return false;
31        }
32        _linkPtr = _linkPtr->next();
33        return (_linkPtr != NULL);
34    }
35
36    float getValue()
37    {
38        union {
39            float x;
40            void *clientData;
41        } value;
42        value.clientData = _linkPtr->getValue();
43        return value.x;
44    }
45
46private:
47    ChainLink *_linkPtr;
48};
49
50/**
51 * Class containing information where the ticks (major or
52 * minor) will be displayed on the graph.
53 */
54class Ticks
55{
56public:
57    Ticks(int numTicks) :
58        reqNumTicks(numTicks),
59        _autoscale(true),
60        _numTicks(0),
61        _ticks(NULL)
62    {
63    }
64
65    ~Ticks()
66    {
67        if (_ticks != NULL) {
68            delete [] _ticks;
69        }
70        _chain.reset();
71    }
72
73    void setTicks(float *ticks, int nTicks)
74    {
75        _ticks = ticks, _numTicks = nTicks;
76    }
77
78    int numTicks()
79    {
80        return _numTicks;
81    }
82
83    double tick(int i)
84    {
85        if ((i < 0) || (i >= _numTicks)) {
86            return NAN;
87        }
88        return _ticks[i];
89    }
90
91    void reset()
92    {
93        _chain.reset();
94    }
95
96    float step()
97    {
98        return _step;
99    }
100
101    void append (float x)
102    {
103        _chain.append(getClientData(x));
104    }
105
106    void setValues(double initial, double step, unsigned int nSteps)
107    {
108        _initial = initial, _step = step, _nSteps = nSteps;
109    }
110
111    bool autoscale()
112    {
113        return _autoscale;
114    }
115
116    void sweepTicks()
117    {
118        if (_autoscale) {
119            if (_ticks != NULL) {
120                delete [] _ticks;
121            }
122            setTicks();
123        }
124    }
125
126    bool firstTick(TickIter &iter)
127    {
128        ChainLink *linkPtr;
129
130        linkPtr = _chain.firstLink();
131        iter.setStartingLink(linkPtr);
132        return (linkPtr != NULL);
133    }
134
135    int reqNumTicks;            /**< Default number of ticks to be displayed. */
136
137private:
138    void setTicks();    /**< Routine used internally to create the array
139                                 * of ticks as defined by a given sweep. */
140    void *getClientData(float x)
141    {
142        union {
143            float x;
144            void *clientData;
145        } value;
146        value.x = x;
147        return value.clientData;
148    }
149
150    bool _autoscale;            /**< Indicates if the ticks are autoscaled. */
151    /*
152     * Tick locations may be generated in two fashions
153     */
154    /* 1. an array of values provided by the user. */
155    int _numTicks;              /* # of ticks on axis */
156    float *_ticks;              /* Array of tick values (alloc-ed).  Right now
157                                 * it's a float so we don't have to allocate
158                                 * store for the list of ticks generated.  In
159                                 * the future when we store both the tick
160                                 * label and the value in the list, we may
161                                 * extend this to a double.
162                                 */
163    /*
164     * 2. a defined sweep of initial, step, and nsteps.  This in turn
165     *    will generate the an array of values.
166     */
167    double _initial;            /**< Initial value */
168    double _step;               /**< Size of interval */
169    unsigned int _nSteps;       /**< Number of intervals. */
170
171    /**
172     *This finally generates a list of ticks values that exclude duplicate
173     * minor ticks (that are always represented by major ticks).  In the
174     * future, the string representing the tick label will be stored in
175     * the chain.
176     */
177    Chain _chain;
178};
179
180/**
181 * Class contains options controlling how the axis will be
182 * displayed.
183 */
184class Axis
185{
186public:
187    /// Flags associated with the axis.
188    enum AxisFlags {
189        AUTOSCALE  = (1<<0),
190        DESCENDING = (1<<1),
191        LOGSCALE   = (1<<2),
192        TIGHT_MIN  = (1<<3),
193        TIGHT_MAX  = (1<<4)
194    };
195
196    Axis(const char *name);
197
198    ~Axis()
199    {
200        if (_name != NULL) {
201            free((void *)_name);
202        }
203        if (_units != NULL) {
204            free((void *)_units);
205        }
206        if (_title != NULL) {
207            free((void *)_title);
208        }
209    }
210
211    bool firstMajor(TickIter& iter)
212    {
213        return _major.firstTick(iter);
214    }
215
216    bool firstMinor(TickIter& iter)
217    {
218        return _minor.firstTick(iter);
219    }
220
221    void resetRange();
222
223    void fixRange(double min, double max);
224
225    void setScale(double min, double max);
226
227    double scale() const
228    {
229        return _scale;
230    }
231
232    double range() const
233    {
234        return _range;
235    }
236
237    double dataMin() const
238    {
239        return _valueMin;
240    }
241
242    double dataMax() const
243    {
244        return _valueMax;
245    }
246
247    double min() const
248    {
249        return _min;
250    }
251
252    double max() const
253    {
254        return _max;
255    }
256
257    void setLimits(double min, double max)
258    {
259        _reqMin = min, _reqMax = max;
260    }
261
262    void unsetLimits()
263    {
264        setLimits(NAN, NAN);
265    }
266
267    double map(double x);
268
269    double invMap(double x);
270
271    const char *name()
272    {
273        return _name;
274    }
275
276    void name(const char *name)
277    {
278        if (_name != NULL) {
279            free((void *)_name);
280        }
281        _name = strdup(name);
282    }
283
284    const char *units()
285    {
286        return _units;
287    }
288
289    void units(const char *units)
290    {
291        if (_units != NULL) {
292            free((void *)_units);
293        }
294        _units = strdup(units);
295    }
296
297    const char *title()
298    {
299        return _title;
300    }
301
302    void title(const char *title)
303    {
304        if (_title != NULL) {
305            free((void *)_title);
306        }
307        _title = strdup(title);
308    }
309
310    void setDescendingOption(bool value)
311    {
312        if (value) {
313            _flags |= DESCENDING;
314        } else {
315            _flags &= ~DESCENDING;
316        }
317    }
318
319    void setTightMinOption(bool value)
320    {
321        if (value) {
322            _flags |= TIGHT_MIN;
323        } else {
324            _flags &= ~TIGHT_MIN;
325        }
326    }
327
328    void setTightMaxOption(bool value)
329    {
330        if (value) {
331            _flags |= TIGHT_MAX;
332        } else {
333            _flags &= ~TIGHT_MAX;
334        }
335    }
336
337    void setLogScaleOption(bool value)
338    {
339        if (value) {
340            _flags |= LOGSCALE;
341        } else {
342            _flags &= ~LOGSCALE;
343        }
344    }
345
346    void setMajorStepOption(double value)
347    {
348        _reqStep = value;       // Setting to 0.0 resets step to "auto"
349    }
350
351    void setNumMinorTicksOption(int n)
352    {
353        _minor.reqNumTicks = n;
354    }
355
356    void setNumMajorTicksOption(int n)
357    {
358        _major.reqNumTicks = n;
359    }
360
361private:
362    void logScale();
363
364    void linearScale();
365
366    bool inRange(double x);
367
368    void makeTicks();
369
370    const char *_name;          /**< Name of the axis. Malloc-ed */
371
372    unsigned int _flags;
373
374    const char *_title;         /**< Title of the axis. */
375
376    const char *_units;         /**< Units of the axis. */
377
378    double _valueMin, _valueMax; /**< The limits of the data. */
379
380    double _reqMin, _reqMax;    /**< Requested axis bounds. Consult the
381                                 * axisPtr->flags field for
382                                 * Axis::CONFIG_MIN and Axis::CONFIG_MAX
383                                 * to see if the requested bound have
384                                 * been set.  They override the
385                                 * computed range of the axis
386                                 * (determined by auto-scaling). */
387
388    double _min, _max;          /**< Smallest and largest major tick values for
389                                 * the axis.  If loose, the tick values lie
390                                 * outside the range of data values.  If
391                                 * tight, they lie interior to the limits of
392                                 * the data. */
393
394    double _range;              /**< Range of values on axis (max_ - min_) */
395    double _scale;              /**< Scale factor for axis (1.0/_range) */
396
397    double _reqStep;            /**< If > 0.0, overrides the computed major tick
398                                 * interval.  Otherwise a stepsize is
399                                 * automatically calculated, based upon the
400                                 * range of elements mapped to the axis. The
401                                 * default value is 0.0. */
402
403    Ticks _major, _minor;
404};
405
406#endif
Note: See TracBrowser for help on using the repository browser.