Skip to content

Commit

Permalink
feat: 히트맵 범위 로직 변경 (#480)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyungminkimdev authored Jan 8, 2025
1 parent d6ea09d commit 148447a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
15 changes: 7 additions & 8 deletions SoccerBeat/SoccerBeat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1159,8 +1159,7 @@
680567242CCA9D0D00DB0B4F /* ShapeStyle+extension.swift in Sources */,
680567272CCA9D3500DB0B4F /* View+extension.swift in Sources */,
BE0639D82AE61BC2008D1D4E /* SplitControlsView.swift in Sources */,
BEA63A672B0AFDFF000A309D /* ActivityEnum.swift in Sources */,
BE360F022BA016EA00071C30 /* WorkoutManager_Watch+extensions.swift in Sources */,
BE360F022BA016EA00071C30 /* WorkoutManager_Watch.swift in Sources */,
683825052B06249F00FE9CDF /* SprintSheetView.swift in Sources */,
6898F2852AEFD7FC0075A573 /* SprintView.swift in Sources */,
6820884C2AF11EB200F51A3E /* PrecountView.swift in Sources */,
Expand Down Expand Up @@ -1327,7 +1326,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"SoccerBeat Watch App/Preview Content\"";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=watchos*]" = 8S86367NT3;
Expand All @@ -1347,7 +1346,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.5;
MARKETING_VERSION = 1.3.0;
PRODUCT_BUNDLE_IDENTIFIER = com.SoccerBeat.Guryongpo.watchkitapp;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand All @@ -1370,7 +1369,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Distribution";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"SoccerBeat Watch App/Preview Content\"";
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=watchos*]" = 8S86367NT3;
Expand All @@ -1390,7 +1389,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.5;
MARKETING_VERSION = 1.3.0;
PRODUCT_BUNDLE_IDENTIFIER = com.SoccerBeat.Guryongpo.watchkitapp;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -1440,7 +1439,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.5;
MARKETING_VERSION = 1.3.0;
PRODUCT_BUNDLE_IDENTIFIER = com.SoccerBeat.Guryongpo;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -1489,7 +1488,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.2.5;
MARKETING_VERSION = 1.3.0;
PRODUCT_BUNDLE_IDENTIFIER = com.SoccerBeat.Guryongpo;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,11 @@ struct HeatmapView: UIViewRepresentable {
}
}

// Maximum number of data per grid
let maxCount = gridCount.flatMap { $0 }.max() ?? 1

// Calculate maxCount and medianCount
let flatGridCount = gridCount.flatMap { $0 }
let maxCount = flatGridCount.max() ?? 1
let medianCount = flatGridCount.sorted()[flatGridCount.count / 2]

for row in 0..<gridSize+1 {
for col in 0..<gridSize+1 {

Expand All @@ -108,8 +110,8 @@ struct HeatmapView: UIViewRepresentable {

let squareCenter = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)

// Calculate ratio of number of data within a grid
let normalizedCount = Double(gridCount[row][col]) / Double(maxCount)
// Calculate ratio of number of data using log function within a grid
let normalizedCount = normalizedCount(gridCount[row][col], maxCount: maxCount, medianCount: medianCount)

let color = colorForNormalizedCount(normalizedCount)

Expand All @@ -121,28 +123,43 @@ struct HeatmapView: UIViewRepresentable {
return overlays
}

// In order to handle unevenly distributed data, multiple scales are used.
// Linear scale
func normalizedCount(_ count: Int, maxCount: Int, medianCount: Int) -> Double {
if count == 0 || count == 1 {
return 0
}
if Double(maxCount) > Double(medianCount) * 5 {
// Log scale for skewed data
return log(Double(count) + 1) / log(Double(maxCount) + 1)
} else {
// Linear scale for evenly distributed data
return Double(count) / Double(maxCount)
}
}

func colorForNormalizedCount(_ normalizedCount: Double) -> UIColor {

switch normalizedCount {
case 0..<0.1:
case 0:
return UIColor.clear
case 0.1..<0.2:
case 0..<0.05:
return UIColor(Color.heatmap90)
case 0.2..<0.3:
case 0.05..<0.1:
return UIColor(Color.heatmap80)
case 0.3..<0.4:
case 0.1..<0.2:
return UIColor(Color.heatmap70)
case 0.4..<0.5:
case 0.2..<0.3:
return UIColor(Color.heatmap60)
case 0.5..<0.6:
case 0.3..<0.4:
return UIColor(Color.heatmap50)
case 0.6..<0.7:
case 0.4..<0.55:
return UIColor(Color.heatmap40)
case 0.7..<0.8:
case 0.55..<0.7:
return UIColor(Color.heatmap30)
case 0.8..<0.9:
case 0.7..<0.85:
return UIColor(Color.heatmap20)
case 0.9...1.0:
case 0.85...1.0:
return UIColor(Color.heatmap10)
default:
return UIColor.clear
Expand Down

0 comments on commit 148447a

Please sign in to comment.