Eclipse SUMO - Simulation of Urban MObility
GUIParameterTracker.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
20// A window which displays the time line of one (or more) value(s)
21/****************************************************************************/
22#include <config.h>
23
24#include <string>
25#include <fstream>
41#include "GUIParameterTracker.h"
42
43
44// ===========================================================================
45// FOX callback mapping
46// ===========================================================================
47FXDEFMAP(GUIParameterTracker) GUIParameterTrackerMap[] = {
48 FXMAPFUNC(SEL_CONFIGURE, 0, GUIParameterTracker::onConfigure),
49 FXMAPFUNC(SEL_PAINT, 0, GUIParameterTracker::onPaint),
50 FXMAPFUNC(SEL_COMMAND, MID_SIMSTEP, GUIParameterTracker::onSimStep),
54
55};
56
57// Macro for the GLTestApp class hierarchy implementation
58FXIMPLEMENT(GUIParameterTracker, FXMainWindow, GUIParameterTrackerMap, ARRAYNUMBER(GUIParameterTrackerMap))
59
60// ===========================================================================
61// static value definitions
62// ===========================================================================
63std::set<GUIParameterTracker*> GUIParameterTracker::myMultiPlots;
64std::vector<RGBColor> GUIParameterTracker::myColors;
65
66
67// ===========================================================================
68// method definitions
69// ===========================================================================
71 const std::string& name)
72 : FXMainWindow(app.getApp(), "Tracker", nullptr, nullptr, DECOR_ALL, 20, 20, 300, 200),
73 myApplication(&app) {
75 app.addChild(this);
76 FXVerticalFrame* glcanvasFrame = new FXVerticalFrame(this, FRAME_SUNKEN | LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
77 myPanel = new GUIParameterTrackerPanel(glcanvasFrame, *myApplication, *this);
78 setTitle(name.c_str());
80
81 if (myColors.size() == 0) {
83
84 }
85}
86
87
89 myMultiPlots.erase(this);
91 for (std::vector<TrackerValueDesc*>::iterator i1 = myTracked.begin(); i1 != myTracked.end(); i1++) {
92 delete (*i1);
93 }
94 // deleted by GUINet
95 for (std::vector<GLObjectValuePassConnector<double>*>::iterator i2 = myValuePassers.begin(); i2 != myValuePassers.end(); i2++) {
96 delete (*i2);
97 }
98 delete myToolBarDrag;
99 delete myToolBar;
100}
101
102
103void
105 FXMainWindow::create();
106 myToolBarDrag->create();
107}
108
109
110void
112 myToolBarDrag = new FXToolBarShell(this, GUIDesignToolBar);
113 myToolBar = new FXToolBar(this, myToolBarDrag, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | FRAME_RAISED);
114 new FXToolBarGrip(myToolBar, myToolBar, FXToolBar::ID_TOOLBARGRIP, GUIDesignToolBarGrip);
115 // save button
116 new FXButton(myToolBar, "\t\tSave the data...",
118
119 // aggregation interval combo
121 new FXComboBox(myToolBar, 8, this, MID_AGGREGATIONINTERVAL,
123 myAggregationInterval->appendItem("1s");
124 myAggregationInterval->appendItem("1min");
125 myAggregationInterval->appendItem("5min");
126 myAggregationInterval->appendItem("15min");
127 myAggregationInterval->appendItem("30min");
128 myAggregationInterval->appendItem("60min");
129 myAggregationInterval->setNumVisible(6);
130
131 myMultiPlot = new FXCheckButton(myToolBar, TL("Multiplot"), this, MID_MULTIPLOT);
132 myMultiPlot->setCheck(false);
133}
134
135
136bool
138 bool first = true;
140 if (first) {
141 first = false;
142 } else {
143 // each Tracker gets its own copy to simplify cleanup
144 newTracked = new TrackerValueDesc(newTracked->getName(), RGBColor::BLACK, newTracked->getRecordingBegin(),
145 STEPS2TIME(newTracked->getAggregationSpan()));
146 src = src->copy();
147 }
148 tr->addTracked(o, src, newTracked);
149 }
150 return myMultiPlots.size() > 0;
151}
152
153
154void
156 TrackerValueDesc* newTracked) {
157 myTracked.push_back(newTracked);
158 // build connection (is automatically set into an execution map)
159 myValuePassers.push_back(new GLObjectValuePassConnector<double>(o, src, newTracked));
160 update();
161}
162
163
164long
165GUIParameterTracker::onConfigure(FXObject* sender, FXSelector sel, void* ptr) {
166 myPanel->onConfigure(sender, sel, ptr);
167 return FXMainWindow::onConfigure(sender, sel, ptr);
168}
169
170
171long
172GUIParameterTracker::onPaint(FXObject* sender, FXSelector sel, void* ptr) {
173 myPanel->onPaint(sender, sel, ptr);
174 return FXMainWindow::onPaint(sender, sel, ptr);
175}
176
177
178long
179GUIParameterTracker::onSimStep(FXObject*, FXSelector, void*) {
180 update();
181 return 1;
182}
183
184long
185GUIParameterTracker::onCmdChangeAggregation(FXObject*, FXSelector, void*) {
186 int index = myAggregationInterval->getCurrentItem();
187 int aggInt = 0;
188 switch (index) {
189 case 0:
190 aggInt = 1;
191 break;
192 case 1:
193 aggInt = 60;
194 break;
195 case 2:
196 aggInt = 60 * 5;
197 break;
198 case 3:
199 aggInt = 60 * 15;
200 break;
201 case 4:
202 aggInt = 60 * 30;
203 break;
204 case 5:
205 aggInt = 60 * 60;
206 break;
207 default:
208 throw 1;
209 }
210 for (TrackerValueDesc* const tvd : myTracked) {
211 tvd->setAggregationSpan(TIME2STEPS(aggInt));
212 }
213 return 1;
214}
215
216
217long
218GUIParameterTracker::onCmdSave(FXObject*, FXSelector, void*) {
219 FXString file = MFXUtils::getFilename2Write(this, TL("Save Data"), ".csv", GUIIconSubSys::getIcon(GUIIcon::EMPTY), gCurrentFolder);
220 if (file == "") {
221 return 1;
222 }
223 try {
224 OutputDevice& dev = OutputDevice::getDevice(file.text());
225 // write header
226 std::vector<TrackerValueDesc*>::iterator i;
227 dev << "# Time";
228 for (i = myTracked.begin(); i != myTracked.end(); ++i) {
229 TrackerValueDesc* tvd = *i;
230 dev << ';' << tvd->getName();
231 }
232 dev << '\n';
233 // count entries
234 int max = 0;
235 for (i = myTracked.begin(); i != myTracked.end(); ++i) {
236 TrackerValueDesc* tvd = *i;
237 int sizei = (int)tvd->getAggregatedValues().size();
238 if (max < sizei) {
239 max = sizei;
240 }
241 tvd->unlockValues();
242 }
243 // write entries
244 SUMOTime t = myTracked.empty() ? 0 : myTracked.front()->getRecordingBegin();
245 SUMOTime dt = myTracked.empty() ? DELTA_T : myTracked.front()->getAggregationSpan();
246 for (int j = 0; j < max; j++) {
247 dev << time2string(t);
248 for (i = myTracked.begin(); i != myTracked.end(); ++i) {
249 TrackerValueDesc* tvd = *i;
250 dev << ';' << tvd->getAggregatedValues()[j];
251 tvd->unlockValues();
252 }
253 dev << '\n';
254 t += dt;
255 }
256 dev.close();
257 } catch (IOError& e) {
258 FXMessageBox::error(this, MBOX_OK, TL("Storing failed!"), "%s", e.what());
259 }
260 return 1;
261}
262
263
264long
265GUIParameterTracker::onMultiPlot(FXObject*, FXSelector, void*) {
266 if (myMultiPlot->getCheck()) {
267 myMultiPlots.insert(this);
268 } else {
269 myMultiPlots.erase(this);
270 }
271 return 1;
272}
273
274/* -------------------------------------------------------------------------
275 * GUIParameterTracker::GUIParameterTrackerPanel-methods
276 * ----------------------------------------------------------------------- */
281
282};
283
284// Macro for the GLTestApp class hierarchy implementation
285FXIMPLEMENT(GUIParameterTracker::GUIParameterTrackerPanel, FXGLCanvas, GUIParameterTrackerPanelMap, ARRAYNUMBER(GUIParameterTrackerPanelMap))
286
287
288
290 FXComposite* c, GUIMainWindow& app,
291 GUIParameterTracker& parent)
292 : FXGLCanvas(c, app.getGLVisual(), app.getBuildGLCanvas(), (FXObject*) nullptr, (FXSelector) 0, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 300, 200),
293 myParent(&parent) {}
294
295
297
298
299void
301 glMatrixMode(GL_PROJECTION);
302 glLoadIdentity();
303 glMatrixMode(GL_MODELVIEW);
304 glLoadIdentity();
305 glDisable(GL_TEXTURE_2D);
306 for (int i = 0; i < (int)myParent->myTracked.size(); i++) {
307 TrackerValueDesc* desc = myParent->myTracked[i];
308 glPushMatrix();
309 drawValue(*desc, myColors[i % myColors.size()], i);
310 glPopMatrix();
311 }
312}
313
314
315void
317 const RGBColor& col,
318 int index) {
319 const double fontWidth = 0.1 * 300. / myWidthInPixels;
320 const double fontHeight = 0.1 * 300. / myHeightInPixels;
321 const bool isMultiPlot = myParent->myTracked.size() > 1;
322 const std::vector<double>& values = desc.getAggregatedValues();
323 if (values.size() < 2) {
324 // draw name
325 glTranslated(-.9, 0.9, 0);
326 GLHelper::drawText(desc.getName(), Position((double)index / (double)myParent->myTracked.size(), 0.), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
327 desc.unlockValues();
328 return;
329 }
330 //
331 // apply scaling
333
334 // apply the positiopn offset of the display
335 glScaled(0.8, 0.8, 1);
336 // apply value range scaling
337 double ys = (double) 2.0 / (double) desc.getRange();
338 glScaled(1.0, ys, 1.0);
339 glTranslated(-1.0, -desc.getYCenter(), 0);
340
341 // draw value bounderies
342 // draw minimum boundary
343 glBegin(GL_LINES);
344 glVertex2d(0, desc.getMin());
345 glVertex2d(2.0, desc.getMin());
346 glEnd();
347 glBegin(GL_LINES);
348 glVertex2d(0, desc.getMax());
349 glVertex2d(2.0, desc.getMax());
350 glEnd();
352 for (int a = 1; a < 6; a++) {
353 const double yp = desc.getRange() / 6.0 * (double) a + desc.getMin();
354 glBegin(GL_LINES);
355 glVertex2d(0, yp);
356 glVertex2d(2.0, yp);
357 glEnd();
358 }
359
360 double latest = 0;
361 double mx = (2 * myMouseX / myWidthInPixels - 1) / 0.8 + 1;
362 int mIndex = 0;
363 double mouseValue = std::numeric_limits<double>::max();
364 latest = values.back();
365 // init values
366 const double xStep = 2.0 / (double) values.size();
367 std::vector<double>::const_iterator i = values.begin();
368 double yp = (*i);
369 double xp = 0;
370 i++;
372 for (; i != values.end(); i++) {
373 double yn = (*i);
374 double xn = xp + xStep;
375 if (xp < mx && mx < xn) {
376 mouseValue = yp;
377 mIndex = (int)(i - values.begin()) - 1;
378 glPushMatrix();
379 GLHelper::setColor(isMultiPlot ? col.changedBrightness(-40).changedAlpha(-100) : RGBColor::BLUE);
380 glTranslated(xn, yn, 0);
381 glScaled(20.0 / myWidthInPixels, 10.0 * desc.getRange() / myHeightInPixels, 0);
384 glPopMatrix();
385 }
386 glBegin(GL_LINES);
387 glVertex2d(xp, yp);
388 glVertex2d(xn, yn);
389 glEnd();
390 yp = yn;
391 xp = xn;
392 }
393 desc.unlockValues();
395
396 // draw value bounderies and descriptions
398
399 // draw min time
400 SUMOTime beginStep = desc.getRecordingBegin();
401 std::string begStr = time2string(beginStep);
402 double w = 50 / myWidthInPixels;
403 glTranslated(-0.8 - w / 2., -0.88, 0);
404 GLHelper::drawText(begStr, Position(0, 0), 1, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
405 glTranslated(0.8 + w / 2., 0.88, 0);
406
407 // draw max time
408 glTranslated(0.75, -0.88, 0);
409 GLHelper::drawText(time2string(beginStep + static_cast<SUMOTime>(values.size() * desc.getAggregationSpan())),
410 Position(0, 0), 1, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
411 glTranslated(-0.75, 0.88, 0);
412
413 // draw min value
414 glTranslated(-0.98, -0.82, 0);
415 GLHelper::drawText(toString(desc.getMin()), Position(0, index * fontHeight), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
416 glTranslated(0.98, 0.82, 0);
417
418 // draw max value
419 glTranslated(-0.98, 0.78, 0);
420 GLHelper::drawText(toString(desc.getMax()), Position(0, -index * fontHeight), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
421 glTranslated(0.98, -0.78, 0);
422
423 // draw name
424 glTranslated(-0.98, .92, 0);
425 GLHelper::drawText(desc.getName(), Position((double)index / (double)myParent->myTracked.size(), 0.), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
426 glTranslated(0.98, -.92, 0);
427
428 // draw current value (with contrasting color)
429 double p = (double) 0.8 -
430 ((double) 1.6 / (desc.getMax() - desc.getMin()) * (latest - desc.getMin()));
431 glTranslated(-0.98, -(p + .02), 0);
432 GLHelper::drawText(toString(latest), Position(isMultiPlot ? 0.1 : 0, 0), 1, fontHeight, isMultiPlot ? col.changedBrightness(50) : RGBColor::RED, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
433 glTranslated(0.98, p + .02, 0);
434
435 // draw moused value
436 if (mouseValue != std::numeric_limits<double>::max()) {
437 p = (double) 0.8 -
438 ((double) 1.6 / (desc.getMax() - desc.getMin()) * (mouseValue - desc.getMin()));
439 glTranslated(-0.98, -(p + .02), 0);
440 GLHelper::drawText(toString(mouseValue), Position(isMultiPlot ? 0.1 : 0, 0), 1, fontHeight, isMultiPlot ? col.changedBrightness(-40) : RGBColor::BLUE, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
441 glTranslated(0.98, p + .02, 0);
442
443 if (index == 0) {
444 // time is the same for all plots so we only draw it once
445 const std::string mouseTime = time2string(beginStep + static_cast<SUMOTime>(mIndex * desc.getAggregationSpan()));
446 glTranslated(1.6 * (double)mIndex / (double)values.size() - 0.8, -0.9, 0);
447 GLHelper::drawText(mouseTime, Position(0, 0), 1, fontHeight, isMultiPlot ? col.changedBrightness(-40) : RGBColor::BLUE, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
448 }
449 }
450
451}
452
453
454long
456 FXSelector, void*) {
457 if (makeCurrent()) {
458 myWidthInPixels = myParent->getWidth();
459 myHeightInPixels = myParent->getHeight();
460 if (myWidthInPixels != 0 && myHeightInPixels != 0) {
461 glViewport(0, 0, myWidthInPixels - 1, myHeightInPixels - 1);
462 glClearColor(1.0, 1.0, 1.0, 1);
463 glDisable(GL_DEPTH_TEST);
464 glDisable(GL_LIGHTING);
465 glDisable(GL_LINE_SMOOTH);
466 glEnable(GL_BLEND);
467 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
468 glEnable(GL_ALPHA_TEST);
469 glDisable(GL_COLOR_MATERIAL);
470 glLineWidth(1);
471 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
472 }
473 makeNonCurrent();
474 }
475 return 1;
476}
477
478
479long
481 FXSelector, void*) {
482 if (!isEnabled()) {
483 return 1;
484 }
485 if (makeCurrent()) {
486 myWidthInPixels = getWidth();
487 myHeightInPixels = getHeight();
488 if (myWidthInPixels != 0 && myHeightInPixels != 0) {
489 glViewport(0, 0, myWidthInPixels - 1, myHeightInPixels - 1);
490 glClearColor(1.0, 1.0, 1.0, 1);
491 glDisable(GL_DEPTH_TEST);
492 glDisable(GL_LIGHTING);
493 glDisable(GL_LINE_SMOOTH);
494 glEnable(GL_BLEND);
495 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
496 glEnable(GL_ALPHA_TEST);
497 glDisable(GL_COLOR_MATERIAL);
498 glLineWidth(1);
499 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
500 // draw
501 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
502 drawValues();
503 swapBuffers();
504 }
505 makeNonCurrent();
506 }
507 return 1;
508}
509
510
511long
513 FXEvent* event = (FXEvent*) ptr;
514 myMouseX = event->win_x;
515 update();
516 return 1;
517}
518
519
520
521/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
@ MID_SIMSTEP
A Simulation step was performed.
Definition: GUIAppEnum.h:532
#define GUIDesignComboBoxStatic
Combo box static (not editable)
Definition: GUIDesigns.h:309
#define GUIDesignToolBarGrip
design for toolbar grip (used to change the position of toolbar with mouse)
Definition: GUIDesigns.h:438
#define GUIDesignButtonToolbar
little button with icon placed in navigation toolbar
Definition: GUIDesigns.h:115
#define GUIDesignToolBar
design for default toolbar
Definition: GUIDesigns.h:426
FXString gCurrentFolder
The folder used as last.
FXDEFMAP(GUIParameterTracker) GUIParameterTrackerMap[]
#define TL(string)
Definition: MsgHandler.h:282
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
std::string time2string(SUMOTime t)
convert SUMOTime to string
Definition: SUMOTime.cpp:68
#define STEPS2TIME(x)
Definition: SUMOTime.h:54
#define TIME2STEPS(x)
Definition: SUMOTime.h:56
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:583
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
Definition: GLHelper.cpp:498
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:130
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:117
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, const int align=0, double width=-1)
Definition: GLHelper.cpp:685
Class passing values from a GUIGlObject to another object.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
void removeChild(FXMainWindow *child)
removes the given child window from the list (FXMainWindow)
void addChild(FXMainWindow *child)
Adds a further child window to the list (FXMainWindow)
long onMouseMove(FXObject *, FXSelector, void *)
called on mouse movement (for updating moused value)
void drawValue(TrackerValueDesc &desc, const RGBColor &col, int index)
Draws a single value.
long onConfigure(FXObject *, FXSelector, void *)
Called on window resizing.
long onPaint(FXObject *, FXSelector, void *)
Called if the window shall be repainted.
A window which displays the time line of one (or more) value(s)
static std::vector< RGBColor > myColors
long onCmdChangeAggregation(FXObject *, FXSelector, void *)
Called when the aggregation interval (combo) has been changed.
friend class GUIParameterTrackerPanel
the panel may change some things
void addTracked(GUIGlObject &o, ValueSource< double > *src, TrackerValueDesc *newTracked)
Adds a further time line to display.
GUIParameterTrackerPanel * myPanel
The panel to display the values in.
void create()
Creates the window.
GUIParameterTracker(GUIMainWindow &app, const std::string &name)
Constructor (the tracker is empty)
FXComboBox * myAggregationInterval
A combo box to select an aggregation interval.
GUIMainWindow * myApplication
The main application.
long onConfigure(FXObject *, FXSelector, void *)
Called on window resizing.
FXCheckButton * myMultiPlot
Whether phase names shall be printed instead of indices.
std::vector< TrackerValueDesc * > myTracked
The list of tracked values.
long onSimStep(FXObject *, FXSelector, void *)
Called on a simulation step.
long onCmdSave(FXObject *, FXSelector, void *)
Called when the data shall be saved.
long onPaint(FXObject *, FXSelector, void *)
Called if the window shall be repainted.
FXToolBar * myToolBar
The tracker tool bar.
static std::set< GUIParameterTracker * > myMultiPlots
all trackers that are opened for plotting multiple values
std::vector< GLObjectValuePassConnector< double > * > myValuePassers
The value sources.
static bool addTrackedMultiplot(GUIGlObject &o, ValueSource< double > *src, TrackerValueDesc *newTracked)
all value source to multiplot trackers
long onMultiPlot(FXObject *, FXSelector, void *)
Called on a simulation step.
void buildToolBar()
Builds the tool bar.
~GUIParameterTracker()
Destructor.
FXToolBarShell * myToolBarDrag
for some menu detaching fun
@ MID_SAVE
Save the current values.
@ MID_MULTIPLOT
toggle multiplot
@ MID_AGGREGATIONINTERVAL
Change aggregation interval.
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extension, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition: MFXUtils.cpp:82
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
void close()
Closes the device and removes it from the dictionary.
static OutputDevice & getDevice(const std::string &name, bool usePrefix=true)
Returns the described OutputDevice.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
static const RGBColor BLUE
Definition: RGBColor.h:187
static const RGBColor ORANGE
Definition: RGBColor.h:191
static const RGBColor CYAN
Definition: RGBColor.h:189
static const RGBColor GREEN
Definition: RGBColor.h:186
static const RGBColor BLACK
Definition: RGBColor.h:193
RGBColor changedBrightness(int change, int toChange=3) const
Returns a new color with altered brightness.
Definition: RGBColor.cpp:200
RGBColor changedAlpha(int change) const
Returns a new color with altered opacity.
Definition: RGBColor.cpp:223
static const RGBColor MAGENTA
Definition: RGBColor.h:190
static const RGBColor RED
named colors
Definition: RGBColor.h:185
Representation of a timeline of floats with their names and moments.
const std::string & getName() const
Returns the name of the value.
double getMax() const
Returns the values maximum.
void unlockValues()
Releases the locking after the values have been drawn.
double getYCenter() const
Returns the center of the value.
double getRange() const
returns the maximum value range
SUMOTime getAggregationSpan() const
get the aggregation amount
const std::vector< double > & getAggregatedValues()
returns the vector of aggregated values The values will be locked - no further addition will be perfo...
SUMOTime getRecordingBegin() const
Returns the timestep the recording started.
double getMin() const
Returns the values minimum.
virtual ValueSource * copy() const =0
@ FONS_ALIGN_MIDDLE
Definition: fontstash.h:47
@ FONS_ALIGN_LEFT
Definition: fontstash.h:42