source: nanovis/tags/1.1.2/Axis.h @ 4988

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

Add basic VTK structured points reader to nanovis, update copyright dates.

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