Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
GUIParameterTracker.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2025 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// ===========================================================================
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 GUIDesigns::buildFXButton(myToolBar, "", "", + TL("Save the data..."),
118
119 // aggregation interval combo
129
130 myMultiPlot = new FXCheckButton(myToolBar, TL("Multiplot"), this, MID_MULTIPLOT);
131 myMultiPlot->setCheck(false);
132}
133
134
135bool
137 bool first = true;
139 if (first) {
140 first = false;
141 } else {
142 // each Tracker gets its own copy to simplify cleanup
143 newTracked = new TrackerValueDesc(newTracked->getName(), RGBColor::BLACK, newTracked->getRecordingBegin(),
144 STEPS2TIME(newTracked->getAggregationSpan()));
145 src = src->copy();
146 }
147 tr->addTracked(o, src, newTracked);
148 }
149 return myMultiPlots.size() > 0;
150}
151
152
153void
155 TrackerValueDesc* newTracked) {
156 myTracked.push_back(newTracked);
157 // build connection (is automatically set into an execution map)
158 myValuePassers.push_back(new GLObjectValuePassConnector<double>(o, src, newTracked));
159 update();
160}
161
162
163long
164GUIParameterTracker::onConfigure(FXObject* sender, FXSelector sel, void* ptr) {
165 myPanel->onConfigure(sender, sel, ptr);
166 return FXMainWindow::onConfigure(sender, sel, ptr);
167}
168
169
170long
171GUIParameterTracker::onPaint(FXObject* sender, FXSelector sel, void* ptr) {
172 myPanel->onPaint(sender, sel, ptr);
173 return FXMainWindow::onPaint(sender, sel, ptr);
174}
175
176
177long
178GUIParameterTracker::onSimStep(FXObject*, FXSelector, void*) {
179 update();
180 return 1;
181}
182
183long
184GUIParameterTracker::onCmdChangeAggregation(FXObject*, FXSelector, void*) {
186 int aggInt = 0;
187 switch (index) {
188 case 0:
189 aggInt = 1;
190 break;
191 case 1:
192 aggInt = 60;
193 break;
194 case 2:
195 aggInt = 60 * 5;
196 break;
197 case 3:
198 aggInt = 60 * 15;
199 break;
200 case 4:
201 aggInt = 60 * 30;
202 break;
203 case 5:
204 aggInt = 60 * 60;
205 break;
206 default:
207 throw 1;
208 }
209 for (TrackerValueDesc* const tvd : myTracked) {
210 tvd->setAggregationSpan(TIME2STEPS(aggInt));
211 }
212 return 1;
213}
214
215
216long
217GUIParameterTracker::onCmdSave(FXObject*, FXSelector, void*) {
218 FXString file = MFXUtils::getFilename2Write(this, TL("Save Data"),
219 SUMOXMLDefinitions::CSVFileExtensions.getMultilineString().c_str(),
221 if (file == "") {
222 return 1;
223 }
224 try {
225 OutputDevice& dev = OutputDevice::getDevice(file.text());
226 // write header
227 std::vector<TrackerValueDesc*>::iterator i;
228 dev << "# Time";
229 for (i = myTracked.begin(); i != myTracked.end(); ++i) {
230 TrackerValueDesc* tvd = *i;
231 dev << ';' << tvd->getName();
232 }
233 dev << '\n';
234 // count entries
235 int max = 0;
236 for (i = myTracked.begin(); i != myTracked.end(); ++i) {
237 TrackerValueDesc* tvd = *i;
238 int sizei = (int)tvd->getAggregatedValues().size();
239 if (max < sizei) {
240 max = sizei;
241 }
242 tvd->unlockValues();
243 }
244 // write entries
245 SUMOTime t = myTracked.empty() ? 0 : myTracked.front()->getRecordingBegin();
246 SUMOTime dt = myTracked.empty() ? DELTA_T : myTracked.front()->getAggregationSpan();
247 for (int j = 0; j < max; j++) {
248 dev << time2string(t);
249 for (i = myTracked.begin(); i != myTracked.end(); ++i) {
250 TrackerValueDesc* tvd = *i;
251 dev << ';' << tvd->getAggregatedValues()[j];
252 tvd->unlockValues();
253 }
254 dev << '\n';
255 t += dt;
256 }
257 dev.close();
258 } catch (IOError& e) {
259 FXMessageBox::error(this, MBOX_OK, TL("Storing failed!"), "%s", e.what());
260 }
261 return 1;
262}
263
264
265long
266GUIParameterTracker::onMultiPlot(FXObject*, FXSelector, void*) {
267 if (myMultiPlot->getCheck()) {
268 myMultiPlots.insert(this);
269 } else {
270 myMultiPlots.erase(this);
271 }
272 return 1;
273}
274
275/* -------------------------------------------------------------------------
276 * GUIParameterTracker::GUIParameterTrackerPanel-methods
277 * ----------------------------------------------------------------------- */
284
285// Macro for the GLTestApp class hierarchy implementation
286FXIMPLEMENT(GUIParameterTracker::GUIParameterTrackerPanel, FXGLCanvas, GUIParameterTrackerPanelMap, ARRAYNUMBER(GUIParameterTrackerPanelMap))
287
288
289
291 FXComposite* c, GUIMainWindow& app,
292 GUIParameterTracker& parent)
293 : FXGLCanvas(c, app.getGLVisual(), app.getBuildGLCanvas(), (FXObject*) nullptr, (FXSelector) 0, LAYOUT_SIDE_TOP | LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 300, 200),
294 myParent(&parent) {}
295
296
298
299
300void
302 glMatrixMode(GL_PROJECTION);
303 glLoadIdentity();
304 glMatrixMode(GL_MODELVIEW);
305 glLoadIdentity();
306 glDisable(GL_TEXTURE_2D);
307 for (int i = 0; i < (int)myParent->myTracked.size(); i++) {
308 TrackerValueDesc* desc = myParent->myTracked[i];
309 glPushMatrix();
310 drawValue(*desc, myColors[i % myColors.size()], i);
311 glPopMatrix();
312 }
313}
314
315
316void
318 const RGBColor& col,
319 int index) {
320 const double fontWidth = 0.1 * 300. / myWidthInPixels;
321 const double fontHeight = 0.1 * 300. / myHeightInPixels;
322 const bool isMultiPlot = myParent->myTracked.size() > 1;
323 const std::vector<double>& values = desc.getAggregatedValues();
324 if (values.size() < 2) {
325 // draw name
326 glTranslated(-.9, 0.9, 0);
327 GLHelper::drawText(desc.getName(), Position((double)index / (double)myParent->myTracked.size(), 0.), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
328 desc.unlockValues();
329 return;
330 }
331 //
332 // apply scaling
334
335 // apply the positiopn offset of the display
336 glScaled(0.8, 0.8, 1);
337 // apply value range scaling
338 double ys = (double) 2.0 / (double) desc.getRange();
339 glScaled(1.0, ys, 1.0);
340 glTranslated(-1.0, -desc.getYCenter(), 0);
341
342 // draw value bounderies
343 // draw minimum boundary
344 glBegin(GL_LINES);
345 glVertex2d(0, desc.getMin());
346 glVertex2d(2.0, desc.getMin());
347 glEnd();
348 glBegin(GL_LINES);
349 glVertex2d(0, desc.getMax());
350 glVertex2d(2.0, desc.getMax());
351 glEnd();
353 for (int a = 1; a < 6; a++) {
354 const double yp = desc.getRange() / 6.0 * (double) a + desc.getMin();
355 glBegin(GL_LINES);
356 glVertex2d(0, yp);
357 glVertex2d(2.0, yp);
358 glEnd();
359 }
360
361 double latest = 0;
362 double mx = (2 * myMouseX / myWidthInPixels - 1) / 0.8 + 1;
363 int mIndex = 0;
364 double mouseValue = std::numeric_limits<double>::max();
365 latest = values.back();
366 // init values
367 const double xStep = 2.0 / (double) values.size();
368 std::vector<double>::const_iterator i = values.begin();
369 double yp = (*i);
370 double xp = 0;
371 i++;
373 for (; i != values.end(); i++) {
374 double yn = (*i);
375 double xn = xp + xStep;
376 if (xp < mx && mx < xn) {
377 mouseValue = yp;
378 mIndex = (int)(i - values.begin()) - 1;
379 glPushMatrix();
380 GLHelper::setColor(isMultiPlot ? col.changedBrightness(-40).changedAlpha(-100) : RGBColor::BLUE);
381 glTranslated(xn, yn, 0);
382 glScaled(20.0 / myWidthInPixels, 10.0 * desc.getRange() / myHeightInPixels, 0);
385 glPopMatrix();
386 }
387 glBegin(GL_LINES);
388 glVertex2d(xp, yp);
389 glVertex2d(xn, yn);
390 glEnd();
391 yp = yn;
392 xp = xn;
393 }
394 desc.unlockValues();
396
397 // draw value bounderies and descriptions
399
400 // draw min time
401 SUMOTime beginStep = desc.getRecordingBegin();
402 std::string begStr = time2string(beginStep);
403 double w = 50 / myWidthInPixels;
404 glTranslated(-0.8 - w / 2., -0.88, 0);
405 GLHelper::drawText(begStr, Position(0, 0), 1, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
406 glTranslated(0.8 + w / 2., 0.88, 0);
407
408 // draw max time
409 glTranslated(0.75, -0.88, 0);
410 GLHelper::drawText(time2string(beginStep + static_cast<SUMOTime>(values.size() * desc.getAggregationSpan())),
411 Position(0, 0), 1, fontHeight, RGBColor::BLACK, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
412 glTranslated(-0.75, 0.88, 0);
413
414 // draw min value
415 glTranslated(-0.98, -0.82, 0);
416 GLHelper::drawText(toString(desc.getMin()), Position(0, index * fontHeight), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
417 glTranslated(0.98, 0.82, 0);
418
419 // draw max value
420 glTranslated(-0.98, 0.78, 0);
421 GLHelper::drawText(toString(desc.getMax()), Position(0, -index * fontHeight), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
422 glTranslated(0.98, -0.78, 0);
423
424 // draw name
425 glTranslated(-0.98, .92, 0);
426 GLHelper::drawText(desc.getName(), Position((double)index / (double)myParent->myTracked.size(), 0.), 1, fontHeight, col, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
427 glTranslated(0.98, -.92, 0);
428
429 // draw current value (with contrasting color)
430 double p = (double) 0.8 -
431 ((double) 1.6 / (desc.getMax() - desc.getMin()) * (latest - desc.getMin()));
432 glTranslated(-0.98, -(p + .02), 0);
433 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);
434 glTranslated(0.98, p + .02, 0);
435
436 // draw moused value
437 if (mouseValue != std::numeric_limits<double>::max()) {
438 p = (double) 0.8 -
439 ((double) 1.6 / (desc.getMax() - desc.getMin()) * (mouseValue - desc.getMin()));
440 glTranslated(-0.98, -(p + .02), 0);
441 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);
442 glTranslated(0.98, p + .02, 0);
443
444 if (index == 0) {
445 // time is the same for all plots so we only draw it once
446 const std::string mouseTime = time2string(beginStep + static_cast<SUMOTime>(mIndex * desc.getAggregationSpan()));
447 glTranslated(1.6 * (double)mIndex / (double)values.size() - 0.8, -0.9, 0);
448 GLHelper::drawText(mouseTime, Position(0, 0), 1, fontHeight, isMultiPlot ? col.changedBrightness(-40) : RGBColor::BLUE, 0, FONS_ALIGN_LEFT | FONS_ALIGN_MIDDLE, fontWidth);
449 }
450 }
451
452}
453
454
455long
457 FXSelector, void*) {
458 if (makeCurrent()) {
459 myWidthInPixels = myParent->getWidth();
460 myHeightInPixels = myParent->getHeight();
461 if (myWidthInPixels != 0 && myHeightInPixels != 0) {
462 glViewport(0, 0, myWidthInPixels - 1, myHeightInPixels - 1);
463 glClearColor(1.0, 1.0, 1.0, 1);
464 glDisable(GL_DEPTH_TEST);
465 glDisable(GL_LIGHTING);
466 glDisable(GL_LINE_SMOOTH);
467 glEnable(GL_BLEND);
468 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
469 glEnable(GL_ALPHA_TEST);
470 glDisable(GL_COLOR_MATERIAL);
471 glLineWidth(1);
472 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
473 }
474 makeNonCurrent();
475 }
476 return 1;
477}
478
479
480long
482 FXSelector, void*) {
483 if (!isEnabled()) {
484 return 1;
485 }
486 if (makeCurrent()) {
487 myWidthInPixels = getWidth();
488 myHeightInPixels = getHeight();
489 if (myWidthInPixels != 0 && myHeightInPixels != 0) {
490 glViewport(0, 0, myWidthInPixels - 1, myHeightInPixels - 1);
491 glClearColor(1.0, 1.0, 1.0, 1);
492 glDisable(GL_DEPTH_TEST);
493 glDisable(GL_LIGHTING);
494 glDisable(GL_LINE_SMOOTH);
495 glEnable(GL_BLEND);
496 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
497 glEnable(GL_ALPHA_TEST);
498 glDisable(GL_COLOR_MATERIAL);
499 glLineWidth(1);
500 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
501 // draw
502 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
503 drawValues();
504 swapBuffers();
505 }
506 makeNonCurrent();
507 }
508 return 1;
509}
510
511
512long
514 FXEvent* event = (FXEvent*) ptr;
515 myMouseX = event->win_x;
516 update();
517 return 1;
518}
519
520
521
522/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
@ MID_SIMSTEP
A Simulation step was performed.
Definition GUIAppEnum.h:541
#define GUIDesignComboBoxStatic
Combo box static (not editable)
Definition GUIDesigns.h:296
#define GUIDesignToolBarGrip
design for toolbar grip (used to change the position of toolbar with mouse)
Definition GUIDesigns.h:449
#define GUIDesignButtonToolbar
little button with icon placed in navigation toolbar
Definition GUIDesigns.h:123
#define GUIDesignToolBar
design for default toolbar
Definition GUIDesigns.h:434
#define GUIDesignComboBoxVisibleItems
Definition GUIDesigns.h:49
FXString gCurrentFolder
The folder used as last.
@ SAVE
save icons
FXDEFMAP(GUIParameterTracker) GUIParameterTrackerMap[]
#define TL(string)
Definition MsgHandler.h:305
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:91
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define TIME2STEPS(x)
Definition SUMOTime.h:57
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:649
static void drawFilledCircle(const double widradiusth, const int steps=8)
Draws a filled circle around (0,0)
Definition GLHelper.cpp:564
static void popMatrix()
pop matrix
Definition GLHelper.cpp:131
static void pushMatrix()
push matrix
Definition GLHelper.cpp:118
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:748
Class passing values from a GUIGlObject to another object.
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
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.
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)
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.
@ MID_SAVE
Save the current values.
@ MID_MULTIPLOT
toggle multiplot
@ MID_AGGREGATIONINTERVAL
Change aggregation interval.
MFXComboBoxIcon * myAggregationInterval
A combo box to select an aggregation interval.
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.
FXToolBarShell * myToolBarDrag
for some menu detaching fun
FXint getCurrentItem() const
Get the current item's index.
FXint appendIconItem(const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
append icon item in the last position
static FXString getFilename2Write(FXWindow *parent, const FXString &header, const FXString &extensions, FXIcon *icon, FXString &currentFolder)
Returns the file name to write.
Definition MFXUtils.cpp:116
Static storage of an output device and its base (abstract) implementation.
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:190
static const RGBColor ORANGE
Definition RGBColor.h:194
static const RGBColor CYAN
Definition RGBColor.h:192
static const RGBColor GREEN
Definition RGBColor.h:189
static const RGBColor BLACK
Definition RGBColor.h:196
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:193
static const RGBColor RED
named colors
Definition RGBColor.h:188
static StringBijection< CSVFileExtension > CSVFileExtensions
CSV file Extensions.
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