AxisLegendManager.cc 11.5 KB
#include "AxisLegendManager.hh"

#include "ParamMgr.hh"

using namespace AMDA::Info;

namespace plot
{

void AxisLegendManager::configureYAxisLegendForSeries(
		PanelPlotOutput* plot)
{
	SeriesProperties lSeriesProperties;

	// Retrieve ParamInfo Manager
	ParamMgr* piMgr = ParamMgr::getInstance();

	std::map<std::string, bool> yAxisIdHasMultiLineLegend;
	std::map<std::string, std::string> generatedYAxisLegend;

	// Parse each parameter and series to determine if axis requires
	// single or multiline legends
	for (auto param: plot->_parameterAxesList)
	{
		for(auto index: param.getYSerieIndexList(plot->_pParameterValues))
		{
			lSeriesProperties = param.getYSeriePropertiesAt(index);
			if(!lSeriesProperties.hasYAxis())
				continue;

			std::string yAxisId = lSeriesProperties.getYAxisId();

			if (yAxisIdHasMultiLineLegend.count(yAxisId) == 0) {
				yAxisIdHasMultiLineLegend [yAxisId] = true;
			}

			for (auto idx : plot->getParamUsedIndexes (lSeriesProperties.getParamId(),
					(*plot->_pParameterValues)[lSeriesProperties.getParamId()].getDim1Size(),
					(*plot->_pParameterValues)[lSeriesProperties.getParamId()].getDim2Size())) {
				// All indexes requested for the parameter,
				// one general legend is sufficient
				if (idx == AMDA::Common::ParameterIndexComponent(-1,-1)) {
					yAxisIdHasMultiLineLegend [yAxisId] = false;
				}
			}
		}
	}

	// Build single or multiline line legend for axis
	for (auto param: plot->_parameterAxesList)
	{
		// Get number of series to draw
		// For each index of parameter identify to which axis series must be drawn.
		for(auto index: param.getYSerieIndexList(plot->_pParameterValues))
		{
			lSeriesProperties = param.getYSeriePropertiesAt(index);
			if(!lSeriesProperties.hasYAxis())
				continue;

			std::string yAxisId = lSeriesProperties.getYAxisId();

			boost::shared_ptr<Axis> lYAxis = plot->_panel->getAxis(yAxisId);
			if (lYAxis.get() == nullptr) {
				std::stringstream lError;
				lError << "AxisLegendManager::configureYAxisLegend : Y axis with id '" << yAxisId << "' not found.";
				BOOST_THROW_EXCEPTION(PanelPlotOutputException() << AMDA::ex_msg(lError.str()));
			}

			// If axis legend already set, nothing to do
			if (lYAxis->_legend._text.empty() == false)
				continue;

			// Otherwise, build multi or single line legend depending on paramInfo availability
			ParameterSPtr p = plot->_parameterManager.getParameter(lSeriesProperties.getParamId());
			ParamInfoSPtr	paramInfo = piMgr->getParamInfoFromId(p->getInfoId());
			if (paramInfo == nullptr)
				continue;

			// Single line legend
			if (yAxisIdHasMultiLineLegend [yAxisId] == false)
			{
				if (generatedYAxisLegend.count(yAxisId) == 0)
				{
					// legend is build using short_name, units, coordinates_system
					std::stringstream legendInfo;
					legendInfo << paramInfo->getShortName();

					if (paramInfo->getUnits().empty() == false)
						legendInfo << ", " + paramInfo->getUnits();

					if (paramInfo->getCoordinatesSystem().empty() == false)
						legendInfo << ", " + paramInfo->getCoordinatesSystem();

					generatedYAxisLegend [yAxisId] = legendInfo.str();
				}
			}
			else
			{
				// legend is build using short_name, units, coordinates_system
				std::stringstream legendInfo;
				legendInfo << paramInfo->getShortName();

				if ((index.getDim1Index() != -1) || (index.getDim2Index() != -1))
				{
					if (paramInfo->getComponents(index).empty() == false)
						legendInfo << ", " << paramInfo->getComponents(index);
					else
					{
						legendInfo << ", " << paramInfo->getShortName() << "[" << index.getDim1Index();
						if (index.getDim2Index() != -1)
							legendInfo << "," << index.getDim2Index();
						legendInfo << "]";
					}
				}

				if (paramInfo->getUnits().empty() == false)
					legendInfo << ", " + paramInfo->getUnits();

				if (paramInfo->getCoordinatesSystem().empty() == false)
					legendInfo << ", " + paramInfo->getCoordinatesSystem();

				if (generatedYAxisLegend [yAxisId].empty() == false)
					generatedYAxisLegend [yAxisId] += Label::DELIMITER;

				generatedYAxisLegend [yAxisId] += legendInfo.str();
			}
		}
	}

	// Build generated sequence if required
	for (auto axisLegend : generatedYAxisLegend) {
		plot->_panel->getAxis (axisLegend.first)->_legend._text = axisLegend.second;
	}
}

void AxisLegendManager::configureColorAxisLegendForSeries(
		PanelPlotOutput* plot)
{
	// Retrieve ParamInfo Manager
	ParamMgr 		*piMgr =ParamMgr::getInstance();

	SeriesProperties lSeriesProperties;

	// Build Z axis leged for colored param
	boost::shared_ptr<ColorAxis> lZAxis = plot->_panel->getColorAxis();
	ColorSeriesProperties lColorSerieProperties;
	std::vector<std::string> zLegendLines;

	if ((lZAxis != nullptr) && lZAxis->_legend._text.empty())
	{
		for (auto param: plot->_parameterAxesList)
		{
			for(auto index: param.getYSerieIndexList(plot->_pParameterValues))
			{
				lSeriesProperties = param.getYSeriePropertiesAt(index);
				if(!lSeriesProperties.hasYAxis())
					continue;
				//check if a colored param is defined for this serie
				if(lSeriesProperties.getColorParamId().empty())
					continue;
				//get info about colored param
				ParameterSPtr p = plot->_parameterManager.getParameter(lSeriesProperties.getColorParamId());
				ParamInfoSPtr	paramInfo = piMgr->getParamInfoFromId(p->getInfoId());
				//get colored serie properties
				ParameterAxes* colorSerieParameterAxes = plot->getParameterAxesByColorSerieId(lSeriesProperties.getColorSerieId());
				if (colorSerieParameterAxes == NULL)
					continue;
				lColorSerieProperties = colorSerieParameterAxes->getColorSeriePropertiesById(lSeriesProperties.getColorSerieId());
				if (paramInfo != nullptr)
				{
					std::stringstream legendInfo;

					legendInfo << paramInfo->getShortName();

					if (lColorSerieProperties.getIndex() != -1)
					{
						if (paramInfo->getComponents(index).empty() == false)
							legendInfo << ", " << paramInfo->getComponents(lColorSerieProperties.getIndex());
						else
							legendInfo << ", " << paramInfo->getShortName() << "[" << lColorSerieProperties.getIndex() << "]" ;
					}

					if (paramInfo->getUnits().empty() == false)
						legendInfo << ", " + paramInfo->getUnits();

					if (paramInfo->getCoordinatesSystem().empty() == false)
						legendInfo << ", " + paramInfo->getCoordinatesSystem();

					if (std::find(zLegendLines.begin(), zLegendLines.end(), legendInfo.str()) == zLegendLines.end())
						zLegendLines.push_back(legendInfo.str());
				}
			}
		}
		bool isFirstLine = true;
		for (auto line : zLegendLines)
		{
			if (!isFirstLine)
				lZAxis->_legend._text += Label::DELIMITER;
			isFirstLine = false;
			lZAxis->_legend._text += line;
		}
	}
}

void AxisLegendManager::configureXAxisLegendForSeries(
		XYPlot* plot)
{
	// Retrieve ParamInfo Manager
	ParamMgr 		*piMgr =ParamMgr::getInstance();

	SeriesProperties lSeriesProperties;

	std::map<std::string, bool> xAxisIdHasMultiLineLegend;
	std::map<std::string, std::list<std::string>> generatedXAxisLegend;

	// Parse each parameter and series to determine if axis requires
	// single or multiline legends
	for (auto param: plot->_parameterAxesList)
	{
		for(auto index: param.getYSerieIndexList(plot->_pParameterValues))
		{
			lSeriesProperties = param.getYSeriePropertiesAt(index);
			if(!lSeriesProperties.hasYAxis() || !lSeriesProperties.hasXAxis())
				continue;

			ParameterAxes& xParameter = plot->getParameterAxeOnXAxis(lSeriesProperties.getXAxisId());

			std::string yParamId = lSeriesProperties.getParamId();

			XSeriesProperties& xSerie = plot->getSerieOnXAxisfromParameter(lSeriesProperties.getXAxisId(), xParameter);

			std::string xAxisId = xSerie.getAxisId();

			if (xAxisIdHasMultiLineLegend.count(xAxisId) == 0) {
				xAxisIdHasMultiLineLegend [xAxisId] = true;
			}

			for (auto idx : plot->getParamUsedIndexes (xSerie.getXParamIds()[yParamId],
					(*plot->_pParameterValues)[xSerie.getXParamIds()[yParamId]].getDim1Size(),
					(*plot->_pParameterValues)[xSerie.getXParamIds()[yParamId]].getDim2Size())) {
				// All indexes requested for the parameter,
				// one general legend is susficient
				if (idx == AMDA::Common::ParameterIndexComponent(-1,-1)) {
					xAxisIdHasMultiLineLegend [xAxisId] = false;
				}
			}
		}
	}

	// Build single line legend for axis
	for (auto param: plot->_parameterAxesList) {
		for(auto index: param.getYSerieIndexList(plot->_pParameterValues))
		{
			lSeriesProperties = param.getYSeriePropertiesAt(index);
			if(!lSeriesProperties.hasYAxis() || !lSeriesProperties.hasXAxis())
				continue;

			ParameterAxes& xParameter = plot->getParameterAxeOnXAxis(lSeriesProperties.getXAxisId());

			std::string yParamId = lSeriesProperties.getParamId();

			XSeriesProperties& xSerie = plot->getSerieOnXAxisfromParameter(lSeriesProperties.getXAxisId(), xParameter);

			std::string xAxisId = xSerie.getAxisId();

			boost::shared_ptr<Axis> lXAxis = plot->_panel->getAxis(xAxisId);
			if (lXAxis.get() == nullptr) {
				std::stringstream lError;
				lError << "AxisLegendManager::configureXAxisLegendForSeries X axis with id '" << xAxisId << "' not found.";
				BOOST_THROW_EXCEPTION(PanelPlotOutputException() << AMDA::ex_msg(lError.str()));
			}

			// If axis legend already set, nothing to do
			if (lXAxis->_legend._text.empty() == false)
				continue;

			// Otherwise, build multi or single line legend depending on paramInfo availability
			ParameterSPtr p = plot->_parameterManager.getParameter(xSerie.getXParamIds()[yParamId]);
			ParamInfoSPtr	paramInfo = piMgr->getParamInfoFromId(p->getInfoId());

			if (paramInfo == nullptr)
				continue;

			// Single line legend
			if (xAxisIdHasMultiLineLegend [xAxisId] == false) {
				if (generatedXAxisLegend.count(xAxisId) == 0) {
					// legend is build using short_name, units, coordinates_system
					std::stringstream legendInfo;
					legendInfo << paramInfo->getShortName();

					if (paramInfo->getUnits().empty() == false)
						legendInfo << ", " + paramInfo->getUnits();

					if (paramInfo->getCoordinatesSystem().empty() == false)
						legendInfo << ", " + paramInfo->getCoordinatesSystem();

					generatedXAxisLegend [xAxisId].push_back(legendInfo.str());
				}
			} else {
				// legend is build using short_name, units, coordinates_system
				std::stringstream legendInfo;
				legendInfo << paramInfo->getShortName();

				if ((xSerie.getIndex().getDim1Index() != -1) || (xSerie.getIndex().getDim2Index() != -1)) {
					if (paramInfo->getComponents(xSerie.getIndex()).empty() == false)
						legendInfo << ", " << paramInfo->getComponents(xSerie.getIndex());
					else
					{
						legendInfo << ", " << paramInfo->getShortName() << "[" << xSerie.getIndex().getDim1Index();
						if (xSerie.getIndex().getDim2Index() != -1)
							legendInfo << "," << xSerie.getIndex().getDim2Index();
						legendInfo << "]";
					}
				}

				if (paramInfo->getUnits().empty() == false)
					legendInfo << ", " + paramInfo->getUnits();

				if (paramInfo->getCoordinatesSystem().empty() == false)
					legendInfo << ", " + paramInfo->getCoordinatesSystem();

				if (std::find(generatedXAxisLegend [xAxisId].begin(),generatedXAxisLegend [xAxisId].end(), legendInfo.str()) == generatedXAxisLegend [xAxisId].end())
					//new legend to add
					generatedXAxisLegend [xAxisId].push_back(legendInfo.str());
			}
		}
	}

	// Build generated sequence if required
	for (auto axisLegends : generatedXAxisLegend)
	{
		std::stringstream fullLegend;
		bool isFirstLegend = true;
		for (auto legend : axisLegends.second)
		{
			if (!isFirstLegend)
				fullLegend << Label::DELIMITER;
			fullLegend << legend;
			isFirstLegend = false;
		}
		plot->_panel->getAxis (axisLegends.first)->_legend._text = fullLegend.str();
	}
}

} /* namespace plot */