/* * Axis.hh * * Created on: 20 nov. 2013 * Author: guillaume */ #ifndef AXIS_HH_ #define AXIS_HH_ #include "Color.hh" #include "PlotCommon.hh" #include "Range.hh" #include "Tick.hh" #include "AxisLegend.hh" #include "ConstantLine.hh" #include "ContextFileWriter.hh" #include #include namespace plot { typedef void (*LabelGeneratorFunction)(PLINT, PLFLT, char *, PLINT, void *); struct LabelGenerator { LabelGenerator() : _function(nullptr), _data(nullptr) { } virtual ~LabelGenerator() { } LabelGeneratorFunction _function; PLPointer _data; }; class DefaultPlotConfiguration; class Panel; class Axis { public: enum Scale { LOGARITHMIC, LINEAR }; Axis(bool isZAxis = false); Axis(const Axis& axis); virtual ~Axis(); virtual Range getRange() { if (_reverse) { Range lRange(_range.getMax(), _range.getMin()); lRange._extend = _range._extend; return lRange; } else { return _range; } } virtual Range getRequestedRange() { if (_reverse) { Range lRange(_requestedRange.getMax(), _requestedRange.getMin()); lRange._extend = _requestedRange._extend; return lRange; } else { return _requestedRange; } } void setRange(Range const& pRange) { _range = pRange; } void setRange(double pMin, double pMax) { _range.setMin(pMin); _range.setMax(pMax); } void setRequestedRange(double pMin, double pMax) { setRange(pMin, pMax); _requestedRange.setMin(pMin); _requestedRange.setMax(pMax); } void setExtended(bool pExtend) { _range._extend = pExtend; } bool isExtended() { return _range._extend; } bool isZAxis() { return _isZAxis; } Font getLegendFont(Panel* pPanel); /** * @brief Write axis context */ void writeContext(ContextFileWriter& writer); /** * @brief axis identifier (associated to parameter) */ std::string _id; /** * @brief _color Color of axis and so color used to plot parameter(s) */ Color _color; /** * @brief _origin, to draw y axis on origin (must be 0) */ double _origin; /** * @brief _position left, right for abscissa axis and top, bottom for ordinate axis. */ PlotCommon::Position _position; /** * @brief _reverse Tell if axis is in reversed orientation [0;100] => [100;0] */ bool _reverse; /** * @brief _tick Define graduation for minor and major tick */ Tick _tick; /** * @brief Is axis virtual or not */ bool _visible; /** * @brief Axis is used for the plot or not */ bool _used; /** * @brief Axis draw thickness */ int _thickness; /** * @brief Axis legend definition */ AxisLegend _legend; /** * @brief _drawn Define if axis is already drawn (true) or not (false). */ bool _drawn; /** * @brief _additionalObjDrawn Define if additional objects were already drawn (true) or not (false). */ bool _additionalObjDrawn; /** * @brief _isZAxis Define if it's a ZAxis. */ bool _isZAxis; /** * @brief Set axis scale (linear or logarithmic). */ void setScale(const std::string& value) { if (value == "linear") { _scale = Scale::LINEAR; } else if (value == "logarithmic") { _scale = Scale::LOGARITHMIC; } } Scale _scale; /** * @brief Set Legend visibility flag for an axis */ void setShowLegend(bool showLegend) { _showLegend = showLegend; } bool _showLegend; /** * @brief Set TickMark visibility flag for an axis */ void setShowTickMark(bool showTickMark) { _showTickMark = showTickMark; } bool _showTickMark; /** * @brief For TU */ virtual void dump(std::ostream& out); /** * @brief Gets string options for the current axis according to previous properties. */ virtual std::string getPlotOpt(); /** * @brief Gets automatically calculated major tick space, default is 0 * to let plplot do it itself */ virtual double getAutoMajorTickSpace(double /*min*/, double /*max*/) { return 0; } /** * @brief Gets automatically calculated minor tick number between 2 major ticks, default is 0 * to let plplot do it itself */ virtual double getAutoMinorTickNumber(double /*min*/, double /*max*/) { return 0; } /** * @brief Gets adjusted value according to axis specifications as log scale, min, max. * by default returns originalValues_. * @param originalValues_ IN values * @param size_ IN number of values * @param min_ min value * @param max_ max value */ virtual double* getComputedValues(double* originalValues_, int /*size_*/, double /*min_*/, double /*max*/) { return originalValues_; } /** * @brief Get tick mark size. * @note This is used to set sufficient space for tick mark to be visible */ virtual std::pair getTickMarkSize(); /** * gets the number of line for each tickMark. This information is used * by Axis::getTickMarkSize to compute tick mark bounds. * @return number of line for each tickMark. */ int getTickMarkLines() const { return _tickMarkLines; } /** * sets the number of line for each tickMark. * @param tickMarkLines_ the number of lines to take into account. */ void setTickMarkLines(int tickMarkLines_) { _tickMarkLines = tickMarkLines_; } double getAxisOffset() const { return _axisOffset; } void setAxisOffset(double axisOffset) { _axisOffset = axisOffset; } double getLegendOffset() const { return _legendOffset; } void setLegendOffset(double legendOffset) { _legendOffset = legendOffset; } std::string getAxisUnits() const { return _axisUnits; } void setAxisUnits(std::string units) { _axisUnits = units; } /** * @brief fixed tickMark width for the axe (-1 means tickmark width is computed) */ int _fixedTickMarkWidth; void setFixedTickMarkWidth(int fixedTickMarkWidth) { _fixedTickMarkWidth = fixedTickMarkWidth; } /** * _labelFunc Function used to format label. */ boost::shared_ptr _labelGenerator; /** * @brief constant lines on axis */ std::list> _constantLines; /** * @brief Reset for next time interval plot */ void resetPlot() { _drawn = false; _additionalObjDrawn = false; _range = Range(_requestedRange); _fixedTickMarkWidth = -1; for(auto constant : _constantLines) { if (constant != nullptr) constant->resetPlot(); } } private: /** * @brief _range Limit of axis */ Range _range; /* * @brief Keep the range defined in the request */ Range _requestedRange; /** * @brief number of line for tickMark */ int _tickMarkLines; /** * @brief axe offset used for multi-axes */ double _axisOffset; /* * @brief axe units */ std::string _axisUnits; /** * @brief legend offset used to positionate axis legend */ double _legendOffset; }; std::ostream& operator <<(std::ostream& out, Axis& axis); /** * @brief Gets world coordinate space between 2 major ticks, returns 0 to let * plplot do this it self. */ double getMajorTickSpace(Axis* axis, double min, double max); /** * @brief Gets number of minor tick between 2 major ones. */ int getMinorTickNumber(Axis* xAxis, double min, double max, double majorTickSpace); /** * @brief Calculates major tick number on given axis. */ double getMajorTickNumber(Axis* axis, double min, double max); } /* namespace plot */ #endif /* AXIS_HH_ */