// Copyright Epic Games, Inc. All Rights Reserved. #include "StatsViewColumnFactory.h" // Insights #include "Insights/Common/TimeUtils.h" #include "Insights/Table/ViewModels/TableCellValueFormatter.h" #include "Insights/Table/ViewModels/TableCellValueGetter.h" #include "Insights/Table/ViewModels/TableCellValueSorter.h" #include "Insights/ViewModels/StatsGroupingAndSorting.h" #include "Insights/ViewModels/StatsNodeHelper.h" #define LOCTEXT_NAMESPACE "SStatsView" //////////////////////////////////////////////////////////////////////////////////////////////////// // Column identifiers const FName FStatsViewColumns::NameColumnID(TEXT("Name")); const FName FStatsViewColumns::MetaGroupNameColumnID(TEXT("MetaGroupName")); const FName FStatsViewColumns::TypeColumnID(TEXT("Type")); const FName FStatsViewColumns::DataTypeColumnID(TEXT("DataType")); const FName FStatsViewColumns::CountColumnID(TEXT("Count")); const FName FStatsViewColumns::SumColumnID(TEXT("Sum")); const FName FStatsViewColumns::MaxColumnID(TEXT("Max")); const FName FStatsViewColumns::UpperQuartileColumnID(TEXT("UpperQuartile")); const FName FStatsViewColumns::AverageColumnID(TEXT("Average")); const FName FStatsViewColumns::MedianColumnID(TEXT("Median")); const FName FStatsViewColumns::LowerQuartileColumnID(TEXT("LowerQuartile")); const FName FStatsViewColumns::MinColumnID(TEXT("Min")); //////////////////////////////////////////////////////////////////////////////////////////////////// void FStatsViewColumnFactory::CreateStatsViewColumns(TArray>& Columns) { Columns.Reset(); Columns.Add(CreateNameColumn()); Columns.Add(CreateMetaGroupNameColumn()); Columns.Add(CreateTypeColumn()); Columns.Add(CreateDataTypeColumn()); Columns.Add(CreateCountColumn()); Columns.Add(CreateSumColumn()); Columns.Add(CreateMaxColumn()); // Columns.Add(CreateUpperQuartileColumn()); Columns.Add(CreateAverageColumn()); Columns.Add(CreateMedianColumn()); // Columns.Add(CreateLowerQuartileColumn()); Columns.Add(CreateMinColumn()); } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateNameColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::NameColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Name_ColumnName", "Name")); Column.SetTitleName(LOCTEXT("Name_ColumnTitle", "Stats or Group Name")); Column.SetDescription(LOCTEXT("Name_ColumnDesc", "Name of stats or group")); Column.SetFlags(ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered | ETableColumnFlags::IsHierarchy); Column.SetHorizontalAlignment(HAlign_Left); Column.SetInitialWidth(206.0f); Column.SetMinWidth(42.0f); Column.SetDataType(ETableCellDataType::Text); TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateMetaGroupNameColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::MetaGroupNameColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("MetaGroupName_ColumnName", "Meta Group")); Column.SetTitleName(LOCTEXT("MetaGroupName_ColumnTitle", "Meta Group Name")); Column.SetDescription(LOCTEXT("MetaGroupName_ColumnDesc", "Name of meta group")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Left); Column.SetInitialWidth(100.0f); Column.SetDataType(ETableCellDataType::Text); class FMetaGroupNameValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::MetaGroupNameColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(FText::FromName(StatsNode.GetMetaGroupName()))); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateTypeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::TypeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Type_ColumnName", "Type")); Column.SetTitleName(LOCTEXT("Type_ColumnTitle", "Type")); Column.SetDescription(LOCTEXT("Type_ColumnDesc", "Type of stats counter or group")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Left); Column.SetInitialWidth(60.0f); Column.SetDataType(ETableCellDataType::Text); class FStatsTypeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::TypeColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNodeTypeHelper::ToText(StatsNode.GetType()))); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); // TSharedRef Sorter = MakeShared(ColumnRef); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateDataTypeColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::DataTypeColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("DataType_ColumnName", "DataType")); Column.SetTitleName(LOCTEXT("DataType_ColumnTitle", "Data Type")); Column.SetDescription(LOCTEXT("DataType_ColumnDesc", "Data type of counter values")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Left); Column.SetInitialWidth(60.0f); Column.SetDataType(ETableCellDataType::Text); class FStatsTypeValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::DataTypeColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNodeDataTypeHelper::ToText(StatsNode.GetDataType()))); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); // TSharedRef Sorter = MakeShared(ColumnRef); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateCountColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::CountColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Count_ColumnName", "Count")); Column.SetTitleName(LOCTEXT("Count_ColumnTitle", "Sample Count")); Column.SetDescription(LOCTEXT("Count_ColumnDesc", "Number of selected samples")); Column.SetFlags(ETableColumnFlags::CanBeHidden | ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(60.0f); Column.SetDataType(ETableCellDataType::Int64); Column.SetAggregation(ETableColumnAggregation::Sum); class FCountValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::CountColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(static_cast(StatsNode.GetAggregatedStats().Count))); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); // TSharedRef Sorter = MakeShared(ColumnRef); TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateSumColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::SumColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Sum_ColumnName", "Sum")); Column.SetTitleName(LOCTEXT("Sum_ColumnTitle", "Sum")); Column.SetDescription(LOCTEXT("Sum_ColumnDesc", "Sum of selected samples")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(AggregatedStatsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); Column.SetAggregation(ETableColumnAggregation::Sum); class FSumValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::SumColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNode.GetAggregatedStats().DoubleStats.Sum)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); class FSumValueFormatter: public FTableCellValueFormatter { public: virtual FText FormatValue(const FTableColumn& Column, const FBaseTreeNode& Node) const override { ensure(Column.GetId() == FStatsViewColumns::SumColumnID); // check(Node.Is()); const FStatsNode& StatsNode = static_cast(Node); return StatsNode.GetTextForAggregatedStatsSum(); } }; TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); // TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateMaxColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::MaxColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Max_ColumnName", "Max")); Column.SetTitleName(LOCTEXT("Max_ColumnTitle", "Maximum")); Column.SetDescription(LOCTEXT("Max_ColumnDesc", "Maximum of selected values")); Column.SetFlags(ETableColumnFlags::CanBeHidden | ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(AggregatedStatsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); // Column.SetAggregation(ETableColumnAggregation::Max); class FMaxValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::MaxColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNode.GetAggregatedStats().DoubleStats.Max)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); class FMaxValueFormatter: public FTableCellValueFormatter { public: virtual FText FormatValue(const FTableColumn& Column, const FBaseTreeNode& Node) const override { ensure(Column.GetId() == FStatsViewColumns::MaxColumnID); // check(Node.Is()); const FStatsNode& StatsNode = static_cast(Node); return StatsNode.GetTextForAggregatedStatsMax(); } }; TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); // TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateUpperQuartileColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::UpperQuartileColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("UpperQuartile_ColumnName", "Upper")); Column.SetTitleName(LOCTEXT("UpperQuartile_ColumnTitle", "Upper Quartile")); Column.SetDescription(LOCTEXT("UpperQuartile_ColumnDesc", "Upper quartile (Q3; third quartile; 75th percentile) of selected values")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(AggregatedStatsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); // Column.SetAggregation(ETableColumnAggregation::Max); class FUpperQuartileValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::UpperQuartileColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNode.GetAggregatedStats().DoubleStats.UpperQuartile)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); class FUpperQuartileValueFormatter: public FTableCellValueFormatter { public: virtual FText FormatValue(const FTableColumn& Column, const FBaseTreeNode& Node) const override { ensure(Column.GetId() == FStatsViewColumns::UpperQuartileColumnID); // check(Node.Is()); const FStatsNode& StatsNode = static_cast(Node); return StatsNode.GetTextForAggregatedStatsUpperQuartile(); } }; TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); // TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateAverageColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::AverageColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Average_ColumnName", "Avg.")); Column.SetTitleName(LOCTEXT("Average_ColumnTitle", "Average")); Column.SetDescription(LOCTEXT("Average_ColumnDesc", "Average (arithmetic mean) of selected values")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(AggregatedStatsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FAverageValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::AverageColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNode.GetAggregatedStats().DoubleStats.Average)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); class FAverageValueFormatter: public FTableCellValueFormatter { public: virtual FText FormatValue(const FTableColumn& Column, const FBaseTreeNode& Node) const override { ensure(Column.GetId() == FStatsViewColumns::AverageColumnID); // check(Node.Is()); const FStatsNode& StatsNode = static_cast(Node); return StatsNode.GetTextForAggregatedStatsAverage(); } }; TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); // TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateMedianColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::MedianColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Median_ColumnName", "Med.")); Column.SetTitleName(LOCTEXT("Median_ColumnTitle", "Median")); Column.SetDescription(LOCTEXT("Median_ColumnDesc", "Median (Q2; second quartile; 50th percentile) of selected values")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(AggregatedStatsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); class FMedianValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::MedianColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNode.GetAggregatedStats().DoubleStats.Median)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); class FMedianValueFormatter: public FTableCellValueFormatter { public: virtual FText FormatValue(const FTableColumn& Column, const FBaseTreeNode& Node) const override { ensure(Column.GetId() == FStatsViewColumns::MedianColumnID); // check(Node.Is()); const FStatsNode& StatsNode = static_cast(Node); return StatsNode.GetTextForAggregatedStatsMedian(); } }; TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); // TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateLowerQuartileColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::LowerQuartileColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("LowerQuartile_ColumnName", "Lower")); Column.SetTitleName(LOCTEXT("LowerQuartile_ColumnTitle", "Lower Quartile")); Column.SetDescription(LOCTEXT("LowerQuartile_ColumnDesc", "Lower quartile (Q1; first quartile; 25th percentile) of selected values")); Column.SetFlags(ETableColumnFlags::CanBeHidden | // ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(AggregatedStatsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); // Column.SetAggregation(ETableColumnAggregation::Min); class FLowerQuartileValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::LowerQuartileColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNode.GetAggregatedStats().DoubleStats.LowerQuartile)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); class FLowerQuartileValueFormatter: public FTableCellValueFormatter { public: virtual FText FormatValue(const FTableColumn& Column, const FBaseTreeNode& Node) const override { ensure(Column.GetId() == FStatsViewColumns::LowerQuartileColumnID); // check(Node.Is()); const FStatsNode& StatsNode = static_cast(Node); return StatsNode.GetTextForAggregatedStatsLowerQuartile(); } }; TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); // TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// TSharedRef FStatsViewColumnFactory::CreateMinColumn() { using namespace Insights; TSharedRef ColumnRef = MakeShared(FStatsViewColumns::MinColumnID); FTableColumn& Column = *ColumnRef; Column.SetShortName(LOCTEXT("Min_ColumnName", "Min")); Column.SetTitleName(LOCTEXT("Min_ColumnTitle", "Minimum")); Column.SetDescription(LOCTEXT("Min_ColumnDesc", "Minimum of selected values")); Column.SetFlags(ETableColumnFlags::CanBeHidden | ETableColumnFlags::ShouldBeVisible | ETableColumnFlags::CanBeFiltered); Column.SetHorizontalAlignment(HAlign_Right); Column.SetInitialWidth(AggregatedStatsColumnInitialWidth); Column.SetDataType(ETableCellDataType::Double); // Column.SetAggregation(ETableColumnAggregation::Min); class FMinValueGetter: public FTableCellValueGetter { public: virtual const TOptional GetValue(const FTableColumn& Column, const FBaseTreeNode& Node) const { ensure(Column.GetId() == FStatsViewColumns::MinColumnID); const FStatsNode& StatsNode = static_cast(Node); return TOptional(FTableCellValue(StatsNode.GetAggregatedStats().DoubleStats.Min)); } }; TSharedRef Getter = MakeShared(); Column.SetValueGetter(Getter); class FMinValueFormatter: public FTableCellValueFormatter { public: virtual FText FormatValue(const FTableColumn& Column, const FBaseTreeNode& Node) const override { ensure(Column.GetId() == FStatsViewColumns::MinColumnID); // check(Node.Is()); const FStatsNode& StatsNode = static_cast(Node); return StatsNode.GetTextForAggregatedStatsMin(); } }; TSharedRef Formatter = MakeShared(); Column.SetValueFormatter(Formatter); TSharedRef Sorter = MakeShared(ColumnRef); // TSharedRef Sorter = MakeShared(ColumnRef); Column.SetValueSorter(Sorter); return ColumnRef; } //////////////////////////////////////////////////////////////////////////////////////////////////// #undef LOCTEXT_NAMESPACE