source: nanovis/branches/1.1/Axis.h @ 4904

Last change on this file since 4904 was 4904, checked in by ldelgass, 4 years ago

Merge serveral changes from trunk. Does not include threading, world space
changes, etc.

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