From 64c480da39cbc30d227f2d79d281271a9a0bc26d Mon Sep 17 00:00:00 2001 From: adityagarud Date: Mon, 13 Oct 2025 19:42:45 +0530 Subject: [PATCH] Fix chart X-axis synchronization for #3998 --- .../analysis/analysis-page.component.ts | 32 +++- .../portfolio/analysis/analysis-page.html | 12 +- test-charts.html | 160 ++++++++++++++++++ 3 files changed, 197 insertions(+), 7 deletions(-) create mode 100644 test-charts.html diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index c8a7ed4b7..3a3ad9056 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -100,6 +100,8 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { public portfolioEvolutionDataLabel = $localize`Investment`; public portfolioEvolutionXMax: Date; public portfolioEvolutionXMin: Date; + public globalXMax: Date; + public globalXMin: Date; public streaks: PortfolioInvestments['streaks']; public top3: PortfolioPosition[]; public unitCurrentStreak: string; @@ -419,6 +421,35 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { // Calculate min and max dates for chart scaling based on filtered data // This ensures charts are scaled proportionally to the selected time period + const allDates: Date[] = []; + + if (this.performanceDataItems && this.performanceDataItems.length > 0) { + allDates.push( + ...this.performanceDataItems.map((item) => new Date(item.date)) + ); + } + + if (this.investmentsByGroup && this.investmentsByGroup.length > 0) { + allDates.push( + ...this.investmentsByGroup.map((item) => new Date(item.date)) + ); + } + + if (this.dividendsByGroup && this.dividendsByGroup.length > 0) { + allDates.push( + ...this.dividendsByGroup.map((item) => new Date(item.date)) + ); + } + + if (allDates.length > 0) { + this.globalXMin = new Date(Math.min(...allDates.map((d) => d.getTime()))); + this.globalXMax = new Date(Math.max(...allDates.map((d) => d.getTime()))); + } else { + this.globalXMin = undefined; + this.globalXMax = undefined; + } + + // Individual ranges for specific charts (fallback if needed) if (this.performanceDataItems && this.performanceDataItems.length > 0) { const dates = this.performanceDataItems.map( (item) => new Date(item.date) @@ -430,7 +461,6 @@ export class GfAnalysisPageComponent implements OnDestroy, OnInit { Math.max(...dates.map((d) => d.getTime())) ); } else { - // Fallback to undefined if no data, allowing chart to use default scaling this.portfolioEvolutionXMin = undefined; this.portfolioEvolutionXMax = undefined; } diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html index a0a878e49..a45bc394c 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -354,8 +354,8 @@ [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" [isLoading]="isLoadingInvestmentChart" [locale]="user?.settings?.locale" - [xMax]="portfolioEvolutionXMax" - [xMin]="portfolioEvolutionXMin" + [xMax]="globalXMax" + [xMin]="globalXMin" /> @@ -413,8 +413,8 @@ [isLoading]="isLoadingInvestmentTimelineChart" [locale]="user?.settings?.locale" [savingsRate]="savingsRate" - [xMax]="investmentTimelineXMax" - [xMin]="investmentTimelineXMin" + [xMax]="globalXMax" + [xMin]="globalXMin" /> @@ -449,8 +449,8 @@ [isInPercent]="hasImpersonationId || user.settings.isRestrictedView" [isLoading]="isLoadingDividendTimelineChart" [locale]="user?.settings?.locale" - [xMax]="dividendTimelineXMax" - [xMin]="dividendTimelineXMin" + [xMax]="globalXMax" + [xMin]="globalXMin" /> diff --git a/test-charts.html b/test-charts.html new file mode 100644 index 000000000..7b86770af --- /dev/null +++ b/test-charts.html @@ -0,0 +1,160 @@ + + + + + + Chart UI Test - Ghostfolio #3998 + + + + + +

Mock Frontend: Chart Visual Comparability Test (#3998)

+

+ This is a simple test page to verify chart scaling with mocked data. No + server needed. +

+ + +

Portfolio Performance Chart

+
+ +
+ + +

Investment Timeline Chart

+
+ +
+ + + +