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

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

Include namespace in header guard defines

  • Property svn:eol-style set to native
File size: 8.0 KB
RevLine 
[2798]1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
[3502]2/*
3 * Copyright (c) 2004-2013  HUBzero Foundation, LLC
4 *
5 * Authors: George A. Howlett <gah@purdue.edu>
6 */
[3613]7#ifndef NV_AXIS_H
8#define NV_AXIS_H
[933]9
[2953]10#include <stdlib.h>
[2972]11#include <string.h>
[2953]12
[2871]13#include <cmath>
14#include <limits>
15
[933]16#include "Chain.h"
17
[2871]18#ifndef NAN
19#define NAN (std::numeric_limits<double>::quiet_NaN())
20#endif
21
[3611]22namespace nv {
23
[936]24class Axis;
25
[2871]26class TickIter
[2822]27{
[933]28public:
[2923]29    void setStartingLink(ChainLink *linkPtr)
[2822]30    {
[2871]31        _linkPtr = linkPtr;
32    }
[2822]33
[2923]34    bool next()
[2871]35    {
36        if (_linkPtr == NULL) {
37            return false;
38        }
[2923]39        _linkPtr = _linkPtr->next();
[2871]40        return (_linkPtr != NULL);
[933]41    }
[2822]42
[2923]43    float getValue()
[2822]44    {
[2871]45        union {
46            float x;
47            void *clientData;
48        } value;
[2923]49        value.clientData = _linkPtr->getValue();
[2871]50        return value.x;
[933]51    }
52
[2871]53private:
54    ChainLink *_linkPtr;
[933]55};
56
[2953]57/**
58 * Class containing information where the ticks (major or
59 * minor) will be displayed on the graph.
[933]60 */
[2871]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        }
[2923]77        _chain.reset();
[2871]78    }
79
[2923]80    void setTicks(float *ticks, int nTicks)
[2871]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
[2923]98    void reset()
[2871]99    {
[2923]100        _chain.reset();
[2871]101    }
102
103    float step()
104    {
105        return _step;
106    }
107
[2923]108    void append (float x)
[2871]109    {
[2923]110        _chain.append(getClientData(x));
[2871]111    }
112
[2923]113    void setValues(double initial, double step, unsigned int nSteps)
[2871]114    {
115        _initial = initial, _step = step, _nSteps = nSteps;
116    }
117
118    bool autoscale()
119    {
120        return _autoscale;
121    }
122
[2923]123    void sweepTicks()
[2871]124    {
125        if (_autoscale) {
126            if (_ticks != NULL) {
127                delete [] _ticks;
128            }
[2923]129            setTicks();
[2871]130        }
131    }
132
[2923]133    bool firstTick(TickIter &iter)
[2871]134    {
135        ChainLink *linkPtr;
136
[2923]137        linkPtr = _chain.firstLink();
138        iter.setStartingLink(linkPtr);
[2871]139        return (linkPtr != NULL);
140    }
141
142    int reqNumTicks;            /**< Default number of ticks to be displayed. */
143
144private:
[2923]145    void setTicks();    /**< Routine used internally to create the array
[2871]146                                 * of ticks as defined by a given sweep. */
[2923]147    void *getClientData(float x)
[2871]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. */
[936]158    /*
159     * Tick locations may be generated in two fashions
160     */
[2871]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
[936]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    /*
[2871]171     * 2. a defined sweep of initial, step, and nsteps.  This in turn
172     *    will generate the an array of values.
[936]173     */
[2871]174    double _initial;            /**< Initial value */
175    double _step;               /**< Size of interval */
176    unsigned int _nSteps;       /**< Number of intervals. */
[936]177
[2871]178    /**
[936]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     */
[2871]184    Chain _chain;
185};
[936]186
[2871]187/**
[2953]188 * Class contains options controlling how the axis will be
[2871]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        }
[933]216    }
217
[2953]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
[2923]228    void resetRange();
[936]229
[2923]230    void fixRange(double min, double max);
[2871]231
[2923]232    void setScale(double min, double max);
[2871]233
[2953]234    double scale() const
[2871]235    {
236        return _scale;
[933]237    }
[2871]238
[2953]239    double range() const
[2871]240    {
241        return _range;
[933]242    }
[2871]243
[3362]244    double dataMin() const
[2871]245    {
[3362]246        return _valueMin;
[936]247    }
[2871]248
[3362]249    double dataMax() const
[2871]250    {
[3362]251        return _valueMax;
[933]252    }
[2871]253
[3362]254    double min() const
[2871]255    {
[3362]256        return _min;
[933]257    }
[2871]258
[2953]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    {
[3362]271        setLimits(NAN, NAN);
[2953]272    }
273
[2923]274    double map(double x);
[2871]275
[2923]276    double invMap(double x);
[2871]277
278    const char *name()
279    {
280        return _name;
[936]281    }
[2871]282
283    void name(const char *name)
284    {
285        if (_name != NULL) {
286            free((void *)_name);
287        }
288        _name = strdup(name);
[936]289    }
[2871]290
291    const char *units()
292    {
293        return _units;
[2822]294    }
[2871]295
296    void units(const char *units)
297    {
298        if (_units != NULL) {
299            free((void *)_units);
300        }
301        _units = strdup(units);
[936]302    }
[2871]303
304    const char *title()
305    {
306        return _title;
[936]307    }
[2871]308
309    void title(const char *title)
310    {
311        if (_title != NULL) {
312            free((void *)_title);
313        }
314        _title = strdup(title);
[936]315    }
316
[2923]317    void setDescendingOption(bool value)
[2871]318    {
319        if (value) {
320            _flags |= DESCENDING;
321        } else {
322            _flags &= ~DESCENDING;
323        }
324    }
[1028]325
[2923]326    void setTightMinOption(bool value)
[2871]327    {
328        if (value) {
329            _flags |= TIGHT_MIN;
330        } else {
331            _flags &= ~TIGHT_MIN;
332        }
333    }
[933]334
[2923]335    void setTightMaxOption(bool value)
[2871]336    {
337        if (value) {
338            _flags |= TIGHT_MAX;
339        } else {
340            _flags &= ~TIGHT_MAX;
341        }
342    }
343
[2923]344    void setLogScaleOption(bool value)
[2871]345    {
346        if (value) {
347            _flags |= LOGSCALE;
348        } else {
349            _flags &= ~LOGSCALE;
350        }
351    }
352
[2923]353    void setMajorStepOption(double value)
[2871]354    {
355        _reqStep = value;       // Setting to 0.0 resets step to "auto"
356    }
357
[2923]358    void setNumMinorTicksOption(int n)
[2871]359    {
360        _minor.reqNumTicks = n;
361    }
362
[2923]363    void setNumMajorTicksOption(int n)
[2871]364    {
365        _major.reqNumTicks = n;
366    }
367
368private:
[2923]369    void logScale();
[2871]370
[2923]371    void linearScale();
[2871]372
[2923]373    bool inRange(double x);
[2871]374
[2923]375    void makeTicks();
[2871]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
[933]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
[2871]395    double _min, _max;          /**< Smallest and largest major tick values for
[933]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
[2871]401    double _range;              /**< Range of values on axis (max_ - min_) */
402    double _scale;              /**< Scale factor for axis (1.0/_range) */
[933]403
[2871]404    double _reqStep;            /**< If > 0.0, overrides the computed major tick
[936]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. */
[933]409
[2871]410    Ticks _major, _minor;
[933]411};
412
[3611]413}
414
[2822]415#endif
Note: See TracBrowser for help on using the repository browser.