source: nanovis/branches/1.2/Axis.h

Last change on this file was 5542, checked in by ldelgass, 9 years ago

Merge r5478,r5480 from nanovis trunk (grid refactoring)

  • Property svn:eol-style set to native
File size: 5.9 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:
6 *   George A. Howlett <gah@purdue.edu>
7 *   Leif Delgass <ldelgass@purdue.edu>
8 */
9#ifndef NV_AXIS_H
10#define NV_AXIS_H
11
12#include <cmath>
13#include <limits>
14#include <list>
15#include <string>
16#include <cstdlib>
17#include <cstring>
18
19#ifndef NAN
20#define NAN (std::numeric_limits<double>::quiet_NaN())
21#endif
22
23namespace nv {
24
25class Axis;
26
27/**
28 * Class containing information where the ticks (major or
29 * minor) will be displayed on the graph.
30 */
31class Ticks
32{
33public:
34    typedef std::list<double>::iterator Iterator;
35    typedef std::list<double>::const_iterator ConstIterator;
36
37    Ticks(int numTicks) :
38        reqNumTicks(numTicks),
39        _numTicks(0),
40        _ticks(NULL)
41    {
42    }
43
44    ~Ticks()
45    {
46        if (_ticks != NULL) {
47            delete [] _ticks;
48        }
49    }
50
51    int numTicks() const
52    {
53        return _numTicks;
54    }
55
56    double tick(int i)
57    {
58        if ((i < 0) || (i >= _numTicks)) {
59            return NAN;
60        }
61        return _ticks[i];
62    }
63
64    void reset()
65    {
66        _chain.clear();
67    }
68
69    float step() const
70    {
71        return _step;
72    }
73
74    void append(float x)
75    {
76        _chain.push_back(x);
77    }
78
79    void setValues(double initial, double step, unsigned int nSteps)
80    {
81        _initial = initial, _step = step, _nSteps = nSteps;
82    }
83
84    void sweepTicks()
85    {
86        if (_ticks != NULL) {
87            delete [] _ticks;
88        }
89        setTicks();
90    }
91
92    ConstIterator begin() const
93    {
94        return _chain.begin();
95    }
96
97    ConstIterator end() const
98    {
99        return _chain.end();
100    }
101
102    int reqNumTicks;            /**< Default number of ticks to be displayed. */
103
104private:
105    void setTicks();    /**< Routine used internally to create the array
106                         * of ticks as defined by a given sweep. */
107
108    /*
109     * Tick locations may be generated in two fashions
110     */
111    /* 1. an array of values provided by the user. */
112    int _numTicks;              /* # of ticks on axis */
113    float *_ticks;              /* Array of tick values (alloc-ed).  Right now
114                                 * it's a float so we don't have to allocate
115                                 * store for the list of ticks generated.  In
116                                 * the future when we store both the tick
117                                 * label and the value in the list, we may
118                                 * extend this to a double.
119                                 */
120    /*
121     * 2. a defined sweep of initial, step, and nsteps.  This in turn
122     *    will generate the an array of values.
123     */
124    double _initial;            /**< Initial value */
125    double _step;               /**< Size of interval */
126    unsigned int _nSteps;       /**< Number of intervals. */
127
128    /**
129     *This finally generates a list of ticks values that exclude duplicate
130     * minor ticks (that are always represented by major ticks).  In the
131     * future, the string representing the tick label will be stored in
132     * the chain.
133     */
134    std::list<double> _chain;
135};
136
137/**
138 * Class contains options controlling how the axis will be
139 * displayed.
140 */
141class Axis
142{
143public:
144    Axis(const char *title);
145
146    ~Axis()
147    {
148    }
149
150    Ticks::ConstIterator firstMajor() const
151    {
152        return _major.begin();
153    }
154    Ticks::ConstIterator lastMajor() const
155    {
156        return _major.end();
157    }
158    Ticks::ConstIterator firstMinor() const
159    {
160        return _minor.begin();
161    }
162    Ticks::ConstIterator lastMinor() const
163    {
164        return _minor.end();
165    }
166
167    /**
168     * This returns the minimum bound of the data, which may
169     * be different than the min() of the axis because of
170     * tight/loose placement of major ticks
171     */
172    double dataMin() const
173    {
174        return _valueMin;
175    }
176
177    /**
178     * This returns the maximum bound of the data, which may
179     * be different than the min() of the axis because of
180     * tight/loose placement of major ticks
181     */
182    double dataMax() const
183    {
184        return _valueMax;
185    }
186
187    /**
188     * The minimum bound of the axis
189     */
190    double min() const
191    {
192        return _min;
193    }
194
195    /**
196     * The maximum bound of the axis
197     */
198    double max() const
199    {
200        return _max;
201    }
202
203    /**
204     * The length of the axis
205     */
206    double length() const
207    {
208        return (_max - _min);
209    }
210
211    void setRange(double min, double max);
212
213    double map(double x);
214
215    double invMap(double x);
216
217    const char *title() const
218    {
219        return _title.c_str();
220    }
221
222    void title(const char *title)
223    {
224        _title = title;
225    }
226
227    const char *units() const
228    {
229        return _units.c_str();
230    }
231
232    void units(const char *units)
233    {
234        _units = units;
235    }
236
237    void setTightMin(bool value)
238    {
239        _tightMin = value;
240    }
241
242    void setTightMax(bool value)
243    {
244        _tightMax = value;
245    }
246
247    void setMajorStep(double value)
248    {
249        // Setting to 0.0 resets step to "auto"
250        _reqStep = value;
251    }
252
253    void setNumMajorTicks(int n)
254    {
255        _major.reqNumTicks = n;
256    }
257
258    void setNumMinorTicks(int n)
259    {
260        _minor.reqNumTicks = n;
261    }
262
263private:
264    void resetRange();
265
266    void fixRange(double min, double max);
267
268    void linearScale();
269
270    bool inRange(double x);
271
272    void makeTicks();
273
274    std::string _title;         /**< Title of the axis */
275    std::string _units;         /**< Units of the axis */
276
277    bool _tightMin, _tightMax;  /**< Tight bounds option flags */
278
279    double _reqStep;            /**< If > 0.0, overrides the computed major tick
280                                 * interval.  Otherwise a stepsize is
281                                 * automatically calculated, based upon the
282                                 * range of elements mapped to the axis. The
283                                 * default value is 0.0. */
284
285    double _valueMin, _valueMax; /**< The limits of the data */
286    double _min, _max;          /**< Smallest and largest major tick values for
287                                 * the axis.  If loose, the tick values lie
288                                 * outside the range of data values.  If
289                                 * tight, they lie interior to the limits of
290                                 * the data. */
291
292    Ticks _major, _minor;
293};
294
295}
296
297#endif
Note: See TracBrowser for help on using the repository browser.