From c78d20494455804d9c8d68293001a88b55d21756 Mon Sep 17 00:00:00 2001 From: mister-ideas <36502095+mister-ideas@users.noreply.github.com> Date: Thu, 22 Oct 2026 22:47:31 +0200 Subject: [PATCH] Feature/refresh the chart of the home page without redrawing it --- CHANGELOG.md | 2 +- .../home-overview/home-overview.component.ts | 30 ++++++++++++------- .../lib/line-chart/line-chart.component.ts | 8 ++++- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d64b985ef7..6453580dcd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Added a periodic refresh of the numbers on the home, analysis and accounts pages while the page is visible, briefly coloring changed values green or red, with a live indicator in the header +- Added a periodic refresh of the numbers on the home, analysis and accounts pages while the page is visible, briefly coloring changed values green or red, moving the chart of the home page without redrawing it, with a live indicator in the header - Added a link to the holdings tab in the holdings table on the overview tab of the home page (experimental) ### Changed diff --git a/apps/client/src/app/components/home-overview/home-overview.component.ts b/apps/client/src/app/components/home-overview/home-overview.component.ts index 06e99f40d4..8e53a9689b 100644 --- a/apps/client/src/app/components/home-overview/home-overview.component.ts +++ b/apps/client/src/app/components/home-overview/home-overview.component.ts @@ -14,6 +14,7 @@ import { AssetProfileIdentifier, LineChartItem, PortfolioPerformance, + PortfolioPerformanceResponse, PortfolioPosition, User } from '@ghostfolio/common/interfaces'; @@ -178,11 +179,14 @@ export class GfHomeOverviewComponent implements OnInit { }), takeUntilDestroyed(this.destroyRef) ) - .subscribe(({ errors, isMarketOpen, performance }) => { + .subscribe(({ chart, errors, isMarketOpen, performance }) => { this.errors.set(errors ?? []); this.isMarketOpen.set(isMarketOpen); this.performance.set(performance); + // Same series: the line chart moves without the drawing animation + this.historicalDataItems.set(this.getChartItems(chart)); + this.autoRefreshService.markUpdated(); }); @@ -225,6 +229,19 @@ export class GfHomeOverviewComponent implements OnInit { }); } + private getChartItems( + chart?: PortfolioPerformanceResponse['chart'] + ): LineChartItem[] | null { + return ( + chart?.map(({ date, netPerformanceInPercentageWithCurrencyEffect }) => { + return { + date, + value: (netPerformanceInPercentageWithCurrencyEffect ?? 0) * 100 + }; + }) ?? null + ); + } + private update() { const userSettings = this.user()?.settings; @@ -255,16 +272,7 @@ export class GfHomeOverviewComponent implements OnInit { this.isMarketOpen.set(isMarketOpen); this.performance.set(performance); - this.historicalDataItems.set( - chart?.map( - ({ date, netPerformanceInPercentageWithCurrencyEffect }) => { - return { - date, - value: (netPerformanceInPercentageWithCurrencyEffect ?? 0) * 100 - }; - } - ) ?? null - ); + this.historicalDataItems.set(this.getChartItems(chart)); this.precision.set(2); diff --git a/libs/ui/src/lib/line-chart/line-chart.component.ts b/libs/ui/src/lib/line-chart/line-chart.component.ts index d910033bc0..f0185b2caf 100644 --- a/libs/ui/src/lib/line-chart/line-chart.component.ts +++ b/libs/ui/src/lib/line-chart/line-chart.component.ts @@ -199,6 +199,12 @@ export class GfLineChartComponent }; if (this.chart) { + // A refresh of the same series (e.g. a background refresh) only moves + // the line, the drawing animation is kept for a new series + const isRefresh = + this.chart.data.labels?.length === labels.length && + this.chart.data.labels?.[0] === labels[0]; + this.chart.data = data; this.chart.options.plugins ??= {}; this.chart.options.plugins.tooltip = @@ -207,7 +213,7 @@ export class GfLineChartComponent ? animations : undefined; - this.chart.update(); + this.chart.update(isRefresh ? 'none' : undefined); } else { this.chart = new Chart<'line'>(this.chartCanvas.nativeElement, { data,