#include "AxisLegendManager.hh" #include // std::cout #include #include using namespace AMDA::Info; namespace plot { void AxisLegendManager::configureXAxisLegendForSeries( XYPlot *plot) { // Build list of all indexes used by each parameters for each x axes std::map axesParamsComponents; // Compute nb series to draw by y axis std::map nbSeriesByYAxisMap = plot->getNbSeriesByYAxis(); SeriesProperties lSeriesProperties; for (auto param : plot->_parameterAxesList) { for (auto lSeriesProperties : param.getYSeriePropertiesList()) { if (!lSeriesProperties.hasYAxis() || !lSeriesProperties.hasXAxis()) continue; bool moreThanOneSerieForAxis = (nbSeriesByYAxisMap[lSeriesProperties.getYAxisId()] > 1); ParameterAxes *xParameter = plot->getParameterAxesByXSerieId(lSeriesProperties.getXId()); XSeriesProperties xSerie = xParameter->getXSeriePropertiesById(lSeriesProperties.getXId()); std::string xAxisId = lSeriesProperties.getXAxisId(); boost::shared_ptr lXAxis = plot->_panel->getAxis(xAxisId); if (lXAxis.get() == nullptr) { continue; } Color compLegendColor = lXAxis->_color; if (moreThanOneSerieForAxis && (lSeriesProperties.getColorSerieId() == -1) && (!plot->_panel->_page->_superposeMode)) { compLegendColor = plot->getSerieLineColor(lSeriesProperties, moreThanOneSerieForAxis); } ParameterIndexComponentColor xIndex = ParameterIndexComponentColor(xSerie.getIndex(), compLegendColor); pushComponentInList(xSerie.getParamId(), xIndex, axesParamsComponents[xAxisId]); } } if (!plot->_panel->_page->_superposeMode) { plot->resetAutomaticSerieColorCursor(); } std::list legendLines; for (auto axisParamsComponents : axesParamsComponents) { boost::shared_ptr lXAxis = plot->_panel->getAxis(axisParamsComponents.first); setAxisLegendForSeries(plot, lXAxis, axisParamsComponents.second); } } void AxisLegendManager::configureYAxisLegendForSpectro( PanelPlotOutput *plot) { for (auto param : plot->_parameterAxesList) { std::shared_ptr spectroPropertiesPtr = param.getSpectroProperties(); if (spectroPropertiesPtr == nullptr) continue; // no spectro defined if (!spectroPropertiesPtr->hasYAxis()) continue; std::string yAxisId = spectroPropertiesPtr->getYAxisId(); boost::shared_ptr lYAxis = plot->_panel->getAxis(yAxisId); if (lYAxis.get() == nullptr) continue; if (!lYAxis->_legend.isEmpty()) continue; setAxisLegendForTable(plot, lYAxis, param._originalParamId, spectroPropertiesPtr->getParamId(), spectroPropertiesPtr->getIndexes(), spectroPropertiesPtr->getRelatedDim()); return; } } void AxisLegendManager::configureYAxisLegendForSeries( PanelPlotOutput *plot) { SeriesProperties lSeriesProperties; // Compute nb series to draw by y axis std::map nbSeriesByYAxisMap = plot->getNbSeriesByYAxis(); // Build list of all indexes used by each parameters for each y axes std::map axesParamsComponents; if (!plot->_panel->_page->_superposeMode) { plot->resetAutomaticSerieColorCursor(); } for (auto param : plot->_parameterAxesList) { for (auto lSeriesProperties : param.getYSeriePropertiesList()) { if (!lSeriesProperties.hasYAxis()) continue; bool moreThanOneSerieForAxis = (nbSeriesByYAxisMap[lSeriesProperties.getYAxisId()] > 1); std::string yAxisId = lSeriesProperties.getYAxisId(); boost::shared_ptr lYAxis = plot->_panel->getAxis(yAxisId); if (lYAxis.get() == nullptr) { continue; } for (auto index : lSeriesProperties.getIndexList(plot->_pParameterValues)) { Color compLegendColor = lYAxis->_color; if (moreThanOneSerieForAxis && (lSeriesProperties.getColorSerieId() == -1) && (!plot->_panel->_page->_superposeMode)) { compLegendColor = plot->getSerieLineColor(lSeriesProperties, moreThanOneSerieForAxis); } ParameterIndexComponentColor yIndex = ParameterIndexComponentColor(index, compLegendColor); pushComponentInList(lSeriesProperties.getParamId(), yIndex, axesParamsComponents[yAxisId]); } } } if (!plot->_panel->_page->_superposeMode) { plot->resetAutomaticSerieColorCursor(); } std::list legendLines; for (auto axisParamsComponents : axesParamsComponents) { boost::shared_ptr lYAxis = plot->_panel->getAxis(axisParamsComponents.first); setAxisLegendForSeries(plot, lYAxis, axisParamsComponents.second); } } void AxisLegendManager::configureColorAxisLegendForSeries( PanelPlotOutput *plot) { SeriesProperties lSeriesProperties; ColorSeriesProperties lColorSerieProperties; boost::shared_ptr lZAxis = plot->_panel->getColorAxis(); if (lZAxis.get() == nullptr) { return; } // Build list of all indexes used by each parameters for each y axes AxisParamsComponents axisParamsComponents; for (auto param : plot->_parameterAxesList) { for (auto lSeriesProperties : param.getYSeriePropertiesList()) { if (!lSeriesProperties.hasYAxis()) continue; std::string yParamId = lSeriesProperties.getParamId(); // check if a colored param is defined for this serie if (lSeriesProperties.getColorParamId().empty()) continue; ParameterAxes *colorSerieParameterAxes = plot->getParameterAxesByColorSerieId(lSeriesProperties.getColorSerieId()); if (colorSerieParameterAxes == NULL) continue; lColorSerieProperties = colorSerieParameterAxes->getColorSeriePropertiesById(lSeriesProperties.getColorSerieId()); ParameterIndexComponentColor colorSerieIndex = ParameterIndexComponentColor(-1, -1, lZAxis->_color); if (lColorSerieProperties.getIndex() > -1) colorSerieIndex = ParameterIndexComponentColor(lColorSerieProperties.getIndex(), -1, lZAxis->_color); pushComponentInList(lColorSerieProperties.getColorParamIds()[yParamId], colorSerieIndex, axisParamsComponents); } } setAxisLegendForSeries(plot, lZAxis, axisParamsComponents); } void AxisLegendManager::configureColorAxisLegendForSpectro( PanelPlotOutput *plot) { boost::shared_ptr lZAxis = plot->_panel->getColorAxis(); if (lZAxis.get() == nullptr) { return; } for (auto param : plot->_parameterAxesList) { std::shared_ptr spectroPropertiesPtr = param.getSpectroProperties(); if (spectroPropertiesPtr == nullptr) continue; // no spectro defined if (!spectroPropertiesPtr->hasZAxis()) continue; setAxisLegendForSpectro(plot, lZAxis, param._originalParamId); break; } for (auto param : plot->_parameterAxesList) { std::shared_ptr sauvaudPropertiesPtr = param.getSauvaudProperties(); if (sauvaudPropertiesPtr == nullptr) continue; // no sauvaud defined if (!sauvaudPropertiesPtr->hasZAxis()) continue; setAxisLegendForSpectro(plot, lZAxis, param._originalParamId); break; } } void AxisLegendManager::pushComponentInList(std::string paramId, ParameterIndexComponentColor &index, AxisParamsComponents &axisParamsComponents) { if (index.getDim1Index() == -1 && index.getDim2Index() == -1) { // All indexes of this parameter are used axisParamsComponents[paramId].clear(); axisParamsComponents[paramId].push_back(index); } else { if (axisParamsComponents[paramId].size() > 0) { if (axisParamsComponents[paramId].front().getDim1Index() == -1 && axisParamsComponents[paramId].front().getDim2Index() == -1) { // Skip. All components already defined for this paramter on this axis return; } } for (auto crtIndex : axisParamsComponents[paramId]) { if ((crtIndex.getDim1Index() == index.getDim1Index()) && (crtIndex.getDim2Index() == index.getDim2Index())) { // Component already exists return; } } // Add this components for this axis axisParamsComponents[paramId].push_back(index); } } void AxisLegendManager::setAxisLegendForSeries(PanelPlotOutput *plot, boost::shared_ptr &pAxis, AxisParamsComponents &axisParamsComponents) { if (pAxis == nullptr || !pAxis->_legend.isEmpty()) { return; } // Retrieve ParamInfo Manager ParamMgr *piMgr = ParamMgr::getInstance(); for (auto paramsComponents : axisParamsComponents) { ParameterSPtr p = plot->_parameterManager.getParameter(paramsComponents.first); ParamInfoSPtr paramInfo = piMgr->getParamInfoFromId(p->getInfoId()); if (paramsComponents.second.size() == p->getDataWriterTemplate()->getParamData()->getDim1() * p->getDataWriterTemplate()->getParamData()->getDim2()) { // All components of this parameter are used by this axis => merge Color color = paramsComponents.second.front().getColor(); paramsComponents.second.clear(); paramsComponents.second.push_back(ParameterIndexComponentColor(-1, -1, color)); } bool isFirstComponent = true; for (auto components : paramsComponents.second) { if (paramInfo == nullptr) continue; Label label(pAxis->_legend.getFont(), components.getColor()); if (axisParamsComponents.size() == 1) { if (isFirstComponent) { std::string info = getMissionInstrumentInfo(paramInfo); if (!info.empty()) { label._text = info; addBreakLine(label._text); } } } else { std::string info = getMissionInfo(paramInfo); if (!info.empty()) { label._text = info + ", "; } } label._text += getParamLegend(paramInfo, components); pAxis->_legend.pushLabel(label); isFirstComponent = false; } } } void AxisLegendManager::setAxisLegendForSpectro(PanelPlotOutput *plot, boost::shared_ptr &pAxis, std::string originalParamId) { if (pAxis == nullptr || !pAxis->_legend.isEmpty()) { return; } // Retrieve ParamInfo Manager ParamMgr *piMgr = ParamMgr::getInstance(); ParameterSPtr p = plot->_parameterManager.getParameter(originalParamId); AMDA::Info::ParamInfoSPtr paramInfo = piMgr->getParamInfoFromId(p->getInfoId()); if (paramInfo == nullptr) return; Label label(pAxis->_legend.getFont(), pAxis->_legend.getColor()); addInfoPart(label._text, paramInfo->getShortName()); addInfoPart(label._text, getTransformedUnits(paramInfo->getUnits())); pAxis->_legend.setLabel(label); } void AxisLegendManager::setAxisLegendForTable(PanelPlotOutput *plot, boost::shared_ptr &pAxis, std::string originalParamId, std::string paramId, AMDA::Common::ParameterIndexComponentList &indexes, int relatedDim) { if (pAxis == nullptr || !pAxis->_legend.isEmpty()) { return; } // Retrieve ParamInfo Manager ParamMgr *piMgr = ParamMgr::getInstance(); ParameterSPtr p = plot->_parameterManager.getParameter(originalParamId); AMDA::Info::ParamInfoSPtr paramInfo = piMgr->getParamInfoFromId(p->getInfoId()); if (paramInfo == nullptr) return; Label label(pAxis->_legend.getFont(), pAxis->_legend.getColor()); std::string info = getMissionInstrumentInfo(paramInfo); if (!info.empty()) { addInfoPart(label._text, info); addBreakLine(label._text); } boost::shared_ptr tableSPtr; tableSPtr = paramInfo->getTable(relatedDim); if (tableSPtr == nullptr) { // look for unique embedded table boost::shared_ptr linkedTableSPtr; int counter = 0; for (auto pInfo : paramInfo->getLinkedParamList()) { linkedTableSPtr = AMDA::Info::ParamMgr::getInstance()->getParamInfoFromId(pInfo)->getTable(relatedDim); if (linkedTableSPtr == nullptr) continue; counter++; } if (linkedTableSPtr == nullptr || counter != 1) { LOG4CXX_DEBUG(gLogger, "table cannot be defined from linked info params"); } else { tableSPtr = linkedTableSPtr; } } if (tableSPtr == nullptr) { std::string tableInfo = "Table "; tableInfo += std::to_string(relatedDim); tableInfo += " indexes"; addInfoPart(label._text, tableInfo); pAxis->_legend.pushLabel(label); return; } if (((*plot->_pParameterValues)[paramId].getDim1Size() > 0) && ((*plot->_pParameterValues)[paramId].getDim2Size() > 0) && !indexes.empty()) { boost::shared_ptr otherTableSPtr; int otherDimIndex; if (relatedDim == 0) { otherTableSPtr = paramInfo->getTable(1); otherDimIndex = indexes.front().getDim2Index(); } else { otherTableSPtr = paramInfo->getTable(0); otherDimIndex = indexes.front().getDim1Index(); } if ((otherTableSPtr != nullptr) && !otherTableSPtr->isVariable(&plot->_parameterManager)) { if (otherTableSPtr->getName(&plot->_parameterManager).empty()) addInfoPart(label._text, "Table bounds"); else addInfoPart(label._text, otherTableSPtr->getName(&plot->_parameterManager)); AMDA::Info::t_TableBound crtBound = otherTableSPtr->getBound(&plot->_parameterManager, otherDimIndex); addBoundsPart(label._text, crtBound.min, crtBound.max); std::string rawUnit = otherTableSPtr->getUnits(&plot->_parameterManager); addInfoPart(label._text, getTransformedUnits(rawUnit)); } else { std::string part = "Table Index: "; part += std::to_string(otherDimIndex); addInfoPart(label._text, part); } addBreakLine(label._text); } addInfoPart(label._text, tableSPtr->getName(&plot->_parameterManager)); std::string rawUnit = tableSPtr->getUnits(&plot->_parameterManager); addInfoPart(label._text, getTransformedUnits(rawUnit)); pAxis->_legend.pushLabel(label); } void AxisLegendManager::addInfoPart(std::string &legend, std::string info) { if (!info.empty()) { if (!legend.empty()) { if (legend.length() >= Label::DELIMITER.length()) { if (legend.compare(legend.length() - Label::DELIMITER.length(), Label::DELIMITER.length(), Label::DELIMITER) != 0) { legend += ", "; } } else { legend += ", "; } } legend += info; } } void AxisLegendManager::addIndexPart(std::string &legend, ParameterIndexComponentColor &index) { legend += "["; legend += std::to_string(index.getDim1Index()); if (index.getDim2Index() != -1) { legend += ","; legend += std::to_string(index.getDim2Index()); } legend += "]"; } void AxisLegendManager::addIndexPart(std::string &legend, int index) { legend += "["; legend += std::to_string(index); legend += "]"; } void AxisLegendManager::addBoundsPart(std::string &legend, PLFLT min, PLFLT max) { legend += " "; char minCount[1024]; char maxCount[1024]; int precision = computeScientificFormatPrecision(min, max); getDigitalLabel(min, precision, minCount, 1024); getDigitalLabel(max, precision, maxCount, 1024); legend += std::string(minCount); legend += ", "; legend += std::string(maxCount); } void AxisLegendManager::addBreakLine(std::string &legend) { if (!legend.empty()) { legend += Label::DELIMITER; } } std::string AxisLegendManager::getParamLegend(AMDA::Info::ParamInfoSPtr paramInfo, ParameterIndexComponentColor &index) { std::string legend; addInfoPart(legend, paramInfo->getShortName()); if ((index.getDim1Index() != -1) || (index.getDim2Index() != -1)) { AMDA::Common::ParameterIndexComponent paramIndex(index.getDim1Index(), index.getDim2Index()); if (paramInfo->getComponents(paramIndex).empty() == false) addInfoPart(legend, paramInfo->getComponents(paramIndex)); else { addInfoPart(legend, paramInfo->getShortName()); addIndexPart(legend, index); } } addInfoPart(legend, getTransformedUnits(paramInfo->getUnits())); addInfoPart(legend, paramInfo->getCoordinatesSystem()); return legend; } /*std::string AxisLegendManager::getParamLegend(AMDA::Info::ParamInfoSPtr paramInfo, int index) { std::string legend; addInfoPart(legend, paramInfo->getShortName()); if ((index.getDim1Index() != -1) || (index.getDim2Index() != -1)) { if (paramInfo->getComponents(index).empty() == false) addInfoPart(legend, paramInfo->getComponents(index)); else { addInfoPart(legend, paramInfo->getShortName()); addIndexPart(legend, index); } } addInfoPart(legend, paramInfo->getUnits()); addInfoPart(legend, paramInfo->getCoordinatesSystem()); return legend; }*/ std::string AxisLegendManager::getMissionInstrumentInfo(AMDA::Info::ParamInfoSPtr paramInfo) { std::string info = paramInfo->getInstrumentId(); if (info.empty()) return info; std::replace(info.begin(), info.end(), '_', ' '); std::transform(info.begin(), info.end(), info.begin(), ::toupper); return info; } std::string AxisLegendManager::getMissionInfo(AMDA::Info::ParamInfoSPtr paramInfo) { std::string info = paramInfo->getInstrumentId(); if (info.empty()) return info; if (info.find('_') != std::string::npos) { info = info.substr(0, info.find('_')); } std::transform(info.begin(), info.end(), info.begin(), ::toupper); return info; } std::string AxisLegendManager::getTransformedUnits(const std::string &rawUnit) { std::string unit = rawUnit; if (unit.find("^")) unit = transformPower(unit, "^"); if (unit.find("**")) unit = transformPower(unit, "**"); return unit; } std::string AxisLegendManager::transformPower(std::string &unit, std::string pattern) { std::map positions; // holds all the positions that pattern occurs within unit size_t pos_first = unit.find(pattern, 0); size_t pos_last; while (pos_first != std::string::npos) { char afterPattern = unit[pos_first + pattern.length()]; pos_last = pos_first + pattern.length(); if (afterPattern == '+' || afterPattern == '-') { afterPattern = unit[pos_first + pattern.length() + 1]; pos_last++; } if (afterPattern == '(') { pos_last = unit.find(")", pos_first + pattern.length()) + 1; } else if (afterPattern == '|') { pos_last = unit.find("|", pos_first + pattern.length() + 2) + 1; } else if (isdigit(afterPattern) || afterPattern == '.') { pos_last++; while (isdigit(unit[pos_last]) || unit[pos_last] == '.') { pos_last++; } } else { pos_last++; } positions.insert(std::pair(pos_first, pos_last)); pos_first = unit.find(pattern, pos_first + pattern.length()); } std::map::reverse_iterator it; for (it = positions.rbegin(); it != positions.rend(); ++it) { unit.insert(it->second, "#d"); unit.erase(it->first, pattern.length()); unit.insert(it->first, "#u"); } return unit; } } /* namespace plot */