diff --git a/PortfolioJournal.xcodeproj/project.pbxproj b/PortfolioJournal.xcodeproj/project.pbxproj index 013b550..357c96a 100644 --- a/PortfolioJournal.xcodeproj/project.pbxproj +++ b/PortfolioJournal.xcodeproj/project.pbxproj @@ -541,7 +541,7 @@ CODE_SIGN_ENTITLEMENTS = PortfolioJournal/PortfolioJournalDebug.entitlements; ENABLE_USER_SCRIPT_SANDBOXING = NO; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_ASSET_PATHS = PortfolioJournal/Assets.xcassets; DEVELOPMENT_TEAM = 2825Q76T7H; ENABLE_PREVIEWS = YES; @@ -582,7 +582,7 @@ CODE_SIGN_IDENTITY = "Apple Distribution"; CODE_SIGN_STYLE = Manual; PROVISIONING_PROFILE_SPECIFIER = "porfoliojournal"; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_ASSET_PATHS = PortfolioJournal/Assets.xcassets; DEVELOPMENT_TEAM = 2825Q76T7H; ENABLE_PREVIEWS = YES; @@ -739,7 +739,7 @@ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; CODE_SIGN_ENTITLEMENTS = PortfolioJournalWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_ASSET_PATHS = PortfolioJournalWidget/Assets.xcassets; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = NO; @@ -774,7 +774,7 @@ CODE_SIGN_IDENTITY = "Apple Distribution"; CODE_SIGN_STYLE = Manual; PROVISIONING_PROFILE_SPECIFIER = "Portfolio Journalwidget"; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_ASSET_PATHS = PortfolioJournalWidget/Assets.xcassets; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = NO; @@ -805,7 +805,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.6; @@ -829,7 +829,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.6; @@ -852,7 +852,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.6; @@ -875,7 +875,7 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.6; @@ -899,7 +899,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = PortfolioJournalQuickUpdateExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_TEAM = 2825Q76T7H; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = PortfolioJournalQuickUpdate/Info.plist; @@ -927,7 +927,7 @@ CODE_SIGN_ENTITLEMENTS = PortfolioJournalQuickUpdateExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 80; + CURRENT_PROJECT_VERSION = 81; DEVELOPMENT_TEAM = 2825Q76T7H; PROVISIONING_PROFILE_SPECIFIER = "PortfolioJournal QuickUpdate AppStore"; GENERATE_INFOPLIST_FILE = NO; diff --git a/PortfolioJournal/Views/Charts/DrawdownChart.swift b/PortfolioJournal/Views/Charts/DrawdownChart.swift index ba87a8a..8b586e9 100644 --- a/PortfolioJournal/Views/Charts/DrawdownChart.swift +++ b/PortfolioJournal/Views/Charts/DrawdownChart.swift @@ -3,6 +3,8 @@ import Charts struct DrawdownChart: View { let data: [(date: Date, drawdown: Double)] + /// Hidden when the host (e.g. a dashboard card) already shows a title. + var showsTitle: Bool = true @State private var zoom = ChartZoomModel() @State private var selectedDate: Date? @Environment(\.horizontalSizeClass) private var labelsSizeClass @@ -26,8 +28,10 @@ struct DrawdownChart: View { var body: some View { VStack(alignment: .leading, spacing: 16) { HStack { - Text("Drawdown Analysis") - .font(.headline) + if showsTitle { + Text("Drawdown Analysis") + .font(.headline) + } Spacer() @@ -207,6 +211,8 @@ struct DrawdownStatView: View { struct VolatilityChartView: View { let data: [(date: Date, volatility: Double)] + /// Hidden when the host (e.g. a dashboard card) already shows a title. + var showsTitle: Bool = true @State private var zoom = ChartZoomModel() @State private var selectedDate: Date? @Environment(\.horizontalSizeClass) private var labelsSizeClass @@ -230,11 +236,13 @@ struct VolatilityChartView: View { var body: some View { VStack(alignment: .leading, spacing: 16) { - HStack { - Text("Volatility") - .font(.headline) + if showsTitle { + HStack { + Text("Volatility") + .font(.headline) - Spacer() + Spacer() + } } Text("Measures price variability over time") diff --git a/PortfolioJournal/Views/Charts/PerformanceBarChart.swift b/PortfolioJournal/Views/Charts/PerformanceBarChart.swift index 0f1838f..9ab0088 100644 --- a/PortfolioJournal/Views/Charts/PerformanceBarChart.swift +++ b/PortfolioJournal/Views/Charts/PerformanceBarChart.swift @@ -185,6 +185,8 @@ struct PerformanceBarChart: View { struct HorizontalPerformanceChart: View { let data: [(category: String, cagr: Double, color: String)] + /// Hidden when the host (e.g. a dashboard card) already shows a title. + var showsTitle: Bool = true var sortedData: [(category: String, cagr: Double, color: String)] { data.sorted { $0.cagr > $1.cagr } @@ -196,8 +198,10 @@ struct HorizontalPerformanceChart: View { var body: some View { VStack(alignment: .leading, spacing: 16) { - Text("Performance by Category") - .font(.headline) + if showsTitle { + Text("Performance by Category") + .font(.headline) + } ForEach(sortedData, id: \.category) { item in VStack(alignment: .leading, spacing: 4) { diff --git a/PortfolioJournal/Views/Charts/PredictionChartView.swift b/PortfolioJournal/Views/Charts/PredictionChartView.swift index 6c511da..6c34d50 100644 --- a/PortfolioJournal/Views/Charts/PredictionChartView.swift +++ b/PortfolioJournal/Views/Charts/PredictionChartView.swift @@ -4,6 +4,8 @@ import Charts struct PredictionChartView: View { let predictions: [Prediction] let historicalData: [(date: Date, value: Decimal)] + /// Hidden when the host (e.g. a dashboard card) already shows a title. + var showsTitle: Bool = true @State private var selectedDate: Date? @Environment(\.horizontalSizeClass) private var labelsSizeClass @@ -23,8 +25,10 @@ struct PredictionChartView: View { var body: some View { VStack(alignment: .leading, spacing: 16) { HStack { - Text(predictions.isEmpty ? "Prediction" : "\(predictions.count)-Month Prediction") - .font(.headline) + if showsTitle { + Text(predictions.isEmpty ? "Prediction" : "\(predictions.count)-Month Prediction") + .font(.headline) + } Spacer() diff --git a/PortfolioJournal/Views/Charts/YearOverYearChartView.swift b/PortfolioJournal/Views/Charts/YearOverYearChartView.swift index d9ce87a..f06e42b 100644 --- a/PortfolioJournal/Views/Charts/YearOverYearChartView.swift +++ b/PortfolioJournal/Views/Charts/YearOverYearChartView.swift @@ -3,6 +3,8 @@ import Charts struct YearOverYearChartView: View { @ObservedObject var viewModel: ChartsViewModel + /// Hidden when the host (e.g. a dashboard card) already shows a title. + var showsTitle: Bool = true @State private var selectedMonthIdx: Int? private let monthAbbreviations = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -20,8 +22,10 @@ struct YearOverYearChartView: View { var body: some View { VStack(alignment: .leading, spacing: 16) { - Text(String(localized: "chart_yoy_title")) - .font(.headline) + if showsTitle { + Text(String(localized: "chart_yoy_title")) + .font(.headline) + } if allYears.isEmpty { Text(String(localized: "chart_yoy_empty")) diff --git a/PortfolioJournal/Views/Dashboard/EvolutionChart.swift b/PortfolioJournal/Views/Dashboard/EvolutionChart.swift index ccda7ac..d539cf9 100644 --- a/PortfolioJournal/Views/Dashboard/EvolutionChart.swift +++ b/PortfolioJournal/Views/Dashboard/EvolutionChart.swift @@ -177,19 +177,22 @@ struct EvolutionChartCard: View { .frame(height: 150) .padding(.vertical, 8) allocationLegend + // showsTitle: false — the card header already names the page; + // the embedded charts' own titles duplicated it. case .performance: - HorizontalPerformanceChart(data: chartsVM.performanceData) + HorizontalPerformanceChart(data: chartsVM.performanceData, showsTitle: false) case .drawdown: - DrawdownChart(data: chartsVM.drawdownData) + DrawdownChart(data: chartsVM.drawdownData, showsTitle: false) case .volatility: - VolatilityChartView(data: chartsVM.volatilityData) + VolatilityChartView(data: chartsVM.volatilityData, showsTitle: false) case .prediction: PredictionChartView( predictions: chartsVM.predictionData, - historicalData: chartsVM.evolutionData + historicalData: chartsVM.evolutionData, + showsTitle: false ) case .yearOverYear: - YearOverYearChartView(viewModel: chartsVM) + YearOverYearChartView(viewModel: chartsVM, showsTitle: false) } } }