Browse Source

Feature/add switch to choose between tracking or exposed currency in allocation chart

Co-authored-by: Copilot <copilot@github.com>
pull/6969/head
swissbuechi 3 months ago
parent
commit
e91478dbf4
  1. 68
      apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts
  2. 13
      apps/client/src/app/pages/portfolio/allocations/allocations-page.html

68
apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts

@ -9,6 +9,7 @@ import {
HoldingWithParents,
PortfolioDetails,
PortfolioPosition,
ToggleOption,
User
} from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
@ -17,6 +18,7 @@ import { translate } from '@ghostfolio/ui/i18n';
import { GfPortfolioProportionChartComponent } from '@ghostfolio/ui/portfolio-proportion-chart';
import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator';
import { DataService } from '@ghostfolio/ui/services';
import { GfToggleComponent } from '@ghostfolio/ui/toggle';
import { GfTopHoldingsComponent } from '@ghostfolio/ui/top-holdings';
import { GfValueComponent } from '@ghostfolio/ui/value';
import { GfWorldMapChartComponent } from '@ghostfolio/ui/world-map-chart';
@ -46,6 +48,7 @@ import { DeviceDetectorService } from 'ngx-device-detector';
imports: [
GfPortfolioProportionChartComponent,
GfPremiumIndicatorComponent,
GfToggleComponent,
GfTopHoldingsComponent,
GfValueComponent,
GfWorldMapChartComponent,
@ -69,6 +72,14 @@ export class GfAllocationsPageComponent implements OnInit {
public countries: {
[code: string]: { name: string; value: number };
};
public currencyHoldings: {
[key: string]: { name: string; value: number };
};
public currencyMode: 'exposure' | 'tracking' = 'tracking';
public currencyModeOptions: ToggleOption[] = [
{ label: $localize`Tracking`, value: 'tracking' },
{ label: $localize`Exposure`, value: 'exposure' }
];
public deviceType: string;
public hasImpersonationId: boolean;
public holdings: {
@ -120,6 +131,13 @@ export class GfAllocationsPageComponent implements OnInit {
public user: User;
public worldMapChartFormat: string;
private currencyHoldingsExposure: {
[key: string]: { name: string; value: number };
};
private currencyHoldingsTracking: {
[key: string]: { name: string; value: number };
};
public constructor(
private changeDetectorRef: ChangeDetectorRef,
private dataService: DataService,
@ -193,6 +211,15 @@ export class GfAllocationsPageComponent implements OnInit {
}
}
public onCurrencyModeChanged(mode: 'exposure' | 'tracking') {
this.currencyMode = mode;
this.currencyHoldings =
mode === 'exposure'
? this.currencyHoldingsExposure
: this.currencyHoldingsTracking;
this.changeDetectorRef.markForCheck();
}
public onSymbolChartClicked({ dataSource, symbol }: AssetProfileIdentifier) {
if (dataSource && symbol) {
this.router.navigate([], {
@ -237,6 +264,9 @@ export class GfAllocationsPageComponent implements OnInit {
value: 0
}
};
this.currencyHoldings = {};
this.currencyHoldingsExposure = {};
this.currencyHoldingsTracking = {};
this.holdings = {};
this.marketsAdvanced = {
[UNKNOWN_KEY]: {
@ -348,6 +378,44 @@ export class GfAllocationsPageComponent implements OnInit {
name: position.assetProfile.name
};
// For the "By Currency" chart:
// - Exposure: shows crypto names instead of tracking currency
// - Tracking: shows the tracking currency for all assets
const exposureKey =
position.assetProfile.assetSubClass === 'CRYPTOCURRENCY' ||
position.assetProfile.assetSubClass === 'PRECIOUS_METAL'
? position.assetProfile.name
: position.assetProfile.currency;
const trackingKey = position.assetProfile.currency;
if (this.currencyHoldingsExposure[exposureKey]?.value) {
this.currencyHoldingsExposure[exposureKey].value += value;
} else {
this.currencyHoldingsExposure[exposureKey] = {
name: exposureKey,
value
};
}
if (this.currencyHoldingsTracking[trackingKey]?.value) {
this.currencyHoldingsTracking[trackingKey].value += value;
} else {
this.currencyHoldingsTracking[trackingKey] = {
name: trackingKey,
value
};
}
// Set default based on experimental features setting
if (
!this.currencyHoldings ||
Object.keys(this.currencyHoldings).length === 0
) {
this.currencyMode = 'tracking';
this.currencyHoldings = this.currencyHoldingsTracking;
}
if (position.assetProfile.assetClass !== AssetClass.LIQUIDITY) {
// Prepare analysis data by continents, countries, holdings and sectors except for liquidity

13
apps/client/src/app/pages/portfolio/allocations/allocations-page.html

@ -63,14 +63,23 @@
<gf-premium-indicator class="ml-1" />
}
</mat-card-title>
@if (user?.settings?.isExperimentalFeatures) {
<gf-toggle
class="d-none d-lg-block"
[defaultValue]="currencyMode"
[isLoading]="false"
[options]="currencyModeOptions"
(valueChange)="onCurrencyModeChanged($event.value)"
/>
}
</mat-card-header>
<mat-card-content>
<gf-portfolio-proportion-chart
[baseCurrency]="user?.settings?.baseCurrency"
[colorScheme]="user?.settings?.colorScheme"
[data]="holdings"
[data]="currencyHoldings"
[isInPercentage]="showValuesInPercentage()"
[keys]="['currency']"
[keys]="['name']"
[locale]="user?.settings?.locale"
/>
</mat-card-content>

Loading…
Cancel
Save