From d1e300a8a056aa05b9a0210f7cb8040879a2e635 Mon Sep 17 00:00:00 2001 From: Blacky <106263486+Black-Fox-2022@users.noreply.github.com> Date: Tue, 28 May 2024 10:26:20 +0200 Subject: [PATCH 1/2] CleanUp Code --- Cluster/Chart/BarChart/BarChartGroupBy.swift | 25 -------------- .../Chart/BarChart/BarChartTimeSeries.swift | 34 ++++++++++++++++++- Cluster/Chart/BarChart/ClusterBarChart.swift | 6 +--- Cluster/Chart/PieChart/ClusterPieChart.swift | 25 ++++++++++++++ Cluster/Chart/PieChart/PieChartGroupBy.swift | 24 +++++++++++++ Telemetry Viewer.xcodeproj/project.pbxproj | 20 ++++++++--- 6 files changed, 99 insertions(+), 35 deletions(-) delete mode 100644 Cluster/Chart/BarChart/BarChartGroupBy.swift create mode 100644 Cluster/Chart/PieChart/ClusterPieChart.swift create mode 100644 Cluster/Chart/PieChart/PieChartGroupBy.swift diff --git a/Cluster/Chart/BarChart/BarChartGroupBy.swift b/Cluster/Chart/BarChart/BarChartGroupBy.swift deleted file mode 100644 index 945d079..0000000 --- a/Cluster/Chart/BarChart/BarChartGroupBy.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// BarChartGroupBy.swift -// Telemetry Viewer (iOS) -// -// Created by Lukas on 23.05.24. -// - -import SwiftUI -import Charts -import DataTransferObjects - -struct BarChartGroupBy: View { - let result: GroupByQueryResult - - var body: some View { - Chart { - /*ForEach(result.rows) { row in - BarMark( - x: .value("Date", 5), - y: .value("Total Count", 5) - ) - }*/ - } - } -} diff --git a/Cluster/Chart/BarChart/BarChartTimeSeries.swift b/Cluster/Chart/BarChart/BarChartTimeSeries.swift index 9e4b625..57e559d 100644 --- a/Cluster/Chart/BarChart/BarChartTimeSeries.swift +++ b/Cluster/Chart/BarChart/BarChartTimeSeries.swift @@ -11,15 +11,47 @@ import DataTransferObjects struct BarChartTimeSeries: View { let result: TimeSeriesQueryResult + let query: CustomQuery var body: some View { Chart { ForEach(result.rows, id: \.timestamp) { row in BarMark( - x: .value("Date", row.timestamp), + x: .value("Date", row.timestamp, unit: granularity()), y: .value("Total Count", row.result["count"]?.value ?? 0) ) } } } + + // swiftlint:disable cyclomatic_complexity + func granularity() -> Calendar.Component{ + switch query.granularity { + case .all: + .month + case .none: + .month + case .second: + .hour + case .minute: + .hour + case .fifteen_minute: + .hour + case .thirty_minute: + .hour + case .hour: + .hour + case .day: + .day + case .week: + .weekOfYear + case .month: + .month + case .quarter: + .quarter + case .year: + .year + } + } + // swiftlint:enable cyclomatic_complexity } diff --git a/Cluster/Chart/BarChart/ClusterBarChart.swift b/Cluster/Chart/BarChart/ClusterBarChart.swift index 446b782..6c0e2cc 100644 --- a/Cluster/Chart/BarChart/ClusterBarChart.swift +++ b/Cluster/Chart/BarChart/ClusterBarChart.swift @@ -15,15 +15,11 @@ struct ClusterBarChart: View { switch query.queryType { case .timeseries: if case let .timeSeries(result) = result { - BarChartTimeSeries(result: result) - } else { - Text("Mismatch in query type and result type 1") + BarChartTimeSeries(result: result, query: query) } case .topN: if case let .topN(result) = result { BarChartTopN(topNQueryResult: result, query: query) - } else { - Text("Mismatch in query type and result type 2") } default: Text("\(query.queryType.rawValue) bar charts are not supported.") diff --git a/Cluster/Chart/PieChart/ClusterPieChart.swift b/Cluster/Chart/PieChart/ClusterPieChart.swift new file mode 100644 index 0000000..0b24421 --- /dev/null +++ b/Cluster/Chart/PieChart/ClusterPieChart.swift @@ -0,0 +1,25 @@ +// +// ClusterPieChart.swift +// Telemetry Viewer (iOS) +// +// Created by Lukas on 28.05.24. +// + +import SwiftUI +import DataTransferObjects + +struct ClusterPieChart: View { + let query: CustomQuery + let result: QueryResult + + var body: some View { + switch query.queryType { + case .groupBy: + if case let .groupBy(result) = result { + PieChartGroupBy(result: result, query: query) + } + default: + Text("\(query.queryType.rawValue) bar charts are not supported.") + } + } +} diff --git a/Cluster/Chart/PieChart/PieChartGroupBy.swift b/Cluster/Chart/PieChart/PieChartGroupBy.swift new file mode 100644 index 0000000..f90471c --- /dev/null +++ b/Cluster/Chart/PieChart/PieChartGroupBy.swift @@ -0,0 +1,24 @@ +// +// PieChartGroupBy.swift +// Telemetry Viewer (iOS) +// +// Created by Lukas on 28.05.24. +// + +import SwiftUI +import Charts +import DataTransferObjects + +struct PieChartGroupBy: View { + let result: GroupByQueryResult + let query: CustomQuery + + var body: some View { + Chart { + ForEach(result.rows, id: \.self) { row in + + } + } + .chartForegroundStyleScale(range: Color.chartColors) + } +} diff --git a/Telemetry Viewer.xcodeproj/project.pbxproj b/Telemetry Viewer.xcodeproj/project.pbxproj index 3eaa9f7..81f9a0e 100644 --- a/Telemetry Viewer.xcodeproj/project.pbxproj +++ b/Telemetry Viewer.xcodeproj/project.pbxproj @@ -163,6 +163,8 @@ 80427FF62BFE2AF4007E89CC /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80427FDF2BFE2AF4007E89CC /* UserInfo.swift */; }; 80427FF72BFE2AF4007E89CC /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80427FDF2BFE2AF4007E89CC /* UserInfo.swift */; }; 80427FF82BFE2AF4007E89CC /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80427FDF2BFE2AF4007E89CC /* UserInfo.swift */; }; + 8083DD692C05C9C300596926 /* ClusterPieChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8083DD682C05C9C300596926 /* ClusterPieChart.swift */; }; + 8083DD6B2C05C9FE00596926 /* PieChartGroupBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8083DD6A2C05C9FE00596926 /* PieChartGroupBy.swift */; }; 80AD3E942BFF2A7300BBD7EB /* QueryRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3E932BFF2A7300BBD7EB /* QueryRunner.swift */; }; 80AD3E972BFF2AA200BBD7EB /* ClusterChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3E962BFF2AA200BBD7EB /* ClusterChart.swift */; }; 80AD3E992BFF2B0A00BBD7EB /* ClusterInstrument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3E982BFF2B0A00BBD7EB /* ClusterInstrument.swift */; }; @@ -170,7 +172,6 @@ 80AD3EA02BFF306F00BBD7EB /* BarChartTimeSeries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3E9F2BFF306F00BBD7EB /* BarChartTimeSeries.swift */; }; 80AD3EA32BFF33D900BBD7EB /* ClusterLineChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3EA22BFF33D900BBD7EB /* ClusterLineChart.swift */; }; 80AD3EA52BFF33FF00BBD7EB /* LineChartTimeSeries.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3EA42BFF33FF00BBD7EB /* LineChartTimeSeries.swift */; }; - 80AD3EAC2BFF6BE000BBD7EB /* BarChartGroupBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3EAB2BFF6BE000BBD7EB /* BarChartGroupBy.swift */; }; 80AD3EAE2BFF6D2200BBD7EB /* BarCharTopN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3EAD2BFF6D2200BBD7EB /* BarCharTopN.swift */; }; C5173B41283D52E40018CE9F /* InsightsGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5173B40283D52E40018CE9F /* InsightsGrid.swift */; }; C51CB73627565EB5005A3FB9 /* TelemetryDeckWidget.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = C5A8D869270C5D7B0032560A /* TelemetryDeckWidget.intentdefinition */; }; @@ -516,6 +517,8 @@ 80427FDD2BFE2AF4007E89CC /* InsightGroupInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InsightGroupInfo.swift; sourceTree = ""; }; 80427FDE2BFE2AF4007E89CC /* InsightInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InsightInfo.swift; sourceTree = ""; }; 80427FDF2BFE2AF4007E89CC /* UserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = ""; }; + 8083DD682C05C9C300596926 /* ClusterPieChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterPieChart.swift; sourceTree = ""; }; + 8083DD6A2C05C9FE00596926 /* PieChartGroupBy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PieChartGroupBy.swift; sourceTree = ""; }; 80AD3E932BFF2A7300BBD7EB /* QueryRunner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryRunner.swift; sourceTree = ""; }; 80AD3E962BFF2AA200BBD7EB /* ClusterChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterChart.swift; sourceTree = ""; }; 80AD3E982BFF2B0A00BBD7EB /* ClusterInstrument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterInstrument.swift; sourceTree = ""; }; @@ -523,7 +526,6 @@ 80AD3E9F2BFF306F00BBD7EB /* BarChartTimeSeries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarChartTimeSeries.swift; sourceTree = ""; }; 80AD3EA22BFF33D900BBD7EB /* ClusterLineChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterLineChart.swift; sourceTree = ""; }; 80AD3EA42BFF33FF00BBD7EB /* LineChartTimeSeries.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChartTimeSeries.swift; sourceTree = ""; }; - 80AD3EAB2BFF6BE000BBD7EB /* BarChartGroupBy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarChartGroupBy.swift; sourceTree = ""; }; 80AD3EAD2BFF6D2200BBD7EB /* BarCharTopN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarCharTopN.swift; sourceTree = ""; }; C5173B40283D52E40018CE9F /* InsightsGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsightsGrid.swift; sourceTree = ""; }; C51CB73B27565F76005A3FB9 /* TelemetryDeckMacIntents.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = TelemetryDeckMacIntents.appex; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -858,6 +860,15 @@ path = DTOs; sourceTree = ""; }; + 8083DD672C05C9AC00596926 /* PieChart */ = { + isa = PBXGroup; + children = ( + 8083DD682C05C9C300596926 /* ClusterPieChart.swift */, + 8083DD6A2C05C9FE00596926 /* PieChartGroupBy.swift */, + ); + path = PieChart; + sourceTree = ""; + }; 80AD3E922BFF28AF00BBD7EB /* Cluster */ = { isa = PBXGroup; children = ( @@ -872,6 +883,7 @@ isa = PBXGroup; children = ( 80AD3E962BFF2AA200BBD7EB /* ClusterChart.swift */, + 8083DD672C05C9AC00596926 /* PieChart */, 80AD3EA12BFF33C100BBD7EB /* LineChart */, 80AD3E9C2BFF303E00BBD7EB /* BarChart */, ); @@ -883,7 +895,6 @@ children = ( 80AD3E9D2BFF305100BBD7EB /* ClusterBarChart.swift */, 80AD3E9F2BFF306F00BBD7EB /* BarChartTimeSeries.swift */, - 80AD3EAB2BFF6BE000BBD7EB /* BarChartGroupBy.swift */, 80AD3EAD2BFF6D2200BBD7EB /* BarCharTopN.swift */, ); path = BarChart; @@ -1713,7 +1724,6 @@ 2B21FCD526FDC33F00A8A55B /* InsightGroupsView.swift in Sources */, DCB02B722502781A00304964 /* LoginView.swift in Sources */, 2B379D2126FBC3A300714BE6 /* IconFinderService.swift in Sources */, - 80AD3EAC2BFF6BE000BBD7EB /* BarChartGroupBy.swift in Sources */, C5CD589D2810368400671359 /* ThreeCirclesInATrenchcode.swift in Sources */, 2BBFC9FF267D05E40013DC74 /* OrderSetter.swift in Sources */, 2B745562272306DD002CBB45 /* ChartDataPoint+InsightCalculationResult.swift in Sources */, @@ -1778,11 +1788,13 @@ 2B46280B2728699E00515530 /* StatusMessageContainer.swift in Sources */, 2BBFCA33267D05E40013DC74 /* AdaptiveStack.swift in Sources */, DC45BB1C24E27F12004E6392 /* SignalView.swift in Sources */, + 8083DD6B2C05C9FE00596926 /* PieChartGroupBy.swift in Sources */, C5F4D33A28ACF48000EBB667 /* RawChartView.swift in Sources */, C5F4D35E28ACF48000EBB667 /* BigNumberFormatter.swift in Sources */, C5D14219273471EF0029CA03 /* ConditionalViewModifier.swift in Sources */, C5F4D36228ACF48000EBB667 /* SingleKeyValueView.swift in Sources */, 63C4E9582778C54D00344E20 /* SignalListExplanationView.swift in Sources */, + 8083DD692C05C9C300596926 /* ClusterPieChart.swift in Sources */, 2BBFCA25267D05E40013DC74 /* ProgressView+Scale.swift in Sources */, 80AD3E942BFF2A7300BBD7EB /* QueryRunner.swift in Sources */, 2BBFCA29267D05E40013DC74 /* Binding+OnUpdate.swift in Sources */, From 7f4e7486bf46c19b0b1e9d27e7121663a33698a6 Mon Sep 17 00:00:00 2001 From: Blacky <106263486+Black-Fox-2022@users.noreply.github.com> Date: Tue, 28 May 2024 12:58:24 +0200 Subject: [PATCH 2/2] Functional Pie Charts Fix #183 --- Cluster/Chart/BarChart/BarCharTopN.swift | 125 +----------------- .../Chart/BarChart/BarChartTimeSeries.swift | 1 + Cluster/Chart/ClusterChart.swift | 2 + Cluster/Chart/Extensions.swift | 123 +++++++++++++++++ Cluster/Chart/PieChart/ClusterPieChart.swift | 6 +- Cluster/Chart/PieChart/PieChartGroupBy.swift | 24 ---- Cluster/Chart/PieChart/PieChartTopN.swift | 84 ++++++++++++ .../Contents.json | 0 Telemetry Viewer.xcodeproj/project.pbxproj | 16 ++- 9 files changed, 229 insertions(+), 152 deletions(-) create mode 100644 Cluster/Chart/Extensions.swift delete mode 100644 Cluster/Chart/PieChart/PieChartGroupBy.swift create mode 100644 Cluster/Chart/PieChart/PieChartTopN.swift rename Shared/Supporting Files/Assets.xcassets/{Tamerald.colorset => Temerald.colorset}/Contents.json (100%) diff --git a/Cluster/Chart/BarChart/BarCharTopN.swift b/Cluster/Chart/BarChart/BarCharTopN.swift index ae34d8b..c9a4185 100644 --- a/Cluster/Chart/BarChart/BarCharTopN.swift +++ b/Cluster/Chart/BarChart/BarCharTopN.swift @@ -24,7 +24,7 @@ struct BarChartTopN: View { if let metricValue = getMetricValue(rowResult: rowResult){ getBarMark( timeStamp: row.timestamp, - name: getAggregatorName(aggregator: aggregator), + name: aggregator.name, metricValue: metricValue, metricName: getMetricName(rowResult: rowResult) ) @@ -39,140 +39,27 @@ struct BarChartTopN: View { } - // swiftlint:disable cyclomatic_complexity - func granularity() -> Calendar.Component{ - switch query.granularity { - case .all: - .month - case .none: - .month - case .second: - .hour - case .minute: - .hour - case .fifteen_minute: - .hour - case .thirty_minute: - .hour - case .hour: - .hour - case .day: - .day - case .week: - .weekOfYear - case .month: - .month - case .quarter: - .quarter - case .year: - .year - } - } - // swiftlint:enable cyclomatic_complexity - func getBarMark(timeStamp: Date, name: String, metricValue: Double, metricName: String) -> some ChartContent { return BarMark( - x: .value("Date", timeStamp, unit: granularity()), + x: .value("Date", timeStamp, unit: query.granularityAsCalendarComponent), y: .value(name, metricValue) ) - .foregroundStyle(by: .value(getDimensionName(from: query.dimension) ?? "Not found", metricName)) - } - - func getDimensionName(from: DimensionSpec?) -> String? { - switch from { - case .default(let defaultDimensionSpec): - defaultDimensionSpec.outputName - case .extraction(let extractionDimensionSpec): - extractionDimensionSpec.outputName - case .none: - nil - } + .foregroundStyle(by: .value(query.dimension?.name ?? "No value", metricName)) + .cornerRadius(2) } func getMetricName(rowResult: AdaptableQueryResultItem) -> String{ - let dimensionName = getDimensionName(from: query.dimension) ?? "Not found" + let dimensionName = query.dimension?.name ?? "No value" let metricName = rowResult.dimensions[dimensionName] ?? "Not found" return metricName } - // swiftlint:disable cyclomatic_complexity - // swiftlint:disable function_body_length - func getAggregatorName(aggregator: Aggregator) -> String { - switch aggregator { - case .count(let a): - a.name - case .cardinality(let a): - a.name - case .longSum(let a): - a.name - case .doubleSum(let a): - a.name - case .floatSum(let a): - a.name - case .doubleMin(let a): - a.name - case .doubleMax(let a): - a.name - case .floatMin(let a): - a.name - case .floatMax(let a): - a.name - case .longMin(let a): - a.name - case .longMax(let a): - a.name - case .doubleMean(let a): - a.name - case .doubleFirst(let a): - a.name - case .doubleLast(let a): - a.name - case .floatFirst(let a): - a.name - case .floatLast(let a): - a.name - case .longFirst(let a): - a.name - case .longLast(let a): - a.name - case .stringFirst(let a): - a.name - case .stringLast(let a): - a.name - case .doubleAny(let a): - a.name - case .floatAny(let a): - a.name - case .longAny(let a): - a.name - case .stringAny(let a): - a.name - case .thetaSketch(let a): - a.name - case .filtered(let a): - getAggregatorName(aggregator: a.aggregator) - } - } - // swiftlint:enable cyclomatic_complexity - // swiftlint:enable function_body_length - func getMetricValue(rowResult: AdaptableQueryResultItem) -> Double? { - guard let metric = query.metric, let metricName = getMetricName(metric: metric) else { + guard let metricName = query.metric?.name else { return nil } let value = rowResult.metrics[metricName] return value } - func getMetricName(metric: TopNMetricSpec) -> String? { - switch metric { - case .numeric(let numericTopNMetricSpec): - return numericTopNMetricSpec.metric - case .inverted(let invertedTopNMetricSpec): - return getMetricName(metric: invertedTopNMetricSpec.metric) - default: - return nil - } - } - } diff --git a/Cluster/Chart/BarChart/BarChartTimeSeries.swift b/Cluster/Chart/BarChart/BarChartTimeSeries.swift index 57e559d..38f4a39 100644 --- a/Cluster/Chart/BarChart/BarChartTimeSeries.swift +++ b/Cluster/Chart/BarChart/BarChartTimeSeries.swift @@ -20,6 +20,7 @@ struct BarChartTimeSeries: View { x: .value("Date", row.timestamp, unit: granularity()), y: .value("Total Count", row.result["count"]?.value ?? 0) ) + .cornerRadius(2) } } } diff --git a/Cluster/Chart/ClusterChart.swift b/Cluster/Chart/ClusterChart.swift index 9d7fafa..dc1447b 100644 --- a/Cluster/Chart/ClusterChart.swift +++ b/Cluster/Chart/ClusterChart.swift @@ -21,6 +21,8 @@ struct ClusterChart: View { ClusterBarChart(query: query, result: result) case .lineChart: ClusterLineChart(query: query, result: result) + case .pieChart: + ClusterPieChart(query: query, result: result) default: Text("Not supported") } diff --git a/Cluster/Chart/Extensions.swift b/Cluster/Chart/Extensions.swift new file mode 100644 index 0000000..d65d0d2 --- /dev/null +++ b/Cluster/Chart/Extensions.swift @@ -0,0 +1,123 @@ +// +// Extensions.swift +// Telemetry Viewer (iOS) +// +// Created by Lukas on 28.05.24. +// + +import Foundation +import DataTransferObjects + +extension CustomQuery { + var granularityAsCalendarComponent: Calendar.Component{ + switch self.granularity { + case .all: + .month + case .none: + .month + case .second: + .hour + case .minute: + .hour + case .fifteen_minute: + .hour + case .thirty_minute: + .hour + case .hour: + .hour + case .day: + .day + case .week: + .weekOfYear + case .month: + .month + case .quarter: + .quarter + case .year: + .year + } + } +} + +extension Aggregator { + var name: String { + switch self { + case .count(let a): + a.name + case .cardinality(let a): + a.name + case .longSum(let a): + a.name + case .doubleSum(let a): + a.name + case .floatSum(let a): + a.name + case .doubleMin(let a): + a.name + case .doubleMax(let a): + a.name + case .floatMin(let a): + a.name + case .floatMax(let a): + a.name + case .longMin(let a): + a.name + case .longMax(let a): + a.name + case .doubleMean(let a): + a.name + case .doubleFirst(let a): + a.name + case .doubleLast(let a): + a.name + case .floatFirst(let a): + a.name + case .floatLast(let a): + a.name + case .longFirst(let a): + a.name + case .longLast(let a): + a.name + case .stringFirst(let a): + a.name + case .stringLast(let a): + a.name + case .doubleAny(let a): + a.name + case .floatAny(let a): + a.name + case .longAny(let a): + a.name + case .stringAny(let a): + a.name + case .thetaSketch(let a): + a.name + case .filtered(let a): + a.aggregator.name + } + } +} + +extension DimensionSpec { + var name: String? { + switch self { + case .default(let defaultDimensionSpec): + defaultDimensionSpec.outputName + case .extraction(let extractionDimensionSpec): + extractionDimensionSpec.outputName + } + } +} + +extension TopNMetricSpec { + var name: String? { + switch self { + case .numeric(let numericTopNMetricSpec): + return numericTopNMetricSpec.metric + case .inverted(let invertedTopNMetricSpec): + return invertedTopNMetricSpec.metric.name + default: + return nil + } + } +} diff --git a/Cluster/Chart/PieChart/ClusterPieChart.swift b/Cluster/Chart/PieChart/ClusterPieChart.swift index 0b24421..329a770 100644 --- a/Cluster/Chart/PieChart/ClusterPieChart.swift +++ b/Cluster/Chart/PieChart/ClusterPieChart.swift @@ -14,9 +14,9 @@ struct ClusterPieChart: View { var body: some View { switch query.queryType { - case .groupBy: - if case let .groupBy(result) = result { - PieChartGroupBy(result: result, query: query) + case .topN: + if case let .topN(result) = result { + PieChartTopN(topNQueryResult: result, query: query) } default: Text("\(query.queryType.rawValue) bar charts are not supported.") diff --git a/Cluster/Chart/PieChart/PieChartGroupBy.swift b/Cluster/Chart/PieChart/PieChartGroupBy.swift deleted file mode 100644 index f90471c..0000000 --- a/Cluster/Chart/PieChart/PieChartGroupBy.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// PieChartGroupBy.swift -// Telemetry Viewer (iOS) -// -// Created by Lukas on 28.05.24. -// - -import SwiftUI -import Charts -import DataTransferObjects - -struct PieChartGroupBy: View { - let result: GroupByQueryResult - let query: CustomQuery - - var body: some View { - Chart { - ForEach(result.rows, id: \.self) { row in - - } - } - .chartForegroundStyleScale(range: Color.chartColors) - } -} diff --git a/Cluster/Chart/PieChart/PieChartTopN.swift b/Cluster/Chart/PieChart/PieChartTopN.swift new file mode 100644 index 0000000..bceefee --- /dev/null +++ b/Cluster/Chart/PieChart/PieChartTopN.swift @@ -0,0 +1,84 @@ +// +// PieChartGroupBy.swift +// Telemetry Viewer (iOS) +// +// Created by Lukas on 28.05.24. +// + +import SwiftUI +import Charts +import DataTransferObjects + +struct PieChartTopN: View { + let topNQueryResult: TopNQueryResult + let query: CustomQuery + + var body: some View { + + Chart { + ForEach(topNQueryResult.rows, id: \.self) { (row: TopNQueryResultRow) in + + ForEach(row.result, id: \.self) { (rowResult: AdaptableQueryResultItem) in + + ForEach(query.aggregations ?? [], id: \.self) { (aggregator: Aggregator) in + if let metricValue = getMetricValue(rowResult: rowResult){ + if query.granularity != .all { + getBarMark( + timeStamp: row.timestamp, + name: aggregator.name, + metricValue: metricValue, + metricName: getMetricName(rowResult: rowResult) + ) + } else { + getSectorMark( + name: aggregator.name, + metricValue: metricValue, + metricName: getMetricName(rowResult: rowResult) + ) + } + } + } + + } + + } + } + .chartForegroundStyleScale(range: Color.chartColors) + + } + + func getSectorMark(name: String, metricValue: Double, metricName: String) -> some ChartContent { + return SectorMark( + angle: .value(name, metricValue), + innerRadius: .ratio(0.5), + angularInset: 1.0 + ) + .cornerRadius(2) + .foregroundStyle(by: .value(query.dimension?.name ?? "No value", metricName)) + } + + func getBarMark(timeStamp: Date, name: String, metricValue: Double, metricName: String) -> some ChartContent { + return BarMark( + x: .value("Date", timeStamp, unit: query.granularityAsCalendarComponent), + y: .value(name, metricValue), + stacking: .normalized + ) + .foregroundStyle(by: .value(query.dimension?.name ?? "No value", metricName)) + .cornerRadius(2) + } + + func getMetricName(rowResult: AdaptableQueryResultItem) -> String{ + let dimensionName = query.dimension?.name ?? "No value" + let metricName = rowResult.dimensions[dimensionName] ?? "Not found" + return metricName + } + + func getMetricValue(rowResult: AdaptableQueryResultItem) -> Double? { + guard let metricName = query.metric?.name else { + return nil + } + let value = rowResult.metrics[metricName] + return value + } + +} diff --git a/Shared/Supporting Files/Assets.xcassets/Tamerald.colorset/Contents.json b/Shared/Supporting Files/Assets.xcassets/Temerald.colorset/Contents.json similarity index 100% rename from Shared/Supporting Files/Assets.xcassets/Tamerald.colorset/Contents.json rename to Shared/Supporting Files/Assets.xcassets/Temerald.colorset/Contents.json diff --git a/Telemetry Viewer.xcodeproj/project.pbxproj b/Telemetry Viewer.xcodeproj/project.pbxproj index 81f9a0e..adb875c 100644 --- a/Telemetry Viewer.xcodeproj/project.pbxproj +++ b/Telemetry Viewer.xcodeproj/project.pbxproj @@ -164,7 +164,8 @@ 80427FF72BFE2AF4007E89CC /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80427FDF2BFE2AF4007E89CC /* UserInfo.swift */; }; 80427FF82BFE2AF4007E89CC /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80427FDF2BFE2AF4007E89CC /* UserInfo.swift */; }; 8083DD692C05C9C300596926 /* ClusterPieChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8083DD682C05C9C300596926 /* ClusterPieChart.swift */; }; - 8083DD6B2C05C9FE00596926 /* PieChartGroupBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8083DD6A2C05C9FE00596926 /* PieChartGroupBy.swift */; }; + 8083DD6B2C05C9FE00596926 /* PieChartTopN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8083DD6A2C05C9FE00596926 /* PieChartTopN.swift */; }; + 8083DD6D2C05EA0100596926 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8083DD6C2C05EA0100596926 /* Extensions.swift */; }; 80AD3E942BFF2A7300BBD7EB /* QueryRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3E932BFF2A7300BBD7EB /* QueryRunner.swift */; }; 80AD3E972BFF2AA200BBD7EB /* ClusterChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3E962BFF2AA200BBD7EB /* ClusterChart.swift */; }; 80AD3E992BFF2B0A00BBD7EB /* ClusterInstrument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80AD3E982BFF2B0A00BBD7EB /* ClusterInstrument.swift */; }; @@ -518,7 +519,8 @@ 80427FDE2BFE2AF4007E89CC /* InsightInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InsightInfo.swift; sourceTree = ""; }; 80427FDF2BFE2AF4007E89CC /* UserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = ""; }; 8083DD682C05C9C300596926 /* ClusterPieChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterPieChart.swift; sourceTree = ""; }; - 8083DD6A2C05C9FE00596926 /* PieChartGroupBy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PieChartGroupBy.swift; sourceTree = ""; }; + 8083DD6A2C05C9FE00596926 /* PieChartTopN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PieChartTopN.swift; sourceTree = ""; }; + 8083DD6C2C05EA0100596926 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 80AD3E932BFF2A7300BBD7EB /* QueryRunner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryRunner.swift; sourceTree = ""; }; 80AD3E962BFF2AA200BBD7EB /* ClusterChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterChart.swift; sourceTree = ""; }; 80AD3E982BFF2B0A00BBD7EB /* ClusterInstrument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterInstrument.swift; sourceTree = ""; }; @@ -864,7 +866,7 @@ isa = PBXGroup; children = ( 8083DD682C05C9C300596926 /* ClusterPieChart.swift */, - 8083DD6A2C05C9FE00596926 /* PieChartGroupBy.swift */, + 8083DD6A2C05C9FE00596926 /* PieChartTopN.swift */, ); path = PieChart; sourceTree = ""; @@ -883,6 +885,7 @@ isa = PBXGroup; children = ( 80AD3E962BFF2AA200BBD7EB /* ClusterChart.swift */, + 8083DD6C2C05EA0100596926 /* Extensions.swift */, 8083DD672C05C9AC00596926 /* PieChart */, 80AD3EA12BFF33C100BBD7EB /* LineChart */, 80AD3E9C2BFF303E00BBD7EB /* BarChart */, @@ -1747,6 +1750,7 @@ 80AD3E9E2BFF305100BBD7EB /* ClusterBarChart.swift in Sources */, 2B3CC0DC264D4AFE0038B528 /* LexiconService.swift in Sources */, 80AD3EA52BFF33FF00BBD7EB /* LineChartTimeSeries.swift in Sources */, + 8083DD6D2C05EA0100596926 /* Extensions.swift in Sources */, 2B1D469E26CC51A8008814A9 /* GroupService.swift in Sources */, C56B91F927C536D60085839A /* QueryView.swift in Sources */, 2B1D468926CC4423008814A9 /* OrgService.swift in Sources */, @@ -1788,7 +1792,7 @@ 2B46280B2728699E00515530 /* StatusMessageContainer.swift in Sources */, 2BBFCA33267D05E40013DC74 /* AdaptiveStack.swift in Sources */, DC45BB1C24E27F12004E6392 /* SignalView.swift in Sources */, - 8083DD6B2C05C9FE00596926 /* PieChartGroupBy.swift in Sources */, + 8083DD6B2C05C9FE00596926 /* PieChartTopN.swift in Sources */, C5F4D33A28ACF48000EBB667 /* RawChartView.swift in Sources */, C5F4D35E28ACF48000EBB667 /* BigNumberFormatter.swift in Sources */, C5D14219273471EF0029CA03 /* ConditionalViewModifier.swift in Sources */, @@ -2341,7 +2345,7 @@ DEVELOPMENT_TEAM = FL4V655A94; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iOS/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2367,7 +2371,7 @@ DEVELOPMENT_TEAM = FL4V655A94; ENABLE_PREVIEWS = YES; INFOPLIST_FILE = iOS/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 16.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks",