2
// The original FieldMeter class is Copyright (c) 1994, 2006 by Mike Romberg
3
// ( mike.romberg@noaa.gov )
5
// Modifications from FieldMeter class done in Oct. 1995
6
// by Brian Grayson ( bgrayson@netbsd.org )
8
// Modifications from FieldMeterDecay class done in Oct. 1998
9
// by Scott McNab ( jedi@tartarus.uwa.edu.au )
14
// In order to use the FieldMeterGraph class in place of a FieldMeter class in
15
// a meter file (say, cpumeter.cc), make the following changes:
16
// 1. Change cpumeter.h to include fieldmetergraph.h instead of
18
// 2. Change CPUMeter to inherit from FieldMeterGraph, rather than
20
// 3. Change the constructor call to use FieldMeterGraph(), rather than
22
// 4. Make the meter call FieldMeterGraph::checkResources(),
23
// to pick up graphNumCols resource.
24
// 5. Make the checkResources () function in the meter set the
25
// useGraph_ variable according to the, e.g., xosview*cpuGraph resource.
32
#include <math.h> // For fabs()
34
#include "fieldmeter.h"
35
#include "fieldmetergraph.h"
39
CVSID_DOT_H(FIELDMETERGRAPH_H_CVSID);
41
FieldMeterGraph::FieldMeterGraph( XOSView *parent,
42
int numfields, const char *title,
43
const char *legend, int docaptions, int dolegends,
45
: FieldMeterDecay (parent, numfields, title, legend, docaptions,
46
dolegends, dousedlegends)
53
// set number of columns to a reasonable default in case we can't
59
FieldMeterGraph::~FieldMeterGraph( void )
61
delete [] heightfield_;
64
void FieldMeterGraph::drawfields( int manditory )
70
// Call FieldMeterDecay code if this meter should not be
72
FieldMeterDecay::drawfields( manditory );
79
// allocate memory for height field graph storage
80
// note: this is done here as it is not certain that both
81
// numfields_ and graphNumCols_ are defined in the constructor
82
if( heightfield_ == NULL )
84
if( numfields_ > 0 && graphNumCols_ > 0 )
86
heightfield_ = new float [numfields_*graphNumCols_];
88
for( i = 0; i < graphNumCols_; i++ )
90
for( j = 0; j < numfields_; j++ )
92
if( j < numfields_-1 )
93
heightfield_[i*numfields_+j] = 0.0;
95
heightfield_[i*numfields_+j] = 1.0;
101
// check current position here and slide graph if necessary
102
if( graphpos_ >= graphNumCols_ )
104
for( i = 0; i < graphNumCols_-1; i++ )
106
for( j = 0; j < numfields_; j++ )
108
heightfield_[i*numfields_+j] = heightfield_[(i+1)*numfields_+j];
111
graphpos_ = graphNumCols_ - 1;
114
// get current values to be plotted
115
for( i = 0; i < numfields_; i++ )
117
float a = fields_[i] / total_;
122
heightfield_[graphpos_*numfields_+i] = a;
125
/* For the first time, we need to draw everything, so
126
* skip the optimized copyArea case. Also, if we are
127
* not fully visible, then the copy-area won't work
129
if( !firstTimeDrawn_ && parent_->hasBeenExposedAtLeastOnce() && !parent_->isExposed() && parent_->isFullyVisible() )
132
int col_width = width_/graphNumCols_;
138
int sx = x_ + col_width;
139
int swidth = width_ - col_width;
140
int sheight = height_ + 1;
141
if( sx > x_ && swidth > 0 && sheight > 0 )
142
parent_->copyArea( sx, y_, swidth, sheight, x_, y_ );
143
drawBar( graphNumCols_ - 1 );
145
if (firstTimeDrawn_ &&
146
parent_->isAtLeastPartiallyVisible() &&
147
parent_->hasBeenExposedAtLeastOnce()) {
148
XOSDEBUG("True exposure! %d\n", firstTimeDrawn_);
151
else XOSDEBUG("Full draw: isAtLeastPart %d, hasBeenExposed %d\n",
152
parent_->isAtLeastPartiallyVisible(),
153
parent_->hasBeenExposedAtLeastOnce());
154
// need to draw entire graph on expose event
155
for( i = 0; i < graphNumCols_; i++ ) {
161
parent_->setStippleN(0); // Restore all-bits stipple.
162
if ( dousedlegends_ )
164
drawused( manditory );
167
void FieldMeterGraph::drawBar( int i )
170
int y = y_ + height_;
171
int x = x_ + i*width_/graphNumCols_;
172
int barwidth = (x_ + (i+1)*width_/graphNumCols_)-x;
177
for( j = 0 ; j < numfields_; j++ )
179
/* Round up, by adding 0.5 before
180
* converting to an int. */
181
barheight = (int)((heightfield_[i*numfields_+j]*height_)+0.5);
183
parent_->setForeground( colors_[j] );
184
parent_->setStippleN(j%4);
186
if( barheight > (y-y_) )
189
// hack to ensure last field always reaches top of graph area
190
if( j == numfields_-1 )
195
parent_->drawFilledRectangle( x, y, barwidth, barheight );
199
void FieldMeterGraph::checkResources( void )
201
FieldMeterDecay::checkResources();
203
const char *ptr = parent_->getResource( "graphNumCols" );
207
if( sscanf( ptr, "%d", &i ) == 1 )
216
void FieldMeterGraph::setNumCols( int n )
219
graphpos_ = graphNumCols_-1;
222
delete [] heightfield_;