From f193c63508c7f2c76809aa9a4cd0228c3e2a990d Mon Sep 17 00:00:00 2001 From: race Date: Thu, 6 Apr 2023 16:37:28 +0800 Subject: [PATCH 1/8] public Initializes `ACData` --- Sources/AxisContribution/Model/ACData.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AxisContribution/Model/ACData.swift b/Sources/AxisContribution/Model/ACData.swift index a0a7eb6..741cbc5 100644 --- a/Sources/AxisContribution/Model/ACData.swift +++ b/Sources/AxisContribution/Model/ACData.swift @@ -38,7 +38,7 @@ public class ACData: Equatable { /// - Parameters: /// - date: Current date. /// - count: The number contributed to the current date. The default value is `0`. - init(date: Date, count: Int = 0) { + public init(date: Date, count: Int = 0) { self.date = date self.count = count } From c0bd6591ad32210a61fb14bcdd14710c1f83bb74 Mon Sep 17 00:00:00 2001 From: race Date: Thu, 6 Apr 2023 17:24:15 +0800 Subject: [PATCH 2/8] show feature dates --- Sources/AxisContribution/View/ACGridStack.swift | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Sources/AxisContribution/View/ACGridStack.swift b/Sources/AxisContribution/View/ACGridStack.swift index 96cca32..007c421 100644 --- a/Sources/AxisContribution/View/ACGridStack.swift +++ b/Sources/AxisContribution/View/ACGridStack.swift @@ -110,15 +110,10 @@ struct ACGridStack: View where B: View, F: View { /// - Returns: - private func getRowView(column: Int, row: Int, data: ACData) -> some View { ZStack { - if data.date.startOfDay > Date().startOfDay { - background?(ACIndexSet(column: column, row: row), data) - .hidden() - }else { - background?(ACIndexSet(column: column, row: row), data) - foreground?(ACIndexSet(column: column, row: row), data) - .opacity(getOpacity(count: data.count)) - .takeSize($rowSize) - } + background?(ACIndexSet(column: column, row: row), data) + foreground?(ACIndexSet(column: column, row: row), data) + .opacity(getOpacity(count: data.count)) + .takeSize($rowSize) } } From c326782567b0a2c2a7a09c75687e9a3618c45044 Mon Sep 17 00:00:00 2001 From: race Date: Thu, 6 Apr 2023 18:44:11 +0800 Subject: [PATCH 3/8] Update view when externalDatas changed --- Sources/AxisContribution/AxisContribution.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/AxisContribution/AxisContribution.swift b/Sources/AxisContribution/AxisContribution.swift index 9027fc6..d0fc95d 100644 --- a/Sources/AxisContribution/AxisContribution.swift +++ b/Sources/AxisContribution/AxisContribution.swift @@ -85,6 +85,11 @@ public struct AxisContribution: View where B: View, F: View { .onChange(of: sourceDatas) { newValue in store.setup(constant: self.constant, source: newValue) } + .onChange(of: externalDatas) { newValue in + if let newValue { + store.setup(constant: self.constant, external: newValue) + } + } .onAppear(perform: { self.fetch() }) From 09d0e76cf80c7e7ba10f1f571873357b0a5a78ea Mon Sep 17 00:00:00 2001 From: race Date: Thu, 6 Apr 2023 22:20:24 +0800 Subject: [PATCH 4/8] Use dict as DataSet --- .../Shared/ContentView.swift | 14 ++++++------- .../AxisContribution/AxisContribution.swift | 13 ++++-------- .../AxisContribution/View/ACGridStack.swift | 2 +- .../ViewModel/ACDataProvider.swift | 21 ++++++------------- .../ViewModel/ACDataStore.swift | 2 +- 5 files changed, 19 insertions(+), 33 deletions(-) diff --git a/AxisContributionExample/Shared/ContentView.swift b/AxisContributionExample/Shared/ContentView.swift index 8095948..403afd5 100644 --- a/AxisContributionExample/Shared/ContentView.swift +++ b/AxisContributionExample/Shared/ContentView.swift @@ -16,13 +16,13 @@ struct ContentView: View { @State private var constant: ACConstant = .init(axisMode: .horizontal, levelLabel: .number) @State private var rowSize: CGFloat = 11 @State private var rowImageName: String = "" - @State private var dates: [Date] = [] + @State private var dataSet: [Date: ACData] = [:] var body: some View { VStack { Spacer() // AxisContribution(constant: constant, source: getDates()) - AxisContribution(constant: constant, source: dates) { indexSet, data in + AxisContribution(constant: constant, source: dataSet) { indexSet, data in if rowImageName.isEmpty { defaultBackground }else { @@ -64,13 +64,13 @@ struct ContentView: View { } .pickerStyle(.segmented) Button("Refresh Dates") { - dates = getDates() + dataSet = getDates() } .padding() } .padding() .onAppear { - dates = getDates() + dataSet = getDates() } } @@ -103,11 +103,11 @@ struct ContentView: View { .frame(width: rowSize, height: rowSize) } - private func getDates() -> [Date] { - var sequenceDatas = [Date]() + private func getDates() -> [Date: ACData] { + var sequenceDatas = [Date: ACData]() for _ in 0..<300 { let date = Date.randomBetween(start: Date().dateHalfAyear, end: Date()) - sequenceDatas.append(date) + sequenceDatas[date.startOfDay] = .init(date: date.startOfDay, count: Int.random(in: 0...10)) } return sequenceDatas } diff --git a/Sources/AxisContribution/AxisContribution.swift b/Sources/AxisContribution/AxisContribution.swift index d0fc95d..a66ab57 100644 --- a/Sources/AxisContribution/AxisContribution.swift +++ b/Sources/AxisContribution/AxisContribution.swift @@ -47,7 +47,7 @@ public struct AxisContribution: View where B: View, F: View { @StateObject private var store = ACDataStore() private var constant: ACConstant = .init() - private var sourceDatas: [Date]? = nil + private var sourceDatas: [Date: ACData] = [:] private var externalDatas: [[ACData]]? = nil public var background: ((ACIndexSet?, ACData?) -> B)? = nil @@ -85,11 +85,6 @@ public struct AxisContribution: View where B: View, F: View { .onChange(of: sourceDatas) { newValue in store.setup(constant: self.constant, source: newValue) } - .onChange(of: externalDatas) { newValue in - if let newValue { - store.setup(constant: self.constant, external: newValue) - } - } .onAppear(perform: { self.fetch() }) @@ -195,7 +190,7 @@ public extension AxisContribution where B == EmptyView, F == EmptyView { /// - Parameters: /// - constant: Settings that define the contribution view. /// - sourceDates: An array of contributed dates. - init(constant: ACConstant = .init(), source sourceDates: [Date] = []) { + init(constant: ACConstant = .init(), source sourceDates: [Date: ACData] = [:]) { self.constant = constant self.sourceDatas = sourceDates } @@ -219,7 +214,7 @@ public extension AxisContribution where B : View, F : View { /// - background: The view that is the background of the row view. /// - foreground: The view that is the foreground of the row view. init(constant: ACConstant = .init(), - source sourceDates: [Date] = [], + source sourceDates: [Date: ACData] = [:], @ViewBuilder background: @escaping (ACIndexSet?, ACData?) -> B, @ViewBuilder foreground: @escaping (ACIndexSet?, ACData?) -> F) { self.constant = constant @@ -246,6 +241,6 @@ public extension AxisContribution where B : View, F : View { struct AxisContribution_Previews: PreviewProvider { static var previews: some View { - AxisContribution(constant: .init(), source: []) + AxisContribution(constant: .init(), source: [:]) } } diff --git a/Sources/AxisContribution/View/ACGridStack.swift b/Sources/AxisContribution/View/ACGridStack.swift index 007c421..e2c972d 100644 --- a/Sources/AxisContribution/View/ACGridStack.swift +++ b/Sources/AxisContribution/View/ACGridStack.swift @@ -180,6 +180,6 @@ extension ACGridStack where B : View, F : View { struct ACGridStack_Previews: PreviewProvider { static var previews: some View { - AxisContribution(constant: .init(), source: []) + AxisContribution(constant: .init(), source: [:]) } } diff --git a/Sources/AxisContribution/ViewModel/ACDataProvider.swift b/Sources/AxisContribution/ViewModel/ACDataProvider.swift index b33f10f..541e558 100644 --- a/Sources/AxisContribution/ViewModel/ACDataProvider.swift +++ b/Sources/AxisContribution/ViewModel/ACDataProvider.swift @@ -35,7 +35,7 @@ public class ACDataProvider { /// - constant: Settings that define the contribution view. /// - sourceDates: An array of contributed dates. /// - Returns: mapped data - public func mappedData(constant: ACConstant, source sourceDates: [Date]) -> [[ACData]] { + public func mappedData(constant: ACConstant, source sourceDates: [Date: ACData]) -> [[ACData]] { var newDatas = [[ACData]]() var dateWeekly = Date.datesWeekly(from: constant.fromDate, to: constant.toDate) if constant.axisMode == .vertical { @@ -43,23 +43,14 @@ public class ACDataProvider { } dateWeekly.forEach { date in let datas = date.datesInWeek.map { date -> ACData in - let data = ACData(date: date, count: getDateCount(sourceDates: sourceDates, date: date)) - return data + if let data = sourceDates[date] { + return data + } else { + return ACData(date: date, count: 0) + } } newDatas.append(datas) } return newDatas } - - /// Returns data corresponding to the date you pass in. - /// - Parameters: - /// - sourceDates: An array of contributed dates. - /// - date: The date required to return the data. - /// - Returns: - - private func getDateCount(sourceDates: [Date], date: Date) -> Int { - let dates = sourceDates.filter { d in - Calendar.current.isDate(d, inSameDayAs: date) - } - return dates.count - } } diff --git a/Sources/AxisContribution/ViewModel/ACDataStore.swift b/Sources/AxisContribution/ViewModel/ACDataStore.swift index f8a22ec..4d5d70f 100644 --- a/Sources/AxisContribution/ViewModel/ACDataStore.swift +++ b/Sources/AxisContribution/ViewModel/ACDataStore.swift @@ -44,7 +44,7 @@ public class ACDataStore: ObservableObject { /// - Parameters: /// - constant: Settings that define the contribution view. /// - sourceDates: An array of contributed dates. - func setup(constant: ACConstant, source sourceDates: [Date]? = nil) { + func setup(constant: ACConstant, source sourceDates: [Date: ACData]? = nil) { self.constant = constant if let sourceDates = sourceDates { self.datas = ACDataProvider.shared.mappedData(constant: constant, source: sourceDates) From 7a3263c5d92c5ed680218a8e884f42558ccf03a6 Mon Sep 17 00:00:00 2001 From: race Date: Thu, 6 Apr 2023 22:20:37 +0800 Subject: [PATCH 5/8] Fix build --- .../AxisContributionExample.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AxisContributionExample/AxisContributionExample.xcodeproj/project.pbxproj b/AxisContributionExample/AxisContributionExample.xcodeproj/project.pbxproj index 395c811..c52481f 100644 --- a/AxisContributionExample/AxisContributionExample.xcodeproj/project.pbxproj +++ b/AxisContributionExample/AxisContributionExample.xcodeproj/project.pbxproj @@ -361,7 +361,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = SM6445X39C; + DEVELOPMENT_TEAM = 5FRV5G4F5S; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -391,7 +391,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = SM6445X39C; + DEVELOPMENT_TEAM = 5FRV5G4F5S; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; @@ -424,7 +424,7 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = SM6445X39C; + DEVELOPMENT_TEAM = 5FRV5G4F5S; ENABLE_HARDENED_RUNTIME = YES; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; From dc53f41556c0580c650e19a04dd35b9456d843fc Mon Sep 17 00:00:00 2001 From: race Date: Thu, 6 Apr 2023 23:14:37 +0800 Subject: [PATCH 6/8] Fix month title mix --- .../AxisContribution/View/ACGridStack.swift | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/Sources/AxisContribution/View/ACGridStack.swift b/Sources/AxisContribution/View/ACGridStack.swift index e2c972d..6b8af0e 100644 --- a/Sources/AxisContribution/View/ACGridStack.swift +++ b/Sources/AxisContribution/View/ACGridStack.swift @@ -27,12 +27,11 @@ import SwiftUI /// A view that represents a grid view. struct ACGridStack: View where B: View, F: View { - @EnvironmentObject private var store: ACDataStore let constant: ACConstant - var background: ((ACIndexSet?, ACData?) -> B)? = nil - var foreground: ((ACIndexSet?, ACData?) -> F)? = nil + var background: ((ACIndexSet?, ACData?) -> B)? + var foreground: ((ACIndexSet?, ACData?) -> F)? @State private var rowSize: CGSize = .zero @State private var titleWidth: CGFloat = .zero @@ -43,7 +42,8 @@ struct ACGridStack: View where B: View, F: View { .font(store.constant.font) } - //MARK: - Properties + // MARK: - Properties + /// Property that displays the grid view. private var content: some View { let spacing = store.constant.spacing @@ -66,14 +66,14 @@ struct ACGridStack: View where B: View, F: View { Rectangle() .fill(Color.clear) .frame(width: rowSize.height, height: rowSize.height) - .overlay(getMonthTitle(column) ,alignment: .leading) + .overlay(getMonthTitle(column), alignment: .leading) ForEach(Array(datas.enumerated()), id: \.offset) { row, data in getRowView(column: column, row: row, data: data) } } } } - }else { + } else { VStack(alignment: .leading, spacing: spacing) { ZStack(alignment: .bottom) { let size = titleWidth @@ -100,7 +100,7 @@ struct ACGridStack: View where B: View, F: View { } } - //MARK: - Methods + // MARK: - Methods /// A method that returns a row view. /// - Parameters: @@ -130,15 +130,18 @@ struct ACGridStack: View where B: View, F: View { .fixedSize(horizontal: true, vertical: false) .takeSize($_titleSize) } - }else { - Text(store.datas[column][0].date.monthTitle) - .lineLimit(1) - .fixedSize(horizontal: true, vertical: false) - .takeSize($_titleSize) + } else { + let date = store.datas[column][0].date.monthTitle + if date > constant.fromDate && date < constant.toDate { + Text(date.monthTitle) + .lineLimit(1) + .fixedSize(horizontal: true, vertical: false) + .takeSize($_titleSize) + } } } } - .onChange(of: _titleSize) { newValue in + .onChange(of: _titleSize) { _ in titleWidth = max(titleWidth, _titleSize.width) } } @@ -149,21 +152,20 @@ struct ACGridStack: View where B: View, F: View { private func getOpacity(count: Int) -> CGFloat { if count == 0 { return ACLevel.zero.opacity - }else if ACLevel.first.rawValue * store.constant.levelSpacing >= count { + } else if ACLevel.first.rawValue * store.constant.levelSpacing >= count { return ACLevel.first.opacity - }else if ACLevel.second.rawValue * store.constant.levelSpacing >= count { + } else if ACLevel.second.rawValue * store.constant.levelSpacing >= count { return ACLevel.second.opacity - }else if ACLevel.third.rawValue * store.constant.levelSpacing >= count { + } else if ACLevel.third.rawValue * store.constant.levelSpacing >= count { return ACLevel.third.opacity - }else if ACLevel.fourth.rawValue * store.constant.levelSpacing >= count { + } else if ACLevel.fourth.rawValue * store.constant.levelSpacing >= count { return ACLevel.fourth.opacity } return 1.0 } } -extension ACGridStack where B : View, F : View { - +extension ACGridStack where B: View, F: View { /// Initializes `ACGridStack` /// - Parameters: /// - constant: Settings that define the contribution view. @@ -171,7 +173,8 @@ extension ACGridStack where B : View, F : View { /// - foreground: The view that is the foreground of the row view. init(constant: ACConstant, @ViewBuilder background: @escaping (ACIndexSet?, ACData?) -> B, - @ViewBuilder foreground: @escaping (ACIndexSet?, ACData?) -> F) { + @ViewBuilder foreground: @escaping (ACIndexSet?, ACData?) -> F) + { self.constant = constant self.background = background self.foreground = foreground @@ -180,6 +183,12 @@ extension ACGridStack where B : View, F : View { struct ACGridStack_Previews: PreviewProvider { static var previews: some View { - AxisContribution(constant: .init(), source: [:]) + AxisContribution( + constant: .init( + from: Date().startOfYear, + to: Date().endOfYear + ), + source: [:] + ) } } From 1f9db980a5357d51f15b9f528bdb87bdedf379fb Mon Sep 17 00:00:00 2001 From: race Date: Thu, 6 Apr 2023 23:19:44 +0800 Subject: [PATCH 7/8] fix build error --- Sources/AxisContribution/View/ACGridStack.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/AxisContribution/View/ACGridStack.swift b/Sources/AxisContribution/View/ACGridStack.swift index 6b8af0e..2563730 100644 --- a/Sources/AxisContribution/View/ACGridStack.swift +++ b/Sources/AxisContribution/View/ACGridStack.swift @@ -131,7 +131,7 @@ struct ACGridStack: View where B: View, F: View { .takeSize($_titleSize) } } else { - let date = store.datas[column][0].date.monthTitle + let date = store.datas[column][0].date if date > constant.fromDate && date < constant.toDate { Text(date.monthTitle) .lineLimit(1) From 6a4d2e0eed2045993584e4803064834a2646b818 Mon Sep 17 00:00:00 2001 From: race Date: Thu, 6 Apr 2023 23:24:20 +0800 Subject: [PATCH 8/8] Fix build error... --- Sources/AxisContribution/View/ACGridStack.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Sources/AxisContribution/View/ACGridStack.swift b/Sources/AxisContribution/View/ACGridStack.swift index 2563730..87399cc 100644 --- a/Sources/AxisContribution/View/ACGridStack.swift +++ b/Sources/AxisContribution/View/ACGridStack.swift @@ -184,10 +184,7 @@ extension ACGridStack where B: View, F: View { struct ACGridStack_Previews: PreviewProvider { static var previews: some View { AxisContribution( - constant: .init( - from: Date().startOfYear, - to: Date().endOfYear - ), + constant: .init(), source: [:] ) }