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

Last change on this file since 2958 was 2953, checked in by ldelgass, 12 years ago

Remove unused global origin, make default transfer function a bit more
sensible (used to have full opacity at 0). Fix HeightMap? dtor to use delete[]
instead of free() on array allocated with new[]. Document data response in
protocol.

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