From 02a4ff509fa23e8c9849b1c0c72f3ef48fc9565e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Offringa?= <offringa@astron.nl> Date: Tue, 22 Mar 2011 18:59:36 +0000 Subject: [PATCH] Bug 1491: esthetic improvements to the time-frequency window of the rfigui: displayment of a colorscale, use of rounded values instead of linear interpolated values along axes and other esthetics --- .gitattributes | 6 +- .../include/AOFlagger/CMakeLists.txt | 4 +- .../{horizontaltimescale.h => colorscale.h} | 79 ++++-- .../gui/plot/horizontalnumericscale.h | 51 ---- .../AOFlagger/gui/plot/horizontalplotscale.h | 33 +-- .../include/AOFlagger/gui/plot/tickset.h | 259 ++++++++++++++++++ .../AOFlagger/gui/plot/verticalnumericscale.h | 51 ---- .../AOFlagger/gui/plot/verticalplotscale.h | 34 +-- .../AOFlagger/gui/timefrequencywidget.h | 5 +- .../AOFlagger/include/AOFlagger/msio/date.h | 23 +- CEP/DP3/AOFlagger/src/CMakeLists.txt | 1 + CEP/DP3/AOFlagger/src/gui/plot/colorscale.cpp | 78 ++++++ .../src/gui/plot/horizontalplotscale.cpp | 95 +++---- .../src/gui/plot/verticalplotscale.cpp | 85 +++--- .../AOFlagger/src/gui/timefrequencywidget.cpp | 81 ++++-- 15 files changed, 559 insertions(+), 326 deletions(-) rename CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/{horizontaltimescale.h => colorscale.h} (52%) delete mode 100644 CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalnumericscale.h create mode 100644 CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/tickset.h delete mode 100644 CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalnumericscale.h create mode 100644 CEP/DP3/AOFlagger/src/gui/plot/colorscale.cpp diff --git a/.gitattributes b/.gitattributes index 574c170c3d6..66eee21e76c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -190,16 +190,15 @@ CEP/DP3/AOFlagger/include/AOFlagger/gui/msoptionwindow.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/mswindow.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/newstrategyactionframe.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/numinputdialog.h -text +CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/colorscale.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/dimension.h -text -CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalnumericscale.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalplotscale.h -text -CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontaltimescale.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/plot2d.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/plot2dpointset.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/plotable.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/plotwidget.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/system.h -text -CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalnumericscale.h -text +CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/tickset.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalplotscale.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/plotframe.h -text CEP/DP3/AOFlagger/include/AOFlagger/gui/progresswindow.h -text @@ -415,6 +414,7 @@ CEP/DP3/AOFlagger/src/gui/imagewidget.cpp -text CEP/DP3/AOFlagger/src/gui/msoptionwindow.cpp -text CEP/DP3/AOFlagger/src/gui/mswindow.cpp -text CEP/DP3/AOFlagger/src/gui/newstrategyactionframe.cpp -text +CEP/DP3/AOFlagger/src/gui/plot/colorscale.cpp -text CEP/DP3/AOFlagger/src/gui/plot/horizontalplotscale.cpp -text CEP/DP3/AOFlagger/src/gui/plot/plot2d.cpp -text CEP/DP3/AOFlagger/src/gui/plot/plotwidget.cpp -text diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/CMakeLists.txt b/CEP/DP3/AOFlagger/include/AOFlagger/CMakeLists.txt index 060e44f95f3..1533589e5eb 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/CMakeLists.txt +++ b/CEP/DP3/AOFlagger/include/AOFlagger/CMakeLists.txt @@ -35,15 +35,13 @@ install(FILES install(FILES gui/plot/dimension.h - gui/plot/horizontalnumericscale.h gui/plot/horizontalplotscale.h - gui/plot/horizontaltimescale.h gui/plot/plot2d.h gui/plot/plot2dpointset.h gui/plot/plotable.h gui/plot/plotwidget.h gui/plot/system.h - gui/plot/verticalnumericscale.h + gui/plot/tickset.h gui/plot/verticalplotscale.h DESTINATION include/${PACKAGE_NAME}/gui/plot) diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontaltimescale.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/colorscale.h similarity index 52% rename from CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontaltimescale.h rename to CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/colorscale.h index 04a72f48985..f36b3e3beba 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontaltimescale.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/colorscale.h @@ -17,38 +17,71 @@ * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef HORIZONTALTIMESCALE_H -#define HORIZONTALTIMESCALE_H +#ifndef PLOT_COLORSCALE_H +#define PLOT_COLORSCALE_H #include <string> +#include <map> -#include "horizontalplotscale.h" +#include <gtkmm/drawingarea.h> -#include <AOFlagger/msio/date.h> +#include <AOFlagger/gui/plot/verticalplotscale.h> -class HorizontalTimeScale : private HorizontalPlotScale -{ +/** + @author A.R. Offringa <offringa@astro.rug.nl> +*/ +class ColorScale { public: - HorizontalTimeScale(Glib::RefPtr<Gdk::Drawable> drawable, double minAipsTime, double maxAipsTime) - : HorizontalPlotScale(drawable) + ColorScale(Glib::RefPtr<Gdk::Drawable> drawable); + + virtual ~ColorScale() { - for(size_t i=0;i<=10;++i) - { - double val = ((maxAipsTime - minAipsTime) * i / 10.0 + minAipsTime); - std::string s = Date::AipsMJDToTimeString(val);// + "\n" + Date::AipsMJDToDateString(val); - if(i % 2 == 0) - HorizontalTimeScale::AddLargeTick(i / 10.0, s); - else - HorizontalTimeScale::AddSmallTick(i / 10.0, s); - } } - void Draw(Cairo::RefPtr<Cairo::Context> cairo) { HorizontalPlotScale::Draw(cairo); } - double GetHeight() { return HorizontalPlotScale::GetHeight(); } - double GetRightMargin() { return HorizontalPlotScale::GetRightMargin(); } - void SetPlotDimensions(double plotWidth, double plotHeight, double topMargin, double verticalScaleWidth) + void SetPlotDimensions(double plotWidth, double plotHeight, double topMargin) { - HorizontalPlotScale::SetPlotDimensions(plotWidth, plotHeight, topMargin, verticalScaleWidth); + _plotWidth = plotWidth; + _plotHeight = plotHeight; + _topMargin = topMargin; + _width = 0.0; } + double GetWidth() + { + if(_width == 0.0) + initWidth(); + return _width; + } + void Draw(Cairo::RefPtr<Cairo::Context> cairo); + void InitializeNumericTicks(double min, double max) + { + _min = min; + _max = max; + _verticalPlotScale.InitializeNumericTicks(min, max); + } + void SetColorValue(double value, double red, double green, double blue) + { + ColorValue cValue; + cValue.red = red; + cValue.green = green; + cValue.blue = blue; + _colorValues.insert(std::pair<double, ColorValue>(value, cValue)); + } + private: + static const double BAR_WIDTH; + + struct ColorValue + { + double red, green, blue; + }; + + void initWidth(); + + double _plotWidth, _plotHeight, _topMargin; + double _scaleWidth, _width; + double _min, _max; + Glib::RefPtr<Gdk::Drawable> _drawable; + Cairo::RefPtr<Cairo::Context> _cairo; + class VerticalPlotScale _verticalPlotScale; + std::map<double, ColorValue> _colorValues; }; -#endif // HORIZONTALTIMESCALE_H +#endif diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalnumericscale.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalnumericscale.h deleted file mode 100644 index 2ed283d54f3..00000000000 --- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalnumericscale.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by A.R. Offringa * - * offringa@astro.rug.nl * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef HORIZONTALNUMERICSCALE_H -#define HORIZONTALNUMERICSCALE_H - -#include <sstream> - -#include "horizontalplotscale.h" - -class HorizontalNumericScale : private HorizontalPlotScale -{ - public: - HorizontalNumericScale(Glib::RefPtr<Gdk::Drawable> drawable, double min, double max) - : HorizontalPlotScale(drawable) - { - for(size_t i=0;i<=100;++i) - { - std::stringstream s; - s << ((max - min) * i / 100.0 + min); - if(i % 10 == 0) - HorizontalPlotScale::AddLargeTick(i / 100.0, s.str()); - else - HorizontalPlotScale::AddSmallTick(i / 100.0, s.str()); - } - } - void Draw(Cairo::RefPtr<Cairo::Context> cairo) { HorizontalPlotScale::Draw(cairo); } - double GetHeight() { return HorizontalPlotScale::GetHeight(); } - void SetPlotDimensions(double plotWidth, double plotHeight, double topMargin, double verticalScaleWidth) - { - HorizontalPlotScale::SetPlotDimensions(plotWidth, plotHeight, topMargin, verticalScaleWidth); - } -}; - -#endif // HORIZONTALNUMERICSCALE_H diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalplotscale.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalplotscale.h index 5f4c3c754a3..9a3160f0a65 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalplotscale.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/horizontalplotscale.h @@ -32,16 +32,6 @@ class HorizontalPlotScale { public: HorizontalPlotScale(Glib::RefPtr<Gdk::Drawable> drawable); virtual ~HorizontalPlotScale(); - void AddLargeTick(double normValue, std::string caption) - { - _largeTicks.push_back(Tick(normValue, caption)); - _metricsAreInitialized = false; - } - void AddSmallTick(double normValue, std::string caption) - { - _smallTicks.push_back(Tick(normValue, caption)); - _metricsAreInitialized = false; - } void SetPlotDimensions(double plotWidth, double plotHeight, double topMargin, double verticalScaleWidth) { _plotWidth = plotWidth; @@ -53,33 +43,18 @@ class HorizontalPlotScale { double GetHeight(); double GetRightMargin(); void Draw(Cairo::RefPtr<Cairo::Context> cairo); + void InitializeNumericTicks(double min, double max); + void InitializeTimeTicks(double timeMin, double timeMax); private: - struct Tick { - Tick(double _normValue, std::string _caption) : - normValue(_normValue), caption(_caption) - { } - Tick(const Tick &source) : - normValue(source.normValue), caption(source.caption) - { } - Tick &operator=(const Tick &rhs) - { - normValue = rhs.normValue; caption = rhs.caption; - return *this; - } - double normValue; - std::string caption; - }; - void setVisibleTicks(); - bool ticksFit(std::map<double, Tick> &ticks); + bool ticksFit(); void initializeMetrics(); double _plotWidth, _plotHeight, _topMargin, _verticalScaleWidth; - std::vector<Tick> _largeTicks, _smallTicks; - std::vector<Tick> _visibleLargeTicks; bool _metricsAreInitialized; double _height, _rightMargin; Glib::RefPtr<Gdk::Drawable> _drawable; Cairo::RefPtr<Cairo::Context> _cairo; + class TickSet *_tickSet; }; #endif diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/tickset.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/tickset.h new file mode 100644 index 00000000000..6733a369536 --- /dev/null +++ b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/tickset.h @@ -0,0 +1,259 @@ + +#include <string> +#include <vector> +#include <cmath> +#include <sstream> +#include <iostream> + +#include <AOFlagger/msio/date.h> + +typedef std::pair<double, std::string> Tick; + +class TickSet +{ + public: + TickSet() + { + } + virtual ~TickSet() + { + } + + virtual unsigned Size() const = 0; + virtual Tick GetTick(unsigned i) const = 0; + + virtual void DecreaseTicks() + { + if(Size() > 1) + { + Reset(Size() - 1); + } + } + virtual void Reset(unsigned sizeRequest) = 0; + protected: + private: + +}; + +class NumericTickSet : public TickSet +{ + public: + NumericTickSet(double min, double max, unsigned sizeRequest) : _min(min), _max(max) + { + set(sizeRequest); + } + + virtual unsigned Size() const + { + return _ticks.size(); + } + + virtual Tick GetTick(unsigned i) const + { + std::stringstream tickStr; + tickStr << _ticks[i]; + return Tick((_ticks[i] - _min) / (_max - _min), tickStr.str()); + } + + virtual void Reset(unsigned sizeRequest) + { + _ticks.clear(); + set(sizeRequest); + } + private: + void set(unsigned sizeRequest) + { + if(_max == _min) + _ticks.push_back(_min); + else + { + if(sizeRequest == 0) + sizeRequest = 1; + double + tickWidth = roundUpToNiceNumber((_max - _min) / (double) sizeRequest); + if(tickWidth == 0.0) + tickWidth = 1.0; + double + pos = roundUpToNiceNumber(_min, tickWidth); + while(pos <= _max) + { + std::cout << tickWidth << ' ' << pos << '\n'; + _ticks.push_back(pos); + pos += tickWidth; + } + } + } + + double roundUpToNiceNumber(double number) + { + if(!std::isfinite(number)) + return number; + double roundedNumber = 1.0; + if(number <= 0.0) + { + if(roundedNumber == 0.0) + return 0.0; + else + { + roundedNumber = -1.0; + number *= -1.0; + } + } + while(number > 10) + { + number /= 10; + roundedNumber *= 10; + } + while(number <= 1) + { + number *= 10; + roundedNumber /= 10; + } + if(number <= 2) return roundedNumber * 2; + else if(number <= 5) return roundedNumber * 5; + else return roundedNumber * 10; + } + double roundUpToNiceNumber(double number, double roundUnit) + { + return roundUnit * ceil(number / roundUnit); + } + + double _min, _max; + std::vector<double> _ticks; +}; + +class TimeTickSet : public TickSet +{ + public: + TimeTickSet(double minTime, double maxTime, unsigned sizeRequest) : _min(minTime), _max(maxTime) + { + set(sizeRequest); + } + + virtual unsigned Size() const + { + return _ticks.size(); + } + + virtual Tick GetTick(unsigned i) const + { + double val = _ticks[i]; + return Tick((val - _min) / (_max - _min), Date::AipsMJDToTimeString(val)); + } + + virtual void Reset(unsigned sizeRequest) + { + _ticks.clear(); + set(sizeRequest); + } + private: + void set(unsigned sizeRequest) + { + if(_max == _min) + _ticks.push_back(_min); + else + { + if(sizeRequest == 0) + sizeRequest = 1; + double tickWidth = calculateTickWidth((_max - _min) / (double) sizeRequest); + if(tickWidth == 0.0) + tickWidth = 1.0; + double + pos = roundUpToNiceNumber(_min, tickWidth); + while(pos < _max) + { + std::cout << tickWidth << ' ' << pos << '\n'; + _ticks.push_back(pos); + pos += tickWidth; + } + } + } + + double calculateTickWidth(double lowerLimit) const + { + // number is in units of seconds + + // In days? + if(lowerLimit >= 60.0*60.0*24.0) + { + double width = 60.0*60.0*24.0; + while(width < lowerLimit) + width *= 2.0; + return width; + } + // in hours? + else if(lowerLimit > 60.0*30.0) + { + if(lowerLimit <= 60.0*60.0) + return 60.0*60.0; // hours + else if(lowerLimit <= 60.0*60.0*2.0) + return 60.0*60.0*2.0; // two hours + else if(lowerLimit <= 60.0*60.0*3.0) + return 60.0*60.0*3.0; // three hours + else if(lowerLimit <= 60.0*60.0*4.0) + return 60.0*60.0*4.0; // four hours + else if(lowerLimit <= 60.0*60.0*6.0) + return 60.0*60.0*6.0; // six hours + else + return 60.0*60.0*12.0; // twelve hours + } + // in minutes? + else if(lowerLimit > 30.0) + { + if(lowerLimit <= 60.0) + return 60.0; // in minutes + else if(lowerLimit <= 60.0*2.0) + return 60.0*2.0; // two minutes + else if(lowerLimit <= 60.0*5.0) + return 60.0*5.0; // five minutes + else if(lowerLimit <= 60.0*10.0) + return 60.0*10.0; // ten minutes + else if(lowerLimit <= 60.0*15.0) + return 60.0*15.0; // quarter hours + else + return 60.0*30.0; // half hours + } + // in seconds? + else if(lowerLimit > 0.5) + { + if(lowerLimit <= 1.0) + return 1.0; // in seconds + else if(lowerLimit <= 2.0) + return 2.0; // two seconds + else if(lowerLimit <= 5.0) + return 5.0; // five seconds + else if(lowerLimit <= 10.0) + return 10.0; // ten seconds + else if(lowerLimit <= 15.0) + return 15.0; // quarter minute + else + return 30.0; // half a minute + } + else if(lowerLimit == 0.0) + return 0.0; + // in 10th of seconds or lower? + else + { + double factor = 1.0; + while(lowerLimit < 0.1) + { + factor *= 0.1; + lowerLimit *= 10.0; + } + if(lowerLimit <= 0.1) + return 0.1 * factor; + else if(lowerLimit <= 0.2) + return 0.2 * factor; + else + return 0.5 * factor; + } + } + + double roundUpToNiceNumber(double number, double roundUnit) + { + return roundUnit * ceil(number / roundUnit); + } + + double _min, _max; + std::vector<double> _ticks; +}; diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalnumericscale.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalnumericscale.h deleted file mode 100644 index b39f2ed2130..00000000000 --- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalnumericscale.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by A.R. Offringa * - * offringa@astro.rug.nl * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VERTICALNUMERICSCALE_H -#define VERTICALNUMERICSCALE_H - -#include <sstream> - -#include "verticalplotscale.h" - -class VerticalNumericScale : private VerticalPlotScale -{ - public: - VerticalNumericScale(Glib::RefPtr<Gdk::Drawable> drawable, double min, double max) - : VerticalPlotScale(drawable) - { - for(size_t i=0;i<=100;++i) - { - std::stringstream s; - s << ((max - min) * i / 100.0 + min); - if(i % 10 == 0) - VerticalPlotScale::AddLargeTick(i / 100.0, s.str()); - else - VerticalPlotScale::AddSmallTick(i / 100.0, s.str()); - } - } - void Draw(Cairo::RefPtr<Cairo::Context> cairo) { VerticalPlotScale::Draw(cairo); } - double GetWidth() { return VerticalPlotScale::GetWidth(); } - void SetPlotDimensions(double plotWidth, double plotHeight, double topMargin) - { - VerticalPlotScale::SetPlotDimensions(plotWidth, plotHeight, topMargin); - } -}; - -#endif // VERTICALNUMERICSCALE_H diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalplotscale.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalplotscale.h index 133c12ab0d0..fd0dae231bb 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalplotscale.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/gui/plot/verticalplotscale.h @@ -32,16 +32,6 @@ class VerticalPlotScale { public: VerticalPlotScale(Glib::RefPtr<Gdk::Drawable> drawable); virtual ~VerticalPlotScale(); - void AddLargeTick(double normValue, std::string caption) - { - _largeTicks.push_back(Tick(normValue, caption)); - _metricsAreInitialized = false; - } - void AddSmallTick(double normValue, std::string caption) - { - _smallTicks.push_back(Tick(normValue, caption)); - _metricsAreInitialized = false; - } void SetPlotDimensions(double plotWidth, double plotHeight, double topMargin) { _plotWidth = plotWidth; @@ -50,34 +40,18 @@ class VerticalPlotScale { _metricsAreInitialized = false; } double GetWidth(); - void Draw(Cairo::RefPtr<Cairo::Context> cairo); + void Draw(Cairo::RefPtr<Cairo::Context> cairo, double offsetX=0.0, double offsetY=0.0); + void InitializeNumericTicks(double min, double max); private: - struct Tick { - Tick(double _normValue, std::string _caption) : - normValue(_normValue), caption(_caption) - { } - Tick(const Tick &source) : - normValue(source.normValue), caption(source.caption) - { } - Tick &operator=(const Tick &rhs) - { - normValue = rhs.normValue; caption = rhs.caption; - return *this; - } - double normValue; - std::string caption; - }; - void setVisibleTicks(); - bool ticksFit(std::map<double, Tick> &ticks); + bool ticksFit(); void initializeMetrics(); double _plotWidth, _plotHeight, _topMargin; - std::vector<Tick> _largeTicks, _smallTicks; - std::vector<Tick> _visibleLargeTicks; bool _metricsAreInitialized; double _width; Glib::RefPtr<Gdk::Drawable> _drawable; Cairo::RefPtr<Cairo::Context> _cairo; + class TickSet *_tickSet; }; #endif diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/gui/timefrequencywidget.h b/CEP/DP3/AOFlagger/include/AOFlagger/gui/timefrequencywidget.h index 29ccd96eada..dd40e116636 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/gui/timefrequencywidget.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/gui/timefrequencywidget.h @@ -171,8 +171,9 @@ class TimeFrequencyWidget : public Gtk::DrawingArea { size_t _startTime, _endTime; size_t _startFrequency, _endFrequency; SegmentedImageCPtr _segmentedImage; - class HorizontalTimeScale *_horiScale; - class VerticalNumericScale *_vertScale; + class HorizontalPlotScale *_horiScale; + class VerticalPlotScale *_vertScale; + class ColorScale *_colorScale; num_t _max, _min; enum Range _range; diff --git a/CEP/DP3/AOFlagger/include/AOFlagger/msio/date.h b/CEP/DP3/AOFlagger/include/AOFlagger/msio/date.h index 97aa98881ad..55005422d76 100644 --- a/CEP/DP3/AOFlagger/include/AOFlagger/msio/date.h +++ b/CEP/DP3/AOFlagger/include/AOFlagger/msio/date.h @@ -23,6 +23,7 @@ #include <string> #include <sstream> +#include <cmath> class Date { public: @@ -95,12 +96,24 @@ class Date { static std::string ToString(double time) { std::stringstream s; - int mins = int(time*60)%60; - int secs = int(time*3600)%60; int msec = int(round(time*3600000))%1000; - s << floor(time) << ":" << (mins/10) << (mins%10) << ":" << (secs/10) << (secs%10); - if(msec != 0) - s << "." << msec/100 << (msec/10)%10 << (msec)%10; + time -= msec/3600000.0; + + int secs = int(round(time*3600))%60; + time -= secs/3600.0; + + int mins = int(round(time*60))%60; + time -= mins/60.0; + + int hours = int(round(time)); + time -= hours; + s << hours << ":" << (mins/10) << (mins%10); + if(msec != 0 || secs != 0) + { + s << ":" << (secs/10) << (secs%10); + if(msec != 0) + s << "." << msec/100 << (msec/10)%10 << (msec)%10; + } return s.str(); } static std::string ToString(int dayOfMonth, int month, int year) diff --git a/CEP/DP3/AOFlagger/src/CMakeLists.txt b/CEP/DP3/AOFlagger/src/CMakeLists.txt index 9e694ad3575..59e02fb1696 100644 --- a/CEP/DP3/AOFlagger/src/CMakeLists.txt +++ b/CEP/DP3/AOFlagger/src/CMakeLists.txt @@ -13,6 +13,7 @@ lofar_add_bin_program(aorefscript aorefscript.cpp) lofar_add_bin_program(aosynchronisation aosynchronisation.cpp) set(GUI_PLOT_FILES + gui/plot/colorscale.cpp gui/plot/horizontalplotscale.cpp gui/plot/plot2d.cpp gui/plot/plotwidget.cpp diff --git a/CEP/DP3/AOFlagger/src/gui/plot/colorscale.cpp b/CEP/DP3/AOFlagger/src/gui/plot/colorscale.cpp new file mode 100644 index 00000000000..ee26096a276 --- /dev/null +++ b/CEP/DP3/AOFlagger/src/gui/plot/colorscale.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (C) 2008 by A.R. Offringa * + * offringa@astro.rug.nl * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include <AOFlagger/gui/plot/colorscale.h> + +const double ColorScale::BAR_WIDTH = 15.0; + +ColorScale::ColorScale(Glib::RefPtr<Gdk::Drawable> drawable) +: _width(0.0), _drawable(drawable), _verticalPlotScale(drawable) +{ + _cairo = _drawable->create_cairo_context(); +} + +void ColorScale::initWidth() +{ + if(_width == 0.0) + { + _scaleWidth = _verticalPlotScale.GetWidth(); + _width = _scaleWidth + BAR_WIDTH; + } +} + +void ColorScale::Draw(Cairo::RefPtr<Cairo::Context> cairo) +{ + _verticalPlotScale.SetPlotDimensions(_plotWidth, _plotHeight, _topMargin); + initWidth(); + _cairo = cairo; + ColorValue backValue; + if(!_colorValues.empty()) + { + backValue = _colorValues.begin()->second; + } else { + backValue.red = 1.0; + backValue.green = 1.0; + backValue.blue = 1.0; + } + _cairo->rectangle(_plotWidth - _width + _scaleWidth, _topMargin, + BAR_WIDTH, _plotHeight); + _cairo->set_source_rgb(backValue.red, backValue.green, backValue.blue); + _cairo->fill(); + + for(std::map<double, ColorValue>::const_iterator i=_colorValues.begin(); + i!=_colorValues.end();++i) + { + double val = (i->first - _min) / (_max - _min); + if(val < 0.0) val = 0.0; + if(val > 1.0) val = 1.0; + double height = _plotHeight * (1.0 - val); + const ColorValue &color = i->second; + _cairo->set_source_rgb(color.red, color.green, color.blue); + _cairo->rectangle(_plotWidth - _width + _scaleWidth, _topMargin, + BAR_WIDTH, height); + _cairo->fill(); + } + + _cairo->rectangle(_plotWidth - _width + _scaleWidth, _topMargin, + BAR_WIDTH, _plotHeight); + _cairo->set_source_rgb(0.0, 0.0, 0.0); + _cairo->stroke(); + + _verticalPlotScale.Draw(cairo, _plotWidth - _width, 0.0); +} diff --git a/CEP/DP3/AOFlagger/src/gui/plot/horizontalplotscale.cpp b/CEP/DP3/AOFlagger/src/gui/plot/horizontalplotscale.cpp index 77ae8ff12ae..63c3a7966d2 100644 --- a/CEP/DP3/AOFlagger/src/gui/plot/horizontalplotscale.cpp +++ b/CEP/DP3/AOFlagger/src/gui/plot/horizontalplotscale.cpp @@ -19,15 +19,18 @@ ***************************************************************************/ #include <AOFlagger/gui/plot/horizontalplotscale.h> -#include <map> +#include <AOFlagger/gui/plot/tickset.h> + HorizontalPlotScale::HorizontalPlotScale(Glib::RefPtr<Gdk::Drawable> drawable) - : _plotWidth(0), _plotHeight(0), _metricsAreInitialized(false), _drawable(drawable) + : _plotWidth(0), _plotHeight(0), _metricsAreInitialized(false), _drawable(drawable), _tickSet(0) { _cairo = _drawable->create_cairo_context(); } HorizontalPlotScale::~HorizontalPlotScale() { + if(_tickSet != 0) + delete _tickSet; } double HorizontalPlotScale::GetHeight() @@ -48,15 +51,16 @@ void HorizontalPlotScale::Draw(Cairo::RefPtr<Cairo::Context> cairo) initializeMetrics(); _cairo->set_source_rgb(0.0, 0.0, 0.0); _cairo->set_font_size(16.0); - for(std::vector<Tick>::const_iterator i=_visibleLargeTicks.begin();i!=_visibleLargeTicks.end();++i) + for(unsigned i=0;i!=_tickSet->Size();++i) { - double x = i->normValue * (_plotWidth - _verticalScaleWidth) + _verticalScaleWidth; + const Tick tick = _tickSet->GetTick(i); + double x = tick.first * (_plotWidth - _verticalScaleWidth) + _verticalScaleWidth; _cairo->move_to(x, _topMargin + _plotHeight); _cairo->line_to(x, _topMargin + _plotHeight + 3); Cairo::TextExtents extents; - _cairo->get_text_extents(i->caption, extents); + _cairo->get_text_extents(tick.second, extents); _cairo->move_to(x - extents.width/2, _topMargin + _plotHeight - extents.y_bearing + extents.height); - _cairo->show_text(i->caption); + _cairo->show_text(tick.second); } _cairo->stroke(); } @@ -65,63 +69,48 @@ void HorizontalPlotScale::initializeMetrics() { if(!_metricsAreInitialized) { - setVisibleTicks(); - _cairo->set_font_size(16.0); - double maxHeight = 0; - for(std::vector<Tick>::const_iterator i=_visibleLargeTicks.begin();i!=_visibleLargeTicks.end();++i) + if(_tickSet != 0) { - Tick tick = *i; + while(!ticksFit()) + { + _tickSet->DecreaseTicks(); + } + _cairo->set_font_size(16.0); + double maxHeight = 0; + for(unsigned i=0;i!=_tickSet->Size();++i) + { + const Tick tick = _tickSet->GetTick(i); + Cairo::TextExtents extents; + _cairo->get_text_extents(tick.second, extents); + if(maxHeight < extents.height) + maxHeight = extents.height; + } + _height = maxHeight*2 + 10; + Cairo::TextExtents extents; - _cairo->get_text_extents(tick.caption, extents); - if(maxHeight < extents.height) - maxHeight = extents.height; + _cairo->get_text_extents(_tickSet->GetTick(_tickSet->Size()-1).second, extents); + _rightMargin = extents.width/2+5 > 10 ? extents.width/2+5 : 10; + + _metricsAreInitialized = true; } - _height = maxHeight*2 + 10; - _metricsAreInitialized = true; - - Cairo::TextExtents extents; - _cairo->get_text_extents(_visibleLargeTicks.rbegin()->caption, extents); - _rightMargin = extents.width/2+5 > 10 ? extents.width/2+5 : 10; } } -void HorizontalPlotScale::setVisibleTicks() +void HorizontalPlotScale::InitializeNumericTicks(double min, double max) { + if(_tickSet != 0) + delete _tickSet; + _tickSet = new NumericTickSet(min, max, 14); +} - std::map<double, Tick> ticks; - for(std::vector<Tick>::const_iterator i=_largeTicks.begin();i!=_largeTicks.end();++i) - ticks.insert(std::pair<double, Tick>(i->normValue, *i)); - - if(!ticksFit(ticks)) - { - size_t tryCount = 2; - - while(tryCount < _largeTicks.size()) - { - tryCount *= 2; - ticks.clear(); - for(size_t i=0;i<tryCount;++i) - { - size_t index = (i * _largeTicks.size() / tryCount); - Tick tick = _largeTicks[index]; - ticks.insert(std::pair<double, Tick>(tick.normValue, tick)); - } - } - tryCount /= 2; - ticks.clear(); - for(size_t i=0;i<tryCount;++i) - { - size_t index = (i * _largeTicks.size() / tryCount); - Tick tick = _largeTicks[index]; - ticks.insert(std::pair<double, Tick>(tick.normValue, tick)); - } - } - _visibleLargeTicks.clear(); - for(std::map<double, Tick>::const_iterator i=ticks.begin();i!=ticks.end();++i) - _visibleLargeTicks.push_back(i->second); +void HorizontalPlotScale::InitializeTimeTicks(double timeMin, double timeMax) +{ + if(_tickSet != 0) + delete _tickSet; + _tickSet = new TimeTickSet(timeMin, timeMax, 14); } -bool HorizontalPlotScale::ticksFit(std::map<double, Tick> &/*ticks*/) +bool HorizontalPlotScale::ticksFit() { /*double pos = 0.0; for(std::map<double, Tick>::const_iterator i= ticks.begin();i!=ticks.end();++i) diff --git a/CEP/DP3/AOFlagger/src/gui/plot/verticalplotscale.cpp b/CEP/DP3/AOFlagger/src/gui/plot/verticalplotscale.cpp index a406692ab45..3a36ebbde04 100644 --- a/CEP/DP3/AOFlagger/src/gui/plot/verticalplotscale.cpp +++ b/CEP/DP3/AOFlagger/src/gui/plot/verticalplotscale.cpp @@ -19,16 +19,18 @@ ***************************************************************************/ #include <AOFlagger/gui/plot/verticalplotscale.h> -#include <map> +#include <AOFlagger/gui/plot/tickset.h> VerticalPlotScale::VerticalPlotScale(Glib::RefPtr<Gdk::Drawable> drawable) - : _plotWidth(0), _plotHeight(0), _metricsAreInitialized(false), _drawable(drawable) + : _plotWidth(0), _plotHeight(0), _metricsAreInitialized(false), _drawable(drawable), _tickSet(0) { _cairo = _drawable->create_cairo_context(); } VerticalPlotScale::~VerticalPlotScale() { + if(_tickSet != 0) + delete _tickSet; } double VerticalPlotScale::GetWidth() @@ -37,18 +39,20 @@ double VerticalPlotScale::GetWidth() return _width; } -void VerticalPlotScale::Draw(Cairo::RefPtr<Cairo::Context> cairo) +void VerticalPlotScale::Draw(Cairo::RefPtr<Cairo::Context> cairo, double offsetX, double offsetY) { _cairo = cairo; initializeMetrics(); _cairo->set_source_rgb(0.0, 0.0, 0.0); _cairo->set_font_size(16.0); - for(std::vector<Tick>::const_iterator i=_visibleLargeTicks.begin();i!=_visibleLargeTicks.end();++i) + for(unsigned i=0;i!=_tickSet->Size();++i) { + const Tick tick = _tickSet->GetTick(i); Cairo::TextExtents extents; - _cairo->get_text_extents(i->caption, extents); - _cairo->move_to(_width - extents.width - 5, i->normValue * _plotHeight - extents.height/2 - extents.y_bearing + _topMargin); - _cairo->show_text(i->caption); + _cairo->get_text_extents(tick.second, extents); + _cairo->move_to(_width - extents.width - 5 + offsetX, + (1.0-tick.first) * _plotHeight - extents.height/2 - extents.y_bearing + _topMargin + offsetY); + _cairo->show_text(tick.second); } _cairo->stroke(); } @@ -57,59 +61,36 @@ void VerticalPlotScale::initializeMetrics() { if(!_metricsAreInitialized) { - setVisibleTicks(); - _cairo->set_font_size(16.0); - double maxWidth = 0; - for(std::vector<Tick>::const_iterator i=_visibleLargeTicks.begin();i!=_visibleLargeTicks.end();++i) + if(_tickSet != 0) { - Tick tick = *i; - Cairo::TextExtents extents; - _cairo->get_text_extents(tick.caption, extents); - if(maxWidth < extents.width) - maxWidth = extents.width; + while(!ticksFit() && _tickSet->Size() > 1) + { + _tickSet->DecreaseTicks(); + } + _cairo->set_font_size(16.0); + double maxWidth = 0; + for(unsigned i=0;i!=_tickSet->Size();++i) + { + Tick tick = _tickSet->GetTick(i); + Cairo::TextExtents extents; + _cairo->get_text_extents(tick.second, extents); + if(maxWidth < extents.width) + maxWidth = extents.width; + } + _width = maxWidth + 10; + _metricsAreInitialized = true; } - _width = maxWidth + 10; - _metricsAreInitialized = true; } } -void VerticalPlotScale::setVisibleTicks() +void VerticalPlotScale::InitializeNumericTicks(double min, double max) { - - std::map<double, Tick> ticks; - for(std::vector<Tick>::const_iterator i=_largeTicks.begin();i!=_largeTicks.end();++i) - ticks.insert(std::pair<double, Tick>(i->normValue, *i)); - - if(!ticksFit(ticks)) - { - size_t tryCount = 2; - - while(tryCount < _largeTicks.size()) - { - tryCount *= 2; - ticks.clear(); - for(size_t i=0;i<tryCount;++i) - { - size_t index = (i * _largeTicks.size() / tryCount); - Tick tick = _largeTicks[index]; - ticks.insert(std::pair<double, Tick>(tick.normValue, tick)); - } - } - tryCount /= 2; - ticks.clear(); - for(size_t i=0;i<tryCount;++i) - { - size_t index = (i * _largeTicks.size() / tryCount); - Tick tick = _largeTicks[index]; - ticks.insert(std::pair<double, Tick>(tick.normValue, tick)); - } - } - _visibleLargeTicks.clear(); - for(std::map<double, Tick>::const_iterator i=ticks.begin();i!=ticks.end();++i) - _visibleLargeTicks.push_back(i->second); + if(_tickSet == 0) + delete _tickSet; + _tickSet = new NumericTickSet(min, max, 20); } -bool VerticalPlotScale::ticksFit(std::map<double, Tick> &/*ticks*/) +bool VerticalPlotScale::ticksFit() { //Cairo::TextExtents extents; //cr->get_text_extents(tick.caption, extents); diff --git a/CEP/DP3/AOFlagger/src/gui/timefrequencywidget.cpp b/CEP/DP3/AOFlagger/src/gui/timefrequencywidget.cpp index ff09cbb1cae..4b532c57df9 100644 --- a/CEP/DP3/AOFlagger/src/gui/timefrequencywidget.cpp +++ b/CEP/DP3/AOFlagger/src/gui/timefrequencywidget.cpp @@ -28,8 +28,9 @@ #include <iostream> -#include <AOFlagger/gui/plot/horizontaltimescale.h> -#include <AOFlagger/gui/plot/verticalnumericscale.h> +#include <AOFlagger/gui/plot/horizontalplotscale.h> +#include <AOFlagger/gui/plot/verticalplotscale.h> +#include <AOFlagger/gui/plot/colorscale.h> TimeFrequencyWidget::TimeFrequencyWidget() : _isInitialized(false), _showOriginalFlagging(true), _showAlternativeFlagging(true), _useColor(true), _colorMap(TFBWMap), @@ -39,6 +40,7 @@ TimeFrequencyWidget::TimeFrequencyWidget() : _segmentedImage(), _horiScale(0), _vertScale(0), + _colorScale(0), _max(1.0), _min(0.0), _range(Winsorized) { @@ -118,17 +120,40 @@ void TimeFrequencyWidget::Update() size_t width = _endTime - _startTime; size_t height = _endFrequency - _startFrequency; + switch(_visualizedImage) + { + case TFOriginalImage: _image = _original.GetSingleImage(); break; + case TFRevisedImage: _image = _revised.GetSingleImage(); break; + case TFContaminatedImage: _image = _contaminated.GetSingleImage(); break; + case TFDifferenceImage: + _image = Image2D::CreateFromDiff(_original.GetSingleImage(), _revised.GetSingleImage()); + break; + } + + num_t min, max; + Mask2DCPtr mask = GetActiveMask(); + findMinMax(_image, mask, min, max); + if(_horiScale != 0) delete _horiScale; if(_vertScale != 0) delete _vertScale; + if(_colorScale != 0) + delete _colorScale; if(_metaData != 0) { - _vertScale = new VerticalNumericScale(get_window(), _metaData->Band().channels[_startFrequency].frequencyHz / 1e6, _metaData->Band().channels[_endFrequency-1].frequencyHz / 1e6); - _horiScale = new HorizontalTimeScale(get_window(), _metaData->ObservationTimes()[_startTime], _metaData->ObservationTimes()[_endTime-1]); + _vertScale = new VerticalPlotScale(get_window()); + _vertScale->InitializeNumericTicks(_metaData->Band().channels[_startFrequency].frequencyHz / 1e6, _metaData->Band().channels[_endFrequency-1].frequencyHz / 1e6); + + _horiScale = new HorizontalPlotScale(get_window()); + _horiScale->InitializeTimeTicks(_metaData->ObservationTimes()[_startTime], _metaData->ObservationTimes()[_endTime-1]); } else { - _vertScale = new VerticalNumericScale(get_window(), _startFrequency, _endFrequency-1); - _horiScale = new HorizontalTimeScale(get_window(), _startTime, _endTime-1); + _vertScale = new VerticalPlotScale(get_window()); + _vertScale->InitializeNumericTicks(_startFrequency, _endFrequency-1); + _horiScale = new HorizontalPlotScale(get_window()); + _horiScale->InitializeNumericTicks(_startTime, _endTime-1); } + _colorScale = new ColorScale(get_window()); + _colorScale->InitializeNumericTicks(min, max); _leftBorderSize = _vertScale->GetWidth(); _rightBorderSize = _horiScale->GetRightMargin(); @@ -136,25 +161,23 @@ void TimeFrequencyWidget::Update() _bottomBorderSize = _horiScale->GetHeight(); ColorMap *colorMap = createColorMap(); + for(unsigned x=0;x<256;++x) + { + const num_t + colorVal = (2.0 / 256.0) * x - 1.0, + imageVal = (max-min) * x / 256.0 + min; + double + r = colorMap->ValueToColorR(colorVal), + g = colorMap->ValueToColorG(colorVal), + b = colorMap->ValueToColorB(colorVal); + _colorScale->SetColorValue(imageVal, r/255.0, g/255.0, b/255.0); + } unsigned sampleSize = 8; _pixbuf.clear(); _pixbuf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, true, sampleSize, width, height); - switch(_visualizedImage) - { - case TFOriginalImage: _image = _original.GetSingleImage(); break; - case TFRevisedImage: _image = _revised.GetSingleImage(); break; - case TFContaminatedImage: _image = _contaminated.GetSingleImage(); break; - case TFDifferenceImage: - _image = Image2D::CreateFromDiff(_original.GetSingleImage(), _revised.GetSingleImage()); - break; - } - - num_t min, max; - Mask2DCPtr mask = GetActiveMask(); - findMinMax(_image, mask, min, max); guint8* data = _pixbuf->get_pixels(); size_t rowStride = _pixbuf->get_rowstride(); @@ -167,7 +190,7 @@ void TimeFrequencyWidget::Update() Mask2DCPtr altMask = _contaminated.GetSingleMask(); for(unsigned long y=_startFrequency;y<_endFrequency;++y) { - guint8* rowpointer = data + rowStride * (y - _startFrequency); + guint8* rowpointer = data + rowStride * (_endFrequency - y - 1); for(unsigned long x=_startTime;x<_endTime;++x) { int xa = (x-_startTime) * 4; char r,g,b,a; @@ -282,12 +305,22 @@ void TimeFrequencyWidget::redraw() cairo->rectangle(0, 0, get_width(), get_height()); cairo->fill(); - _pixbuf->scale_simple(get_width() - (int) floor(_leftBorderSize + _rightBorderSize), get_height() - (int) floor(_topBorderSize + _bottomBorderSize), Gdk::INTERP_BILINEAR)->render_to_drawable(get_window(), get_style()->get_black_gc(), + double rightBorder = _rightBorderSize; + _colorScale->SetPlotDimensions(get_width() - rightBorder, get_height()-_topBorderSize - _bottomBorderSize - 10.0, _topBorderSize + 10.0); + rightBorder += _colorScale->GetWidth() + 5.0; + _vertScale->SetPlotDimensions(get_width() - rightBorder, get_height() - _topBorderSize - _bottomBorderSize, _topBorderSize); + _horiScale->SetPlotDimensions(get_width() - rightBorder, get_height()-_topBorderSize - _bottomBorderSize, _topBorderSize, _vertScale->GetWidth()); + + int + width = get_width() - (int) floor(_leftBorderSize + rightBorder), + height = get_height() - (int) floor(_topBorderSize + _bottomBorderSize); + _pixbuf->scale_simple(width, height, Gdk::INTERP_BILINEAR)->render_to_drawable(get_window(), get_style()->get_black_gc(), 0, 0, (int) round(_leftBorderSize), (int) round(_topBorderSize), -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); + cairo->set_source_rgb(0.0, 0.0, 0.0); + cairo->rectangle(round(_leftBorderSize), round(_topBorderSize), width, height); + cairo->stroke(); - _vertScale->SetPlotDimensions(get_width() - _rightBorderSize, get_height() - _topBorderSize - _bottomBorderSize, _topBorderSize); - _horiScale->SetPlotDimensions(get_width() - _rightBorderSize, get_height()-_topBorderSize - _bottomBorderSize, _topBorderSize, _vertScale->GetWidth()); - + _colorScale->Draw(cairo); _vertScale->Draw(cairo); _horiScale->Draw(cairo); } -- GitLab