Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cluster structure #182

Merged
merged 6 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@ identifier_name:
- env
- telemetry_api_server_version

reporter: "github-actions-logging" # reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging)
#reporter: "github-actions-logging" # reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging)
reporter: "xcode"
11 changes: 11 additions & 0 deletions APIClient/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
extension APIClient {

func login(loginRequestBody: LoginRequestBody, callback: @escaping (Bool) -> Void) {
let url = urlForPath(apiVersion: .v3,"users", "login")

Check warning on line 98 in APIClient/APIClient.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Comma Spacing Violation: There should be no space before and one after any comma (comma)

var request = URLRequest(url: url)
request.httpMethod = "POST"
Expand Down Expand Up @@ -414,6 +414,17 @@
runTask(with: request, completion: completion)
}

@available(macOS 12.0, *)
func post<Input: Encodable, Output: Decodable>(data: Input, url: URL) async throws -> Output {
#if DEBUG
print("🌍 POST", url)
#endif

var request = authenticatedURLRequest(for: url, httpMethod: "POST")
request.httpBody = try? JSONEncoder.telemetryEncoder.encode(data)
return try await runAsyncTask(with: request)
}

func post<Input: Encodable, Output: Decodable>(_ data: Input, to url: URL, defaultValue _: Output? = nil, completion: @escaping (Result<Output, TransferError>) -> Void) {
#if DEBUG
print("🌍 POST", url)
Expand Down
18 changes: 7 additions & 11 deletions APIClient/DTOs/InsightInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,6 @@ public struct InsightInfo: Codable, Hashable, Identifiable {
/// What kind of insight is this?
public var type: InsightType

/// If set, display the chart with this accent color, otherwise fall back to default color
public var accentColor: String?

/// If set, use the custom query in this property instead of constructing a query out of the options below
public var customQuery: CustomQuery?

/// Which signal types are we interested in? If nil, do not filter by signal type
public var signalType: String?

Expand All @@ -57,31 +51,32 @@ public struct InsightInfo: Codable, Hashable, Identifiable {
/// The date this query was last run
public var lastRunAt: Date?

/// The query to calculate this insight
public var query: CustomQuery?

public init(
id: UUID,
groupID: UUID,
order: Double?,
title: String,
type: InsightType,
accentColor: String? = nil,
accentColor _: String? = nil,
widgetable _: Bool? = false,
customQuery: CustomQuery? = nil,
signalType: String?,
uniqueUser: Bool,
breakdownKey: String?,
groupBy: QueryGranularity?,
displayMode: InsightDisplayMode,
isExpanded: Bool,
lastRunTime: TimeInterval?,
lastRunAt: Date?
lastRunAt: Date?,
query: CustomQuery?
) {
self.id = id
self.groupID = groupID
self.order = order
self.title = title
self.type = type
self.accentColor = accentColor
self.customQuery = customQuery
self.signalType = signalType
self.uniqueUser = uniqueUser
self.breakdownKey = breakdownKey
Expand All @@ -90,5 +85,6 @@ public struct InsightInfo: Codable, Hashable, Identifiable {
self.isExpanded = isExpanded
self.lastRunTime = lastRunTime
self.lastRunAt = lastRunAt
self.query = query
}
}
25 changes: 25 additions & 0 deletions Cluster/Chart/BarChart/BarCharTopN.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// BarCharTopN.swift
// Telemetry Viewer (iOS)
//
// Created by Lukas on 23.05.24.
//

import SwiftUI
import Charts
import DataTransferObjects

struct BarChartTopN: View {
let result: TopNQueryResult

var body: some View {
Chart {
//ForEach(result.rows) { row in

Check warning on line 17 in Cluster/Chart/BarChart/BarCharTopN.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Comment Spacing Violation: Prefer at least one space after slashes for comments (comment_spacing)
// BarMark(
// x: .value("Date", 4),
// y: .value("Total Count", 5)
// )
//}

Check warning on line 22 in Cluster/Chart/BarChart/BarCharTopN.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Comment Spacing Violation: Prefer at least one space after slashes for comments (comment_spacing)
}
}
}
25 changes: 25 additions & 0 deletions Cluster/Chart/BarChart/BarChartGroupBy.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// 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)
)
}*/
}
}
}
25 changes: 25 additions & 0 deletions Cluster/Chart/BarChart/BarChartTimeSeries.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// BarChartTimeSeries.swift
// Telemetry Viewer (iOS)
//
// Created by Lukas on 23.05.24.
//

import SwiftUI
import Charts
import DataTransferObjects

struct BarChartTimeSeries: View {
let result: TimeSeriesQueryResult

var body: some View {
Chart {
ForEach(result.rows, id: \.timestamp) { row in
BarMark(
x: .value("Date", row.timestamp),
y: .value("Total Count", row.result["count"]?.value ?? 0)
)
}
}
}
}
38 changes: 38 additions & 0 deletions Cluster/Chart/BarChart/ClusterBarChart.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// ClusterBarChart.swift
// Telemetry Viewer (iOS)
//
// Created by Lukas on 23.05.24.
//
import SwiftUI
import DataTransferObjects

struct ClusterBarChart: View {
let query: CustomQuery
let result: QueryResult

var body: some 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")
}
/*case .groupBy:
if case let .groupBy(result) = result {
BarChartGroupBy(result: result)
} else {
Text("Mismatch in query type and result type 2")
}*/
case .topN:
if case let .topN(result) = result {
BarChartTopN(result: result)
} else {
Text("Mismatch in query type and result type 2")
}
default:
Text("\(query.queryType.rawValue) bar charts are not supported.")
}
}
}
28 changes: 28 additions & 0 deletions Cluster/Chart/ClusterChart.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// ClusterChart.swift
// Telemetry Viewer (iOS)
//
// Created by Lukas on 23.05.24.
//

import SwiftUI
import DataTransferObjects

/// Cluster/Chart – given a query and a result, displays the result
struct ClusterChart: View {

let query: CustomQuery
let result: QueryResult
let type: InsightDisplayMode

var body: some View {
switch type {
case .barChart:
ClusterBarChart(query: query, result: result)
case .lineChart:
ClusterLineChart(query: query, result: result)
default:
Text("Not supported")
}
}
}
27 changes: 27 additions & 0 deletions Cluster/Chart/LineChart/ClusterLineChart.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// ClusterLineChart.swift
// Telemetry Viewer (iOS)
//
// Created by Lukas on 23.05.24.
//

import SwiftUI
import DataTransferObjects

struct ClusterLineChart: View {
let query: CustomQuery
let result: QueryResult

var body: some View {
switch query.queryType {
case .timeseries:
if case let .timeSeries(result) = result {
LineChartTimeSeries(result: result)
} else {
Text("Mismatch in query type and result type")
}
default:
Text("\(query.queryType.rawValue) bar charts are not supported.")
}
}
}
33 changes: 33 additions & 0 deletions Cluster/Chart/LineChart/LineChartTimeSeries.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// LineChartTimeSeries.swift
// Telemetry Viewer (iOS)
//
// Created by Lukas on 23.05.24.
//

import SwiftUI
import Charts
import DataTransferObjects

struct LineChartTimeSeries: View {
let result: TimeSeriesQueryResult

var body: some View {
Chart {
ForEach(result.rows, id: \.timestamp) { row in
LineMark(
x: .value("Date", row.timestamp),
y: .value("Total Count", row.result["count"]?.value ?? 0)
)
}
.interpolationMethod(.cardinal)

ForEach(result.rows, id: \.timestamp) { row in
AreaMark(x: .value("Date", row.timestamp),
y: .value("Total Count", row.result["count"]?.value ?? 0))
}
.interpolationMethod(.cardinal)
.foregroundStyle(LinearGradient(colors: [Color.telemetryOrange.opacity(0.25), Color.telemetryOrange.opacity(0.0)], startPoint: .top, endPoint: .bottom))
}
}
}
34 changes: 34 additions & 0 deletions Cluster/ClusterInstrument.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// ClusterInstrument.swift
// Telemetry Viewer (iOS)
//
// Created by Lukas on 23.05.24.
//

import SwiftUI
import DataTransferObjects

struct ClusterInstrument: View {
@EnvironmentObject var api: APIClient

let query: CustomQuery
let title: String
let type: InsightDisplayMode

var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text(title)
.font(.headline)
.fontWeight(.medium)
.foregroundStyle(Color.Zinc600)
.padding(.top)
.padding(.horizontal)
QueryRunner(query: query, type: type)
}
.compositingGroup()
.background(.background)
.shadow(color: .gray.opacity(0.15), radius: 5, x: 0, y: 2)
.border(Color.Zinc200, width: 1.0)
.padding(.vertical, 5)
}
}
Loading
Loading