From f5fdd37e22ede0024ba6bdb8432d5daebd71469c Mon Sep 17 00:00:00 2001 From: Vladyslav Goncharuk Date: Wed, 29 May 2024 18:21:17 +0300 Subject: [PATCH] [ISSUE #193][PLOT_VIEW] Add name label above each axis rectangle - Implement support of the 'PARL' group name parameter - Rename console command 'plot-sequence-ids' into the 'plot-ids' - Update README.md Signed-off-by: Vladyslav Goncharuk --- .../src/common/PlotDefinitions.cpp | 34 +++- .../src/common/PlotDefinitions.hpp | 39 +++++ .../log/src/CConsoleInputProcessor.cpp | 4 +- .../plotView/src/CPlotViewComponent.cpp | 13 +- .../searchView/api/ISearchResultModel.hpp | 1 + .../searchView/src/CSearchResultModel.cpp | 145 +++++++++++++++--- md/plot_view/plot_view.md | 31 ++-- 7 files changed, 225 insertions(+), 42 deletions(-) diff --git a/dltmessageanalyzerplugin/src/common/PlotDefinitions.cpp b/dltmessageanalyzerplugin/src/common/PlotDefinitions.cpp index 4470d3ef..aeb70fef 100644 --- a/dltmessageanalyzerplugin/src/common/PlotDefinitions.cpp +++ b/dltmessageanalyzerplugin/src/common/PlotDefinitions.cpp @@ -12,6 +12,7 @@ //////// PLOT_IDENTIFIERS //////// const QString s_PLOT_AXIS_RECTANGLE_TYPE = "PARType"; +const QString s_PLOT_AXIS_RECTANGLE_LABEL = "PARL"; const QString s_PLOT_X_MAX = "PXMx"; const QString s_PLOT_X_MIN = "PXMn"; const QString s_PLOT_Y_MAX = "PYMx"; @@ -138,13 +139,40 @@ static tPlotViewIDsMap createPlotIDsMap() item.description = QString("Plot axis rectangle type. %1. " "PARType_CPUC_LINEAR. Type of the specific plot axis rectangle. " - "Supported types are - GANNT, BAR, POINT, LINEAR. " + "Supported types are - GANTT, BAR, POINT, LINEAR. " "If not specified, the LINEAR value is used. " "If multiple values appear - the 'last win' strategy is applied.").arg(item.getParametersDescription()); result.insert(std::make_pair(ePlotViewID::PLOT_AXIS_RECTANGLE_TYPE, item)); } + { + tPlotViewIDItem item; + item.id_type = ePlotViewIDType::e_Optional; + item.id_str = s_PLOT_AXIS_RECTANGLE_LABEL; + + { + tPlotViewIDParameterPtr pParameter = std::make_shared(); + pParameter->name = "axisRectName"; + pParameter->type = ePlotViewParameterType::e_Mandatory; + item.addParameter(pParameter); + } + + { + tPlotViewIDParameterPtr pParameter = std::make_shared(); + pParameter->name = "axisRectLabel"; + pParameter->type = ePlotViewParameterType::e_Mandatory; + item.addParameter(pParameter); + } + + item.description = QString("Plot axis rectangle label. %1. " + "PARL_CPUC_MyChart. The label, that will be created above the corresponding plot axis rectangle. " + "If not specified, the label is not created. " + "If multiple values appear for the same 'axisRectName' - they are concatenated.").arg(item.getParametersDescription()); + + result.insert(std::make_pair(ePlotViewID::PLOT_AXIS_RECTANGLE_LABEL, item)); + } + auto formMinMaxParameters = [](tPlotViewIDItem& item) { { @@ -873,9 +901,9 @@ QRegularExpression createPlotViewRegex() for( auto it = sPlotViewIDsMap.begin(); it != sPlotViewIDsMap.end(); ++it ) { - const auto& UML_IDs_MapItem = *it; + const auto& Plot_IDs_MapItem = *it; - resultRegex.append(UML_IDs_MapItem.second.id_str); + resultRegex.append(Plot_IDs_MapItem.second.id_str); if(it != finalIter) { diff --git a/dltmessageanalyzerplugin/src/common/PlotDefinitions.hpp b/dltmessageanalyzerplugin/src/common/PlotDefinitions.hpp index f4939baa..b35be54d 100644 --- a/dltmessageanalyzerplugin/src/common/PlotDefinitions.hpp +++ b/dltmessageanalyzerplugin/src/common/PlotDefinitions.hpp @@ -30,6 +30,7 @@ typedef std::unordered_map tPlot enum class ePlotViewID { PLOT_AXIS_RECTANGLE_TYPE = 0, + PLOT_AXIS_RECTANGLE_LABEL, PLOT_X_MAX, PLOT_X_MIN, PLOT_Y_MAX, @@ -203,6 +204,44 @@ struct tPlotParametersParser } }; +template<> +struct tPlotParametersParser +{ + ePlotViewID plotViewId = ePlotViewID::PLOT_AXIS_RECTANGLE_LABEL; + + struct tParsingResult + { + bool bParsingSuccessful = false; + QString errors; + QString axisRectName; + QString axisRectLabel; + }; + + tParsingResult parse(bool fillInStringMsg, + const tQStringPtr& pPlotViewGroupName, + const tQStringPtrVec& splitParameters) + { + tParsingResult result; + + if(checkPlotViewParameter(result.errors, + fillInStringMsg, + plotViewId, + pPlotViewGroupName, + splitParameters)) + { + assert(splitParameters[0] != nullptr); + result.axisRectName = *splitParameters[0]; + + assert(splitParameters[1] != nullptr); + result.axisRectLabel = *splitParameters[1]; + + result.bParsingSuccessful = true; + } + + return result; + } +}; + template<> struct tPlotParametersParser { diff --git a/dltmessageanalyzerplugin/src/components/log/src/CConsoleInputProcessor.cpp b/dltmessageanalyzerplugin/src/components/log/src/CConsoleInputProcessor.cpp index 6a800bba..bcb59cbb 100644 --- a/dltmessageanalyzerplugin/src/components/log/src/CConsoleInputProcessor.cpp +++ b/dltmessageanalyzerplugin/src/components/log/src/CConsoleInputProcessor.cpp @@ -272,7 +272,7 @@ static void UML_sequence_identifiers() } } -static void plot_sequence_identifiers() +static void plot_identifiers() { SEND_MSG("Plot regex group identifiers, which are supported by the plugin:"); @@ -387,7 +387,7 @@ CConsoleInputProcessor::tScenariosMap CConsoleInputProcessor::createScenariosMap "- clears debug view"); result["color-aliases"] = CConsoleInputProcessor::tScenarioData([](const CConsoleInputProcessor::tParamMap&){supportedColors();} , "- prints all supported color aliases"); - result["plot-sequence-ids"] = CConsoleInputProcessor::tScenarioData([](const CConsoleInputProcessor::tParamMap&){plot_sequence_identifiers();} + result["plot-ids"] = CConsoleInputProcessor::tScenarioData([](const CConsoleInputProcessor::tParamMap&){plot_identifiers();} , "- prints information about regex names scripting in area of the plot diagrams."); result["plot-operations"] = CConsoleInputProcessor::tScenarioData([](const CConsoleInputProcessor::tParamMap&){plot_operations();} , "- prints information about regex names scripting in area of the plot diagrams."); diff --git a/dltmessageanalyzerplugin/src/components/plotView/src/CPlotViewComponent.cpp b/dltmessageanalyzerplugin/src/components/plotView/src/CPlotViewComponent.cpp index db011600..7e441d7d 100644 --- a/dltmessageanalyzerplugin/src/components/plotView/src/CPlotViewComponent.cpp +++ b/dltmessageanalyzerplugin/src/components/plotView/src/CPlotViewComponent.cpp @@ -225,13 +225,24 @@ void generateAxisRect(const std::pairinsetLayout()->addElement(pLegend, Qt::AlignRight|Qt::AlignTop); // Adjust position as needed pLegend->setLayer(QLatin1String("legend")); - pAxisRect->insetLayout()->setInsetAlignment(0, Qt::AlignTop|Qt::AlignRight); // Position of legend auto* pLeftAxis = pAxisRect->axis(QCPAxis::atLeft); auto* pBottomAxis = pAxisRect->axis(QCPAxis::atBottom); pPlot->plotLayout()->addElement(rowCounter, 0, pAxisRect); pAxisRect->axis(QCPAxis::atBottom)->setLayer("axes"); pAxisRect->axis(QCPAxis::atBottom)->grid()->setLayer("grid"); + + { + if (plotAxis.axisLabel.isSet()) + { + QCPTextElement *pTitleLabel = new QCPTextElement(pPlot, plotAxis.axisLabel.getValue(), QFont("sans", 12, QFont::Bold)); + pTitleLabel->setVisible(true); + pAxisRect->insetLayout()->addElement(pTitleLabel, QRectF(0.005, 0.0, 0.0, 0.0)); + pTitleLabel->setLayer(QLatin1String("axis_rect_label")); + pTitleLabel->setSelectable(false); + } + } + // bring bottom and main axis rect closer together: pAxisRect->setAutoMargins(QCP::msLeft|QCP::msRight|QCP::msBottom); pAxisRect->setMargins(QMargins(0, 0, 0, 0)); diff --git a/dltmessageanalyzerplugin/src/components/searchView/api/ISearchResultModel.hpp b/dltmessageanalyzerplugin/src/components/searchView/api/ISearchResultModel.hpp index 109c80cc..f07da193 100644 --- a/dltmessageanalyzerplugin/src/components/searchView/api/ISearchResultModel.hpp +++ b/dltmessageanalyzerplugin/src/components/searchView/api/ISearchResultModel.hpp @@ -84,6 +84,7 @@ class ISearchResultModel struct tPlotAxisItem { TOptional axisType; + TOptional axisLabel; TOptional xName; TOptional yName; TOptional xUnit; diff --git a/dltmessageanalyzerplugin/src/components/searchView/src/CSearchResultModel.cpp b/dltmessageanalyzerplugin/src/components/searchView/src/CSearchResultModel.cpp index e50db369..0484921a 100644 --- a/dltmessageanalyzerplugin/src/components/searchView/src/CSearchResultModel.cpp +++ b/dltmessageanalyzerplugin/src/components/searchView/src/CSearchResultModel.cpp @@ -580,7 +580,15 @@ namespace detail }; typedef std::map tGraphIdMetadataMap; - typedef std::map tAxisNameMetadataMap; + + struct tAxisRectMetadataItem + { + tGraphIdMetadataMap graphIdMetadataMap; + bool bLabelParsed = false; + bool bLabelParsingLocked = false; + }; + + typedef std::map tAxisNameMetadataMap; struct tMetadataItem { @@ -596,24 +604,67 @@ namespace detail for (int i = 0; i < val.size(); ++i) { QChar ch = val[i]; + bool bIsFirstCharacter = i == 0; bool bIsLastCharacter = i == val.size() - 1; - if(true == bIsLastCharacter) + if (bIsLastCharacter) { - result.append(ch); + if(bIsFirstCharacter == bIsLastCharacter) + { + result.append(ch.toUpper()); + } + else + { + result.append(ch); + } } else { - QChar nextCh = val[i+1]; - - bool bIsFirstCharacter = i == 0; + QChar nextCh = val[i + 1]; - if(true == ch.isUpper() && - true == nextCh.isLower() && - false == bIsFirstCharacter) + // Add a space if the current character is lowercase and next character is uppercase + // helloWorld => Hello world + if (ch.isLower() && nextCh.isUpper()) { + result.append(ch); result.append(" "); - result.append(ch.toLower()); + } + else if (ch.isLower() && nextCh.isLower()) + { + result.append(ch); + } + else if (ch.isUpper()) + { + // Add a space if the current and next characters are uppercase, but the one after is lowercase + // RAMLoad => RAM load + if (nextCh.isUpper() && (i + 2 < val.size() && val[i + 2].isLower())) + { + if (bIsFirstCharacter) + { + result.append(ch.toUpper()); + } + else + { + result.append(ch); + } + + result.append(" "); + } + else if (nextCh.isLower()) + { + if (bIsFirstCharacter) + { + result.append(ch.toUpper()); + } + else + { + result.append(ch.toLower()); + } + } + else if (nextCh.isUpper()) + { + result.append(ch); + } } else { @@ -780,6 +831,40 @@ namespace detail } } break; + case ePlotViewID::PLOT_AXIS_RECTANGLE_LABEL: + { + if(false == splitParameters.empty()) + { + auto parser = tPlotParametersParser(); + auto parsingResult = parser.parse(true, pGroupName, splitParameters); + + if(true == parsingResult.bParsingSuccessful) + { + auto& axisRectData = axisNameMetadataMap[parsingResult.axisRectName]; + if(false == axisRectData.bLabelParsingLocked) + { + if(false == plotContent.plotAxisMap[parsingResult.axisRectName].axisLabel.isSet()) + { + plotContent.plotAxisMap[parsingResult.axisRectName].axisLabel.setValue(parsingResult.axisRectLabel); + } + else + { + plotContent.plotAxisMap[parsingResult.axisRectName].axisLabel.getWriteableValue().append(parsingResult.axisRectLabel); + } + + axisRectData.bLabelParsed = true; + } + } + else + { + SEND_WRN(QString("Skip line #%1 due to the following error: '%2'") + .arg(msgId).arg(parsingResult.errors)); + bResult = false; + continue; + } + } + } + break; case ePlotViewID::PLOT_X_MAX: { if(false == splitParameters.empty()) @@ -1045,9 +1130,9 @@ namespace detail if(foundAxisNameMetadata != axisNameMetadataMap.end()) { - auto foundGraphIdMetadata = foundAxisNameMetadata->second.find(parsingResult.graphId); + auto foundGraphIdMetadata = foundAxisNameMetadata->second.graphIdMetadataMap.find(parsingResult.graphId); - if(foundGraphIdMetadata != foundAxisNameMetadata->second.end()) + if(foundGraphIdMetadata != foundAxisNameMetadata->second.graphIdMetadataMap.end()) { assert(true == foundGraphIdMetadata->second.graphName.isSet()); auto& graphSubItem = plotContent.plotAxisMap[parsingResult.axisRectName].plotGraphItemMap[parsingResult.graphId] @@ -1143,9 +1228,9 @@ namespace detail if(foundAxisNameMetadata != axisNameMetadataMap.end()) { - auto foundGraphIdMetadata = foundAxisNameMetadata->second.find(parsingResult.graphId); + auto foundGraphIdMetadata = foundAxisNameMetadata->second.graphIdMetadataMap.find(parsingResult.graphId); - if(foundGraphIdMetadata != foundAxisNameMetadata->second.end()) + if(foundGraphIdMetadata != foundAxisNameMetadata->second.graphIdMetadataMap.end()) { assert(true == foundGraphIdMetadata->second.graphName.isSet()); auto& graphSubItem = plotContent.plotAxisMap[parsingResult.axisRectName].plotGraphItemMap[parsingResult.graphId] @@ -1234,7 +1319,7 @@ namespace detail if(true == parsingResult.bParsingSuccessful) { - auto& axisRectNameMap = axisNameMetadataMap[parsingResult.axisRectName]; + auto& axisRectNameMap = axisNameMetadataMap[parsingResult.axisRectName].graphIdMetadataMap; auto& metadataItem = axisRectNameMap[parsingResult.graphId]; metadataItem.graphName.setValue(""); @@ -1273,9 +1358,9 @@ namespace detail if(foundAxisNameMetadata != axisNameMetadataMap.end()) { - auto foundGraphIdMetadata = foundAxisNameMetadata->second.find(parsingResult.graphId); + auto foundGraphIdMetadata = foundAxisNameMetadata->second.graphIdMetadataMap.find(parsingResult.graphId); - if(foundGraphIdMetadata != foundAxisNameMetadata->second.end()) + if(foundGraphIdMetadata != foundAxisNameMetadata->second.graphIdMetadataMap.end()) { assert(true == foundGraphIdMetadata->second.graphName.isSet()); auto& graphSubItem = plotContent.plotAxisMap[parsingResult.axisRectName].plotGraphItemMap[parsingResult.graphId] @@ -1328,9 +1413,9 @@ namespace detail if(foundAxisNameMetadata != axisNameMetadataMap.end()) { - auto foundGraphIdMetadata = foundAxisNameMetadata->second.find(parsingResult.graphId); + auto foundGraphIdMetadata = foundAxisNameMetadata->second.graphIdMetadataMap.find(parsingResult.graphId); - if(foundGraphIdMetadata != foundAxisNameMetadata->second.end()) + if(foundGraphIdMetadata != foundAxisNameMetadata->second.graphIdMetadataMap.end()) { assert(true == foundGraphIdMetadata->second.graphName.isSet()); auto& graphSubItem = plotContent.plotAxisMap[parsingResult.axisRectName].plotGraphItemMap[parsingResult.graphId] @@ -1343,7 +1428,7 @@ namespace detail auto& dataItem = graphSubItem.dataItems.back(); - ISearchResultModel::eGanttDataItemType eventType; + ISearchResultModel::eGanttDataItemType eventType = ISearchResultModel::eGanttDataItemType::START; switch(parsingResult.eventType) { @@ -1409,7 +1494,7 @@ ISearchResultModel::tPlotContent CSearchResultModel::createPlotContent() const const auto& plotViewID = plotViewDataMap.first; const auto& plotViewDataItemVec = plotViewDataMap.second; - skipRowFlag = !processPlotViewDataItemVec(*this, + skipRowFlag = !detail::processPlotViewDataItemVec(*this, plotViewID, plotViewDataItemVec, result, @@ -1421,6 +1506,24 @@ ISearchResultModel::tPlotContent CSearchResultModel::createPlotContent() const } } ++row; + + // Lock labels parsing for axis rects where they were already parsed, + // cause we do not expect new content for those in other found lines. + for(auto& axisNameMetadataMapPair : axisNameMetadataMap) + { + if(true == axisNameMetadataMapPair.second.bLabelParsed) + { + axisNameMetadataMapPair.second.bLabelParsingLocked = true; + } + } + } + + for(auto& resultItem : result.plotAxisMap) + { + if(true == resultItem.second.axisLabel.isSet()) + { + resultItem.second.axisLabel.setValue(detail::splitCamelCase(resultItem.second.axisLabel.getValue())); + } } return result; diff --git a/md/plot_view/plot_view.md b/md/plot_view/plot_view.md index 5a58dce7..b19b1f11 100644 --- a/md/plot_view/plot_view.md +++ b/md/plot_view/plot_view.md @@ -75,21 +75,22 @@ Plot regex group identifiers, which are supported by the plugin: |#| Group name | Format | Example | Meaning | Type | | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | |1| **PARType** | PARType + _ + \ + _ + \ | PARType_CPUC_LINEAR |**Plot axis rectangle type**. Type of the specific plot axis rectangle. Supported types are - GANNT, POINT, LINEAR.|**Optional**. If not specified, the LINEAR value is used. If multiple values appear - the 'last win' strategy is applied.| -|2| **PXMx** | PXMx + _ + \ + _ + \ + _ + [real_part_value] + _ + [neg] | PXMx_CustomDiagram_10_00 | **Plot X Max**. Sets the maximum visible value on axis X of the specified axis rectangle. | **Optional**. Last win. If not set, then the maximum value will be derived from the provided data. You can omit 'real_part_value' if not needed. Use the 'neg' keyword as the last parameter to specify negative values. Not applicable to Gantt charts. | -|3| **PXMn** | PXMn + _ + \ + _ + \ + _ + [real_part_value] + _ + [neg] | PXMn_CustomDiagram_10_00_neg | **Plot X Min**. Sets the minimum visible value on axis X of the specified axis rectangle. | **Optional**. Last win. If not set, then the minimum value will be derived from the provided data. You can omit 'real_part_value' if not needed. Use the 'neg' keyword as the last parameter to specify negative values. Not applicable to Gantt charts. | -|4| **PYMx** | PYMx + _ + \ + _ + \ + _ + [real_part_value] + _ + [neg] | PYMx_CPUC_100_00 | **Plot Y Max**. Sets the maximum visible value on axis Y of the specified axis rectangle. | **Optional**. Last win. If not set, then the maximum value will be derived from the provided data. You can omit 'real_part_value' if not needed. Use the 'neg' keyword as the last parameter to specify negative values. Not applicable to Gantt charts. | -|5| **PYMn** | PYMn + _ + \ + _ + \ + _ + [real_part_value] + _ + [neg] | PYMn_CPUC_0_00 | **Plot Y Min**. Sets the minimum visible value on axis Y of the specified axis rectangle. | **Optional**. Last win. If not set, then the minimum value will be derived from the provided data. You can omit 'real_part_value' if not needed. Use the 'neg' keyword as the last parameter to specify negative values. Not applicable to Gantt charts. | -|6| **PXN** | PXN + _ + \ + _ + \ | PXN_CPUC_Timestamp |**Plot X-axis name**. Sets plot X-axis name for the specified plot axis rectangle. Use camelStyleNaming. E.g. 'camelStyleNaming' will be represented as 'Camel style naming' inside the diagram. | **Optional**. If not set, the default 'Timestamp' value is used. | -|7| **PYN** | PYN + _ + \ + _ + \ | PYN_CPUC_CPUConsumption |**Plot Y-axis name**. Sets plot Y-axis name for the specified plot axis rectangle. Use camelStyleNaming. E.g. 'camelStyleNaming' will be represented as 'Camel style naming' inside the diagram. | **Optional**. If not set - remains empty. | -|8| **PXU** | PXU + _ + \ + _ + \ | PXU_CPUC_Milliseconds | **Plot X-axis unit**. Specifies the plot X-axis unit. Use camelStyleNaming. E.g. 'camelStyleNaming' will be represented as 'Camel style naming' inside the diagram. | **Optional**. If not set, then the 'seconds' default value is used, as the X-axis is usually used to represent the time, and in dlt, the timestamp is measured in seconds ( with real part, representing milliseconds, microseconds, etc. ) | -|9| **PYU** | PYU + _ + \ + _ + \ | PYU_CPUC_Percents | **Plot Y-axis unit**. Specifies the plot Y-axis unit. Use camelStyleNaming. E.g. 'camelStyleNaming' will be represented as 'Camel style naming' inside the diagram. | **Optional**. If not set - remains empty. | -|10| **PXData** | PXData + _ + \ + _ + \ + _ + [value] | PXData_CPUC_1 |**Plot X-axis data**. The content of this regex group contains the data, that will be placed at axis X of the specified graph id and axis rectangle. The data of EACH VALUE should be convertible from the string to the float or the date-time. For conversion to date-time see PXT parameter. The graphId parameter should be convertible to an integer. If an optional 'value' parameter was specified, the captured data would be ignored. The 'value' param will be NOT considered as the "time", even if the PXT data was provided. | **Optional**. If not set, the timestamp of each involved DLT message would be used. This parameter can be used for the Gantt chart to get the timestamp from the message's payload. | -|11| **PXT** | PXT + _ + \ | PXT_4yw2Mv2dw2Hw2mw2sw6f | **Plot X-axis time format**. Specifies, how to decode the date and time from the string out of the PXData. E.g. the '05-24 18:25:01.439' time format can be decoded with PXT_2Mw2dw2Hw2mw2sw3f. y - year. M - month. d - day. H - hour. m - minute. s - second. w - any delimiter symbol. f - a real part of the second ( milliseconds, microseconds, etc. ). Useful for custom imported logs, like Android logcat traces, which do not have proper dlt timestamp. | **Optional**. If not specified - there would be no attempt to decode PXData as time. | -|12| **PYData** | PYData + _ + \ + _ + \ + _ + [value] | PYData_CPUC_1 |**Plot Y-axis data**. The content of this regex group contains the data, that will be placed at axis Y of the specified graph id and axis rectangle. The data of EACH VALUE should be convertible from the string to the float or the date-time. For conversion to date-time see PYT parameter. The graphId parameter should be convertible to an integer. If an optional 'value' parameter was specified, the captured data would be ignored. The 'value' param will be NOT considered as the "time", even if the PYT data was provided. | **Mandatory** for plots in which 'PARType' is not equal to 'GANTT'. | -|13| **PYT** | PYT + _ + \ | PYT_4yw2Mv2dw2Hw2mw2sw6f | **Plot Y-axis time format**. Specifies, how to decode the date and time from the string out of the PYData. E.g. the '05-24 18:25:01.439' time format can be decoded with PYT_2Mw2dw2Hw2mw2sw3f. y - year. M - month. d - day. H - hour. m - minute. s - second. w - any delimiter symbol. f - a real part of the second ( milliseconds, microseconds, etc. ). Useful for custom imported logs, like Android logcat traces, which do not have proper dlt timestamp. | **Optional**. If not specified - there would be no attempt to decode PYData as time. | -|14| **PGN** | PGN + _ + \ + _ + \ + _ + [name] | PGN_CPUC_1_NavApp, PGN_CPUC_1 | **Plot graph name**. Specifies the graph name for the specified graph id. If name parameter is not specified, then graph names would be derrived from the caprute content, and a separate graph on the plot would be created for each unique captured graph name. If name parameter is specified, then all names of the specified graphId would be the hard-coded ones, and only one graph would be produced on the plot for that graph id. | **Mandatory** for plots in which 'PARType' is not equal to 'GANTT'. | -|15| **PGMD** | PGMD + _ + \ + _ + \ + _ + \ + _ + [value] | PGMD_SST_1_Domain | **Plot graph meta data**. Declares a metadata item, which ( if found for a specific plot point ) will be added to point's representation when it is selected by the user. | Optional. One or more. If 'value' parameter is not explicitly set, then captured data will be set as 'value'. If multiple 'value'-s are found in the analyzed string for the same 'key' - they will be concatenated. That includes both captured and explicitly set 'value'-s. | -|16| **PGE** | PGE + _ + \ + _ + \ + _ + \ | PGE_proc_1_start | **Plot Gantt chart event**. Declares event of a certain type ( either "start" or "end" ). Used to identify start and end points of different events, which should be represented on the Gantt chart. | Mandatory. One or more. | +|2| **PARL** | PARL + _ + \ + _ + \ | PARL_CPUC_MyChart |**Plot axis rectangle label**. The label, that will be created above the corresponding plot axis rectangle.|**Optional**. If not specified, the label is not created. If multiple values appear for the same 'axisRectName' - they are concatenated.| +|3| **PXMx** | PXMx + _ + \ + _ + \ + _ + [real_part_value] + _ + [neg] | PXMx_CustomDiagram_10_00 | **Plot X Max**. Sets the maximum visible value on axis X of the specified axis rectangle. | **Optional**. Last win. If not set, then the maximum value will be derived from the provided data. You can omit 'real_part_value' if not needed. Use the 'neg' keyword as the last parameter to specify negative values. Not applicable to Gantt charts. | +|4| **PXMn** | PXMn + _ + \ + _ + \ + _ + [real_part_value] + _ + [neg] | PXMn_CustomDiagram_10_00_neg | **Plot X Min**. Sets the minimum visible value on axis X of the specified axis rectangle. | **Optional**. Last win. If not set, then the minimum value will be derived from the provided data. You can omit 'real_part_value' if not needed. Use the 'neg' keyword as the last parameter to specify negative values. Not applicable to Gantt charts. | +|5| **PYMx** | PYMx + _ + \ + _ + \ + _ + [real_part_value] + _ + [neg] | PYMx_CPUC_100_00 | **Plot Y Max**. Sets the maximum visible value on axis Y of the specified axis rectangle. | **Optional**. Last win. If not set, then the maximum value will be derived from the provided data. You can omit 'real_part_value' if not needed. Use the 'neg' keyword as the last parameter to specify negative values. Not applicable to Gantt charts. | +|6| **PYMn** | PYMn + _ + \ + _ + \ + _ + [real_part_value] + _ + [neg] | PYMn_CPUC_0_00 | **Plot Y Min**. Sets the minimum visible value on axis Y of the specified axis rectangle. | **Optional**. Last win. If not set, then the minimum value will be derived from the provided data. You can omit 'real_part_value' if not needed. Use the 'neg' keyword as the last parameter to specify negative values. Not applicable to Gantt charts. | +|7| **PXN** | PXN + _ + \ + _ + \ | PXN_CPUC_Timestamp |**Plot X-axis name**. Sets plot X-axis name for the specified plot axis rectangle. Use camelStyleNaming. E.g. 'camelStyleNaming' will be represented as 'Camel style naming' inside the diagram. | **Optional**. If not set, the default 'Timestamp' value is used. | +|8| **PYN** | PYN + _ + \ + _ + \ | PYN_CPUC_CPUConsumption |**Plot Y-axis name**. Sets plot Y-axis name for the specified plot axis rectangle. Use camelStyleNaming. E.g. 'camelStyleNaming' will be represented as 'Camel style naming' inside the diagram. | **Optional**. If not set - remains empty. | +|9| **PXU** | PXU + _ + \ + _ + \ | PXU_CPUC_Milliseconds | **Plot X-axis unit**. Specifies the plot X-axis unit. Use camelStyleNaming. E.g. 'camelStyleNaming' will be represented as 'Camel style naming' inside the diagram. | **Optional**. If not set, then the 'seconds' default value is used, as the X-axis is usually used to represent the time, and in dlt, the timestamp is measured in seconds ( with real part, representing milliseconds, microseconds, etc. ) | +|10| **PYU** | PYU + _ + \ + _ + \ | PYU_CPUC_Percents | **Plot Y-axis unit**. Specifies the plot Y-axis unit. Use camelStyleNaming. E.g. 'camelStyleNaming' will be represented as 'Camel style naming' inside the diagram. | **Optional**. If not set - remains empty. | +|11| **PXData** | PXData + _ + \ + _ + \ + _ + [value] | PXData_CPUC_1 |**Plot X-axis data**. The content of this regex group contains the data, that will be placed at axis X of the specified graph id and axis rectangle. The data of EACH VALUE should be convertible from the string to the float or the date-time. For conversion to date-time see PXT parameter. The graphId parameter should be convertible to an integer. If an optional 'value' parameter was specified, the captured data would be ignored. The 'value' param will be NOT considered as the "time", even if the PXT data was provided. | **Optional**. If not set, the timestamp of each involved DLT message would be used. This parameter can be used for the Gantt chart to get the timestamp from the message's payload. | +|12| **PXT** | PXT + _ + \ | PXT_4yw2Mv2dw2Hw2mw2sw6f | **Plot X-axis time format**. Specifies, how to decode the date and time from the string out of the PXData. E.g. the '05-24 18:25:01.439' time format can be decoded with PXT_2Mw2dw2Hw2mw2sw3f. y - year. M - month. d - day. H - hour. m - minute. s - second. w - any delimiter symbol. f - a real part of the second ( milliseconds, microseconds, etc. ). Useful for custom imported logs, like Android logcat traces, which do not have proper dlt timestamp. | **Optional**. If not specified - there would be no attempt to decode PXData as time. | +|13| **PYData** | PYData + _ + \ + _ + \ + _ + [value] | PYData_CPUC_1 |**Plot Y-axis data**. The content of this regex group contains the data, that will be placed at axis Y of the specified graph id and axis rectangle. The data of EACH VALUE should be convertible from the string to the float or the date-time. For conversion to date-time see PYT parameter. The graphId parameter should be convertible to an integer. If an optional 'value' parameter was specified, the captured data would be ignored. The 'value' param will be NOT considered as the "time", even if the PYT data was provided. | **Mandatory** for plots in which 'PARType' is not equal to 'GANTT'. | +|14| **PYT** | PYT + _ + \ | PYT_4yw2Mv2dw2Hw2mw2sw6f | **Plot Y-axis time format**. Specifies, how to decode the date and time from the string out of the PYData. E.g. the '05-24 18:25:01.439' time format can be decoded with PYT_2Mw2dw2Hw2mw2sw3f. y - year. M - month. d - day. H - hour. m - minute. s - second. w - any delimiter symbol. f - a real part of the second ( milliseconds, microseconds, etc. ). Useful for custom imported logs, like Android logcat traces, which do not have proper dlt timestamp. | **Optional**. If not specified - there would be no attempt to decode PYData as time. | +|15| **PGN** | PGN + _ + \ + _ + \ + _ + [name] | PGN_CPUC_1_NavApp, PGN_CPUC_1 | **Plot graph name**. Specifies the graph name for the specified graph id. If name parameter is not specified, then graph names would be derrived from the caprute content, and a separate graph on the plot would be created for each unique captured graph name. If name parameter is specified, then all names of the specified graphId would be the hard-coded ones, and only one graph would be produced on the plot for that graph id. | **Mandatory** for plots in which 'PARType' is not equal to 'GANTT'. | +|16| **PGMD** | PGMD + _ + \ + _ + \ + _ + \ + _ + [value] | PGMD_SST_1_Domain | **Plot graph meta data**. Declares a metadata item, which ( if found for a specific plot point ) will be added to point's representation when it is selected by the user. | Optional. One or more. If 'value' parameter is not explicitly set, then captured data will be set as 'value'. If multiple 'value'-s are found in the analyzed string for the same 'key' - they will be concatenated. That includes both captured and explicitly set 'value'-s. | +|17| **PGE** | PGE + _ + \ + _ + \ + _ + \ | PGE_proc_1_start | **Plot Gantt chart event**. Declares event of a certain type ( either "start" or "end" ). Used to identify start and end points of different events, which should be represented on the Gantt chart. | Mandatory. One or more. | ----