DefaultTimeAxisDecorator.cc 4.59 KB
/*
 * DefaultTimeAxisDecorator.cc
 *
 *  Created on: Dec 17, 2013
 *      Author: amdadev
 */

#include "DefaultTimeAxisDecorator.hh"
#include "plplot/plplot.h"

#include "plplot/plstream.h"

#include "PlotLogger.hh"
#include "TimeAxis.hh"
#include "TimePlot.hh"
#include "PlPlotUtil.hh"

namespace plot {



void DefaultTimeAxisDecorator::updatePlotArea( PanelPlotOutput* pplot_,Axis* axis_, const Bounds& /*panelBounds_*/, Bounds& bounds_){

	TimeAxis* pAxis = static_cast<TimeAxis*> (axis_);
	Font font(pplot_->_panel->getFont());
	PlPlotUtil::setPlFont(font);
	CharSize lCharSizePanel = PlPlotUtil::getCharacterSizeInPlPage(pplot_->_panel->_page);
	double panelCharHeight 	= lCharSizePanel.second;
	double lBottomSpace = 0;

	if (pAxis->_visible == true) {
		if (pAxis->_position == PlotCommon::Position::POS_TOP) {
			// When X axis is at top edge of plot area, there is only room for tick.
			// So add space for start date
			lBottomSpace += panelCharHeight * 2;
		} else {
			// Add space to have start date visible.
			// Otherwise, space was calculated to draw legend and so space is sufficient to draw start date.
			// Only if panel font size is not twice time high than legend font size.
			if ((pAxis->_showLegend == true) &&
				(pAxis->_showTickMark == true) &&
				(pAxis->_legend.isEmpty() == true)) {
				lBottomSpace += panelCharHeight * 2;
			}
		}
	} else {
		// when axis is not visible PanelPlotOutput set at least one character height by default.
		// So we just have to push two character height (for text and space bottom).
		lBottomSpace = panelCharHeight * 2;
	}

	// update y and height; x and width are left unchanged.
	bounds_._y += lBottomSpace;
	bounds_._height -= lBottomSpace;
}

void DefaultTimeAxisDecorator::configure
	(
	PanelPlotOutput* pplot_,
	Axis* axis_,
	double start_,
	double stop_,
	std::map<std::string, ParameterData> *pParameterValues
	)
{
	_pParameterValues = pParameterValues;

	// retrieve time axis
	TimeAxis* timeAxis = static_cast<TimeAxis*> (axis_);

	// configure x axis range
	timeAxis->setRange( start_, stop_ );

	// store plplot format
	setPlFormat( getPlTimeFormat(
					timeAxis->_timeFormat,
					timeAxis->getRange().getMin(),
					timeAxis->getRange().getMax(),
					getMajorTickNumber(	timeAxis,
										timeAxis->getRange().getMin(),
										timeAxis->getRange().getMax())) );

	// install label generator
	installLabelGenerator(pplot_, timeAxis);
}

void DefaultTimeAxisDecorator::draw( PanelPlotOutput* /*pplot_*/,Axis* /*axis_*/, std::shared_ptr<plstream> /*pls_*/){
	// nothing to draw...

}

void DefaultTimeAxisDecorator::installLabelGenerator(PanelPlotOutput* /*pplot_*/, TimeAxis* timeAxis_) {

	// setup a custom labeler for time axis, give it time format and
	// min time to not display this min time on axis label
	std::ostringstream data;
	data << std::setprecision(10) << std::min(timeAxis_->getRange().getMin(), timeAxis_->getRange().getMax()) << "#"
				<< getPlFormat();
	_timeFormat->assign(data.str());
	timeAxis_->_labelGenerator->_data = _timeFormat.get();
	if (timeAxis_->_showTickMark == true) {
		timeAxis_->_labelGenerator->_function = generateDefaultTimeLabel;
	} else {
		timeAxis_->_labelGenerator->_function = generateNoTimeLabel;
	}


}

/***************************** EXTERNAL METHODS ********************************/

void generateDefaultTimeLabel(PLINT axis, PLFLT value, char *label, PLINT length,
		PLPointer data) {
	if (axis == PL_X_AXIS) {
		// get time format and min value
		// if value equals min, display an empty string
		// otherwise, format time and display formatted time
		std::string* dataStr =(std::string*) data;
		if( dataStr == nullptr ){
			std::cout << "WARNING NO FORMAT FOUND !!!" << std::endl;
		}

		size_t sharpIndex = dataStr->find("#");
		double min = atof(dataStr->substr(0, sharpIndex).c_str());

		if (value == min) {
			// do not display min value label
			// but display title :
			snprintf(label, length, "%s", "");

		} else {
			// display formatted time
			std::string timeFormatstr = dataStr->substr(sharpIndex + 1).c_str();
			char *timeFormat = new char[timeFormatstr.length() + 1];
			strcpy(timeFormat, timeFormatstr.c_str());

			if (TimePlot::qsasconfig == NULL) {
				configqsas(1. / 86400., 0., 0., 0x0, 1, 1970, 0, 1, 0, 0, 0.,
						&TimePlot::qsasconfig);
			}
			char formattedTime[40];
			strfqsas(formattedTime, 40, timeFormat, (double) value,	TimePlot::qsasconfig);
			delete[] timeFormat;

			snprintf(label, length, "%s", formattedTime);
		}
	}
}

void generateNoTimeLabel(PLINT /*axis*/, PLFLT /*value*/, char *label, PLINT /*length*/, PLPointer /*data*/) {
	// Builds an empty Time label
	label [0] = 0;
}


} /* namespace plot */