INET Framework for OMNeT++/OMNEST
ThermometerFigure Class Reference

#include <ThermometerFigure.h>

Inheritance diagram for ThermometerFigure:
inet::IIndicatorFigure

Public Member Functions

 ThermometerFigure (const char *name=nullptr)
 
virtual ~ThermometerFigure ()
 
virtual void setValue (int series, simtime_t timestamp, double value) override
 
const Rectangle & getBounds () const
 
void setBounds (const Rectangle &rect)
 
const ColorgetMercuryColor () const
 
void setMercuryColor (const Color &color)
 
const char * getLabel () const
 
void setLabel (const char *text)
 
const int getLabelOffset () const
 
void setLabelOffset (int offset)
 
const Font & getLabelFont () const
 
void setLabelFont (const Font &font)
 
const ColorgetLabelColor () const
 
void setLabelColor (const Color &color)
 
double getMinValue () const
 
void setMinValue (double value)
 
double getMaxValue () const
 
void setMaxValue (double value)
 
double getTickSize () const
 
void setTickSize (double value)
 
- Public Member Functions inherited from inet::IIndicatorFigure
virtual ~IIndicatorFigure ()
 
virtual int getNumSeries () const
 
virtual void refreshDisplay ()
 

Protected Member Functions

virtual void parse (cProperty *property) override
 
virtual const char ** getAllowedPropertyKeys () const override
 
void addChildren ()
 
void getContainerGeometry (double &x, double &y, double &width, double &height, double &offset)
 
void setTickGeometry (cLineFigure *tick, int index)
 
void setNumberGeometry (cTextFigure *number, int index)
 
void setMercuryAndContainerGeometry ()
 
void redrawTicks ()
 
void layout ()
 
void refresh ()
 

Protected Attributes

cFigure::Rectangle bounds
 
cPathFigure * mercuryFigure
 
cPathFigure * containerFigure
 
cTextFigure * labelFigure
 
std::vector< cLineFigure * > tickFigures
 
std::vector< cTextFigure * > numberFigures
 
double min = 0
 
double max = 100
 
double tickSize = 10
 
double value = NaN
 
int numTicks = 0
 
double shifting = 0
 
int labelOffset = 10
 

Constructor & Destructor Documentation

ThermometerFigure::ThermometerFigure ( const char *  name = nullptr)
50  : cGroupFigure(name)
51 {
52  addChildren();
53 }
void addChildren()
Definition: ThermometerFigure.cc:217
ThermometerFigure::~ThermometerFigure ( )
virtual
56 {
57  // delete figures which is not in canvas
58  for (int i = numTicks; i < tickFigures.size(); ++i) {
59  delete tickFigures[i];
60  delete numberFigures[i];
61  }
62 }
int numTicks
Definition: ThermometerFigure.h:41
std::vector< cLineFigure * > tickFigures
Definition: ThermometerFigure.h:35
std::vector< cTextFigure * > numberFigures
Definition: ThermometerFigure.h:36

Member Function Documentation

void ThermometerFigure::addChildren ( )
protected

Referenced by ThermometerFigure().

218 {
219  mercuryFigure = new cPathFigure("mercury");
220  containerFigure = new cPathFigure("container");
221  labelFigure = new cTextFigure("label");
222 
223  mercuryFigure->setFilled(true);
224  mercuryFigure->setFillColor("darkorange");
225  mercuryFigure->setLineOpacity(0);
226 
227  labelFigure->setAnchor(cFigure::ANCHOR_N);
228 
229  addFigure(mercuryFigure);
230  addFigure(containerFigure);
231  addFigure(labelFigure);
232 }
cPathFigure * containerFigure
Definition: ThermometerFigure.h:33
cPathFigure * mercuryFigure
Definition: ThermometerFigure.h:32
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
const char ** ThermometerFigure::getAllowedPropertyKeys ( ) const
overrideprotectedvirtual
204 {
205  static const char *keys[32];
206  if (!keys[0]) {
207  const char *localKeys[] = {
208  PKEY_MERCURY_COLOR, PKEY_LABEL, PKEY_LABEL_FONT,
209  PKEY_LABEL_COLOR, PKEY_MIN_VALUE, PKEY_MAX_VALUE, PKEY_TICK_SIZE,
210  PKEY_INITIAL_VALUE, PKEY_POS, PKEY_SIZE, PKEY_ANCHOR, PKEY_BOUNDS, PKEY_LABEL_OFFSET, nullptr
211  };
212  concatArrays(keys, cGroupFigure::getAllowedPropertyKeys(), localKeys);
213  }
214  return keys;
215 }
std::vector< K > keys(const std::map< K, V > &m)
Definition: stlutils.h:96
const cFigure::Rectangle & ThermometerFigure::getBounds ( ) const

Referenced by getContainerGeometry(), layout(), parse(), setLabelOffset(), setMercuryAndContainerGeometry(), setNumberGeometry(), and setTickGeometry().

65 {
66  return bounds;
67 }
cFigure::Rectangle bounds
Definition: ThermometerFigure.h:31
void ThermometerFigure::getContainerGeometry ( double &  x,
double &  y,
double &  width,
double &  height,
double &  offset 
)
protected

Referenced by setMercuryAndContainerGeometry(), setNumberGeometry(), and setTickGeometry().

261 {
262  x = getBounds().x + getBounds().width * CONTAINER_POS_PERCENT;
263  y = getBounds().y + getBounds().width * CONTAINER_POS_PERCENT;
264  width = getBounds().width * CONTAINER_WIDTH_PERCENT;
265  offset = getBounds().height * CONTAINER_OFFSET_PERCENT;
266  height = getBounds().height - width * (1 + 2 * CONTAINER_POS_PERCENT) - getBounds().width * CONTAINER_POS_PERCENT - offset;
267 }
const Rectangle & getBounds() const
Definition: ThermometerFigure.cc:64
const char * ThermometerFigure::getLabel ( ) const
86 {
87  return labelFigure->getText();
88 }
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
const cFigure::Color & ThermometerFigure::getLabelColor ( ) const
118 {
119  return labelFigure->getColor();
120 }
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
const cFigure::Font & ThermometerFigure::getLabelFont ( ) const
108 {
109  return labelFigure->getFont();
110 }
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
const int ThermometerFigure::getLabelOffset ( ) const
96 {
97  return labelOffset;
98 }
int labelOffset
Definition: ThermometerFigure.h:43
double ThermometerFigure::getMaxValue ( ) const
142 {
143  return max;
144 }
double max
Definition: ThermometerFigure.h:38
const cFigure::Color & ThermometerFigure::getMercuryColor ( ) const
76 {
77  return mercuryFigure->getLineColor();
78 }
cPathFigure * mercuryFigure
Definition: ThermometerFigure.h:32
double ThermometerFigure::getMinValue ( ) const
128 {
129  return min;
130 }
double min
Definition: ThermometerFigure.h:37
double ThermometerFigure::getTickSize ( ) const
156 {
157  return tickSize;
158 }
double tickSize
Definition: ThermometerFigure.h:39
void ThermometerFigure::layout ( )
protected

Referenced by setBounds().

386 {
388 
389  for (int i = 0; i < numTicks; ++i) {
392  }
393 
394  labelFigure->setPosition(Point(getBounds().getCenter().x, getBounds().y + getBounds().height + labelOffset));
395 }
void setNumberGeometry(cTextFigure *number, int index)
Definition: ThermometerFigure.cc:269
int numTicks
Definition: ThermometerFigure.h:41
std::vector< cLineFigure * > tickFigures
Definition: ThermometerFigure.h:35
std::vector< cTextFigure * > numberFigures
Definition: ThermometerFigure.h:36
int labelOffset
Definition: ThermometerFigure.h:43
void setMercuryAndContainerGeometry()
Definition: ThermometerFigure.cc:287
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
const Rectangle & getBounds() const
Definition: ThermometerFigure.cc:64
void setTickGeometry(cLineFigure *tick, int index)
Definition: ThermometerFigure.cc:244
void ThermometerFigure::parse ( cProperty *  property)
overrideprotectedvirtual
170 {
171  cGroupFigure::parse(property);
172 
173 
174  setBounds(parseBounds(property, getBounds()));
175 
176 
177  // Set default
178  redrawTicks();
179 
180 
181  const char *s;
182  if ((s = property->getValue(PKEY_MERCURY_COLOR)) != nullptr)
183  setMercuryColor(parseColor(s));
184  if ((s = property->getValue(PKEY_LABEL)) != nullptr)
185  setLabel(s);
186  if ((s = property->getValue(PKEY_LABEL_OFFSET)) != nullptr)
187  setLabelOffset(atoi(s));
188  if ((s = property->getValue(PKEY_LABEL_FONT)) != nullptr)
189  setLabelFont(parseFont(s));
190  if ((s = property->getValue(PKEY_LABEL_COLOR)) != nullptr)
191  setLabelColor(parseColor(s));
192  // This must be initialized before min and max, because it is possible to have too many unnecessary ticks
193  if ((s = property->getValue(PKEY_TICK_SIZE)) != nullptr)
195  if ((s = property->getValue(PKEY_MIN_VALUE)) != nullptr)
197  if ((s = property->getValue(PKEY_MAX_VALUE)) != nullptr)
199  if ((s = property->getValue(PKEY_INITIAL_VALUE)) != nullptr)
200  setValue(0, simTime(), utils::atod(s));
201 }
void setLabelOffset(int offset)
Definition: ThermometerFigure.cc:99
virtual void setValue(int series, simtime_t timestamp, double value) override
Definition: ThermometerFigure.cc:234
void setLabel(const char *text)
Definition: ThermometerFigure.cc:90
void setBounds(const Rectangle &rect)
Definition: ThermometerFigure.cc:69
double atod(const char *s)
Converts string to double.
Definition: INETUtils.cc:38
void setLabelColor(const Color &color)
Definition: ThermometerFigure.cc:122
void setTickSize(double value)
Definition: ThermometerFigure.cc:160
void setMinValue(double value)
Definition: ThermometerFigure.cc:132
void redrawTicks()
Definition: ThermometerFigure.cc:335
void setLabelFont(const Font &font)
Definition: ThermometerFigure.cc:112
void setMaxValue(double value)
Definition: ThermometerFigure.cc:146
value< double, units::s > s
Definition: Units.h:1049
const Rectangle & getBounds() const
Definition: ThermometerFigure.cc:64
void setMercuryColor(const Color &color)
Definition: ThermometerFigure.cc:80
void ThermometerFigure::redrawTicks ( )
protected

Referenced by parse(), setMaxValue(), setMinValue(), and setTickSize().

336 {
337  ASSERT(tickFigures.size() == numberFigures.size());
338 
339  double fraction = std::abs(fmod(min / tickSize, 1));
340  shifting = tickSize * (min < 0 ? fraction : 1 - fraction);
341  // if fraction == 0 then shifting == tickSize therefore don't have to shift the ticks
342  if (shifting == tickSize)
343  shifting = 0;
344 
345  int prevNumTicks = numTicks;
346  numTicks = std::max(0.0, std::abs(max - min - shifting) / tickSize + 1);
347 
348  // Allocate ticks and numbers if needed
349  if (numTicks > tickFigures.size()) {
350  while (numTicks > tickFigures.size()) {
351  cLineFigure *tick = new cLineFigure();
352  cTextFigure *number = new cTextFigure();
353 
354  number->setAnchor(cFigure::ANCHOR_W);
355 
356  tickFigures.push_back(tick);
357  numberFigures.push_back(number);
358  }
359  }
360 
361  // Add or remove figures from canvas according to previous number of ticks
362  for (int i = numTicks; i < prevNumTicks; ++i) {
363  removeFigure(tickFigures[i]);
364  removeFigure(numberFigures[i]);
365  }
366  for (int i = prevNumTicks; i < numTicks; ++i) {
367  addFigure(tickFigures[i]);
368  addFigure(numberFigures[i]);
369  }
370 
371  for (int i = 0; i < numTicks; ++i) {
373 
374  double number = min + i * tickSize + shifting;
375  if (std::abs(number) < tickSize / 2)
376  number = 0;
377 
378  char buf[32];
379  sprintf(buf, "%g", number);
380  numberFigures[i]->setText(buf);
382  }
383 }
double min
Definition: ThermometerFigure.h:37
double tickSize
Definition: ThermometerFigure.h:39
double max(double a, double b)
Returns the greater of the given parameters.
Definition: INETMath.h:161
void setNumberGeometry(cTextFigure *number, int index)
Definition: ThermometerFigure.cc:269
int numTicks
Definition: ThermometerFigure.h:41
double shifting
Definition: ThermometerFigure.h:42
double max
Definition: ThermometerFigure.h:38
std::vector< cLineFigure * > tickFigures
Definition: ThermometerFigure.h:35
std::vector< cTextFigure * > numberFigures
Definition: ThermometerFigure.h:36
void setTickGeometry(cLineFigure *tick, int index)
Definition: ThermometerFigure.cc:244
void ThermometerFigure::refresh ( )
protected

Referenced by setMaxValue(), setMinValue(), setTickSize(), and setValue().

398 {
400 }
void setMercuryAndContainerGeometry()
Definition: ThermometerFigure.cc:287
void ThermometerFigure::setBounds ( const Rectangle &  rect)

Referenced by parse().

70 {
71  bounds = rect;
72  layout();
73 }
cFigure::Rectangle bounds
Definition: ThermometerFigure.h:31
void layout()
Definition: ThermometerFigure.cc:385
void ThermometerFigure::setLabel ( const char *  text)

Referenced by parse().

91 {
92  labelFigure->setText(text);
93 }
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
void ThermometerFigure::setLabelColor ( const Color color)

Referenced by parse().

123 {
124  labelFigure->setColor(color);
125 }
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
void ThermometerFigure::setLabelFont ( const Font &  font)

Referenced by parse().

113 {
114  labelFigure->setFont(font);
115 }
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
void ThermometerFigure::setLabelOffset ( int  offset)

Referenced by parse().

100 {
101  if(labelOffset != offset) {
102  labelOffset = offset;
103  labelFigure->setPosition(Point(getBounds().getCenter().x, getBounds().y + getBounds().height + labelOffset));
104  }
105 }
int labelOffset
Definition: ThermometerFigure.h:43
cTextFigure * labelFigure
Definition: ThermometerFigure.h:34
const Rectangle & getBounds() const
Definition: ThermometerFigure.cc:64
void ThermometerFigure::setMaxValue ( double  value)

Referenced by parse().

147 {
148  if (max != value) {
149  max = value;
150  redrawTicks();
151  refresh();
152  }
153 }
double value
Definition: ThermometerFigure.h:40
double max
Definition: ThermometerFigure.h:38
void redrawTicks()
Definition: ThermometerFigure.cc:335
void refresh()
Definition: ThermometerFigure.cc:397
void ThermometerFigure::setMercuryAndContainerGeometry ( )
protected

Referenced by layout(), and refresh().

288 {
289  containerFigure->clearPath();
290  mercuryFigure->clearPath();
291 
292  containerFigure->setLineWidth(getBounds().width * CONTAINER_LINE_WIDTH_PERCENT);
293 
294  double x, y, width, height, offset;
295  getContainerGeometry(x, y, width, height, offset);
296 
297  containerFigure->addMoveTo(x, y);
298  containerFigure->addLineRel(0, height + 2 * offset);
299  //TODO this does not work with Qtenv:
300  //containerFigure->addCubicBezierCurveRel(0, width, width, width, width, 0);
301  containerFigure->addArcRel(width / 2, width / 2, 0, true, false, width, 0);
302  containerFigure->addLineRel(0, -height - 2 * offset);
303  containerFigure->addArcRel(width / 2, width / 2, 0, true, false, -width, 0);
304 
305  double mercuryLevel;
306  double overflow = 0;
307  if (std::isnan(value))
308  return;
309  else if (value < min) {
310  mercuryFigure->addMoveTo(x, y + 2 * offset + height);
311  mercuryFigure->addArcRel(width / 2, width / 2, 0, true, false, width, 0);
312  mercuryFigure->addClosePath();
313  return;
314  }
315  else if (value > max) {
316  mercuryLevel = 1;
317  // value < max so the mercury will be overflow
318  overflow = 2 * offset;
319  offset = 0;
320  }
321  else
322  mercuryLevel = (value - min) / (max - min);
323 
324  mercuryFigure->addMoveTo(x, y + offset + height * (1 - mercuryLevel));
325  mercuryFigure->addLineRel(0, height * mercuryLevel + overflow + offset);
326  //TODO this does not work with Qtenv:
327  //mercuryFigure->addCubicBezierCurveRel(0, width, width, width, width, 0);
328  mercuryFigure->addArcRel(width / 2, width / 2, 0, true, false, width, 0);
329  mercuryFigure->addLineRel(0, -height * mercuryLevel - overflow - offset);
330  if (overflow > 0)
331  mercuryFigure->addArcRel(width / 2, width / 2, 0, true, false, -width, 0);
332  mercuryFigure->addClosePath();
333 }
double value
Definition: ThermometerFigure.h:40
double min
Definition: ThermometerFigure.h:37
cPathFigure * containerFigure
Definition: ThermometerFigure.h:33
double max
Definition: ThermometerFigure.h:38
void getContainerGeometry(double &x, double &y, double &width, double &height, double &offset)
Definition: ThermometerFigure.cc:260
cPathFigure * mercuryFigure
Definition: ThermometerFigure.h:32
const Rectangle & getBounds() const
Definition: ThermometerFigure.cc:64
void ThermometerFigure::setMercuryColor ( const Color color)

Referenced by parse().

81 {
82  mercuryFigure->setFillColor(color);
83 }
cPathFigure * mercuryFigure
Definition: ThermometerFigure.h:32
void ThermometerFigure::setMinValue ( double  value)

Referenced by parse().

133 {
134  if (min != value) {
135  min = value;
136  redrawTicks();
137  refresh();
138  }
139 }
double value
Definition: ThermometerFigure.h:40
double min
Definition: ThermometerFigure.h:37
void redrawTicks()
Definition: ThermometerFigure.cc:335
void refresh()
Definition: ThermometerFigure.cc:397
void ThermometerFigure::setNumberGeometry ( cTextFigure *  number,
int  index 
)
protected

Referenced by layout(), and redrawTicks().

270 {
271  if (numTicks - 1 == 0)
272  return;
273 
274  double x, y, width, height, offset;
275  getContainerGeometry(x, y, width, height, offset);
276 
277  double lineWidth = getBounds().height * TICK_LINE_WIDTH_PERCENT;
278  x += width + lineWidth + getBounds().width * TICK_LENGTH_PERCENT;
279  y += offset + height - height * (index * tickSize + shifting) / (max - min);
280 
281  double pointSize = getBounds().height * FONT_SIZE_PERCENT;
282 
283  number->setPosition(Point(x + pointSize * NUMBER_DISTANCE_FROM_TICK_PERCENT, y));
284  number->setFont(cFigure::Font("", pointSize, 0));
285 }
double min
Definition: ThermometerFigure.h:37
double tickSize
Definition: ThermometerFigure.h:39
int numTicks
Definition: ThermometerFigure.h:41
double shifting
Definition: ThermometerFigure.h:42
double max
Definition: ThermometerFigure.h:38
void getContainerGeometry(double &x, double &y, double &width, double &height, double &offset)
Definition: ThermometerFigure.cc:260
const Rectangle & getBounds() const
Definition: ThermometerFigure.cc:64
void ThermometerFigure::setTickGeometry ( cLineFigure *  tick,
int  index 
)
protected

Referenced by layout(), and redrawTicks().

245 {
246  if (numTicks - 1 == 0)
247  return;
248 
249  double x, y, width, height, offset;
250  getContainerGeometry(x, y, width, height, offset);
251 
252  double lineWidth = getBounds().height * TICK_LINE_WIDTH_PERCENT / 2;
253  x += width + lineWidth;
254  y += offset + height - height * (index * tickSize + shifting) / (max - min);
255  tick->setStart(Point(x, y));
256  tick->setEnd(Point(x + getBounds().width * TICK_LENGTH_PERCENT, y));
257  tick->setLineWidth(lineWidth);
258 }
double min
Definition: ThermometerFigure.h:37
double tickSize
Definition: ThermometerFigure.h:39
int numTicks
Definition: ThermometerFigure.h:41
double shifting
Definition: ThermometerFigure.h:42
double max
Definition: ThermometerFigure.h:38
void getContainerGeometry(double &x, double &y, double &width, double &height, double &offset)
Definition: ThermometerFigure.cc:260
const Rectangle & getBounds() const
Definition: ThermometerFigure.cc:64
void ThermometerFigure::setTickSize ( double  value)

Referenced by parse().

161 {
162  if (tickSize != value) {
163  tickSize = value;
164  redrawTicks();
165  refresh();
166  }
167 }
double value
Definition: ThermometerFigure.h:40
double tickSize
Definition: ThermometerFigure.h:39
void redrawTicks()
Definition: ThermometerFigure.cc:335
void refresh()
Definition: ThermometerFigure.cc:397
void ThermometerFigure::setValue ( int  series,
simtime_t  timestamp,
double  value 
)
overridevirtual

Implements inet::IIndicatorFigure.

Referenced by parse().

235 {
236  ASSERT(series == 0);
237  // Note: we currently ignore timestamp
238  if (value != newValue) {
239  value = newValue;
240  refresh();
241  }
242 }
double value
Definition: ThermometerFigure.h:40
void refresh()
Definition: ThermometerFigure.cc:397

Member Data Documentation

cFigure::Rectangle ThermometerFigure::bounds
protected

Referenced by getBounds(), and setBounds().

cPathFigure* ThermometerFigure::containerFigure
protected
cTextFigure* ThermometerFigure::labelFigure
protected
int ThermometerFigure::labelOffset = 10
protected
double ThermometerFigure::max = 100
protected
cPathFigure* ThermometerFigure::mercuryFigure
protected
double ThermometerFigure::min = 0
protected
std::vector<cTextFigure *> ThermometerFigure::numberFigures
protected
int ThermometerFigure::numTicks = 0
protected
double ThermometerFigure::shifting = 0
protected
std::vector<cLineFigure *> ThermometerFigure::tickFigures
protected
double ThermometerFigure::tickSize = 10
protected
double ThermometerFigure::value = NaN
protected

The documentation for this class was generated from the following files: