From 3ad99c9991223d933932819da18602cead3041cb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 6 Sep 2022 20:39:27 +0200 Subject: [PATCH] Add data management (#1230) * Add data management for benchmarks --- .../src/app/benchmark/benchmark.controller.ts | 32 ++++++- .../src/app/benchmark/benchmark.service.ts | 45 ++++++++- apps/api/src/app/info/info.module.ts | 2 +- .../admin-market-data-detail.component.ts | 3 +- .../benchmark-comparator.component.html | 4 +- .../benchmark-comparator.component.ts | 94 ++++++------------- .../home-overview/home-overview.component.ts | 2 +- .../position-detail-dialog.component.ts | 6 +- .../analysis/analysis-page.component.ts | 40 +++++++- .../portfolio/analysis/analysis-page.html | 6 +- .../pages/register/register-page.component.ts | 3 +- apps/client/src/app/services/data.service.ts | 20 +++- ...benchmark-market-data-details.interface.ts | 5 + libs/common/src/lib/interfaces/index.ts | 4 + .../interfaces/line-chart-item.interface.ts} | 0 .../lib/line-chart/line-chart.component.ts | 3 +- 16 files changed, 182 insertions(+), 87 deletions(-) create mode 100644 libs/common/src/lib/interfaces/benchmark-market-data-details.interface.ts rename libs/{ui/src/lib/line-chart/interfaces/line-chart.interface.ts => common/src/lib/interfaces/line-chart-item.interface.ts} (100%) diff --git a/apps/api/src/app/benchmark/benchmark.controller.ts b/apps/api/src/app/benchmark/benchmark.controller.ts index 4638e0c4f..b5562bf86 100644 --- a/apps/api/src/app/benchmark/benchmark.controller.ts +++ b/apps/api/src/app/benchmark/benchmark.controller.ts @@ -1,7 +1,18 @@ import { TransformDataSourceInRequestInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-request.interceptor'; import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interceptors/transform-data-source-in-response.interceptor'; -import { BenchmarkResponse } from '@ghostfolio/common/interfaces'; -import { Controller, Get, UseInterceptors } from '@nestjs/common'; +import { + BenchmarkMarketDataDetails, + BenchmarkResponse +} from '@ghostfolio/common/interfaces'; +import { + Controller, + Get, + Param, + UseGuards, + UseInterceptors +} from '@nestjs/common'; +import { AuthGuard } from '@nestjs/passport'; +import { DataSource } from '@prisma/client'; import { BenchmarkService } from './benchmark.service'; @@ -17,4 +28,21 @@ export class BenchmarkController { benchmarks: await this.benchmarkService.getBenchmarks() }; } + + @Get(':dataSource/:symbol/:startDateString') + @UseInterceptors(TransformDataSourceInRequestInterceptor) + @UseGuards(AuthGuard('jwt')) + public async getBenchmarkMarketDataBySymbol( + @Param('dataSource') dataSource: DataSource, + @Param('startDateString') startDateString: string, + @Param('symbol') symbol: string + ): Promise { + const startDate = new Date(startDateString); + + return this.benchmarkService.getMarketDataBySymbol({ + dataSource, + startDate, + symbol + }); + } } diff --git a/apps/api/src/app/benchmark/benchmark.service.ts b/apps/api/src/app/benchmark/benchmark.service.ts index 559595cc5..351ec2974 100644 --- a/apps/api/src/app/benchmark/benchmark.service.ts +++ b/apps/api/src/app/benchmark/benchmark.service.ts @@ -4,9 +4,15 @@ import { MarketDataService } from '@ghostfolio/api/services/market-data.service' import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile.service'; import { PROPERTY_BENCHMARKS } from '@ghostfolio/common/config'; -import { BenchmarkResponse, UniqueAsset } from '@ghostfolio/common/interfaces'; +import { DATE_FORMAT } from '@ghostfolio/common/helper'; +import { + BenchmarkMarketDataDetails, + BenchmarkResponse, + UniqueAsset +} from '@ghostfolio/common/interfaces'; import { Injectable } from '@nestjs/common'; import Big from 'big.js'; +import { format } from 'date-fns'; import ms from 'ms'; @Injectable() @@ -111,6 +117,43 @@ export class BenchmarkService { }); } + public async getMarketDataBySymbol({ + dataSource, + startDate, + symbol + }: { startDate: Date } & UniqueAsset): Promise { + const marketDataItems = await this.marketDataService.marketDataItems({ + orderBy: { + date: 'asc' + }, + where: { + dataSource, + symbol, + date: { + gte: startDate + } + } + }); + + const marketPriceAtStartDate = new Big( + marketDataItems?.[0]?.marketPrice ?? 0 + ); + + return { + marketData: marketDataItems.map((marketDataItem) => { + return { + date: format(marketDataItem.date, DATE_FORMAT), + value: marketPriceAtStartDate.eq(0) + ? 0 + : new Big(marketDataItem.marketPrice) + .div(marketPriceAtStartDate) + .minus(1) + .toNumber() * 100 + }; + }) + }; + } + private getMarketCondition(aPerformanceInPercent: Big) { return aPerformanceInPercent.lte(-0.2) ? 'BEAR_MARKET' : 'NEUTRAL_MARKET'; } diff --git a/apps/api/src/app/info/info.module.ts b/apps/api/src/app/info/info.module.ts index 9bddb769f..4c9c9f9d9 100644 --- a/apps/api/src/app/info/info.module.ts +++ b/apps/api/src/app/info/info.module.ts @@ -1,3 +1,4 @@ +import { BenchmarkModule } from '@ghostfolio/api/app/benchmark/benchmark.module'; import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration.module'; import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering.module'; @@ -9,7 +10,6 @@ import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile.mod import { TagModule } from '@ghostfolio/api/services/tag/tag.module'; import { Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; -import { BenchmarkModule } from '@ghostfolio/api/app/benchmark/benchmark.module'; import { InfoController } from './info.controller'; import { InfoService } from './info.service'; diff --git a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts index b4a715a95..eb5f8207f 100644 --- a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts +++ b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts @@ -14,8 +14,7 @@ import { getDateFormatString, getLocale } from '@ghostfolio/common/helper'; -import { User } from '@ghostfolio/common/interfaces'; -import { LineChartItem } from '@ghostfolio/ui/line-chart/interfaces/line-chart.interface'; +import { LineChartItem, User } from '@ghostfolio/common/interfaces'; import { DataSource, MarketData } from '@prisma/client'; import { addDays, diff --git a/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html b/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html index 104651b68..35d808497 100644 --- a/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html +++ b/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html @@ -1,4 +1,4 @@ -
+
Benchmarks Beta @@ -12,7 +12,7 @@ Compare with... {{ diff --git a/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts b/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts index af1bcb105..aca6229fc 100644 --- a/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts +++ b/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts @@ -3,9 +3,11 @@ import 'chartjs-adapter-date-fns'; import { ChangeDetectionStrategy, Component, + EventEmitter, Input, OnChanges, OnDestroy, + Output, ViewChild } from '@angular/core'; import { @@ -17,12 +19,13 @@ import { primaryColorRgb, secondaryColorRgb } from '@ghostfolio/common/config'; import { getBackgroundColor, getDateFormatString, - getTextColor, - parseDate, - transformTickToAbbreviation + getTextColor } from '@ghostfolio/common/helper'; -import { UniqueAsset, User } from '@ghostfolio/common/interfaces'; -import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface'; +import { + LineChartItem, + UniqueAsset, + User +} from '@ghostfolio/common/interfaces'; import { Chart, LineController, @@ -33,7 +36,6 @@ import { Tooltip } from 'chart.js'; import annotationPlugin from 'chartjs-plugin-annotation'; -import { addDays, isAfter, parseISO, subDays } from 'date-fns'; @Component({ selector: 'gf-benchmark-comparator', @@ -42,21 +44,20 @@ import { addDays, isAfter, parseISO, subDays } from 'date-fns'; styleUrls: ['./benchmark-comparator.component.scss'] }) export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { + @Input() benchmarkDataItems: LineChartItem[] = []; @Input() benchmarks: UniqueAsset[]; - @Input() currency: string; @Input() daysInMarket: number; - @Input() investments: InvestmentItem[]; - @Input() isInPercent = false; @Input() locale: string; + @Input() performanceDataItems: LineChartItem[]; @Input() user: User; + @Output() benchmarkChanged = new EventEmitter(); + @ViewChild('chartCanvas') chartCanvas; + public benchmark: UniqueAsset; public chart: Chart; public isLoading = true; - public value; - - private data: InvestmentItem[]; public constructor() { Chart.register( @@ -74,13 +75,13 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { } public ngOnChanges() { - if (this.investments) { + if (this.performanceDataItems) { this.initialize(); } } - public onChangeBenchmark(aBenchmark: any) { - console.log(aBenchmark); + public onChangeBenchmark(aBenchmark: UniqueAsset) { + this.benchmarkChanged.next(aBenchmark); } public ngOnDestroy() { @@ -90,61 +91,26 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { private initialize() { this.isLoading = true; - // Create a clone - this.data = this.investments.map((a) => Object.assign({}, a)); - - if (this.data?.length > 0) { - // Extend chart by 5% of days in market (before) - const firstItem = this.data[0]; - this.data.unshift({ - ...firstItem, - date: subDays( - parseISO(firstItem.date), - this.daysInMarket * 0.05 || 90 - ).toISOString(), - investment: 0 - }); - - // Extend chart by 5% of days in market (after) - const lastItem = this.data[this.data.length - 1]; - this.data.push({ - ...lastItem, - date: addDays( - parseDate(lastItem.date), - this.daysInMarket * 0.05 || 90 - ).toISOString() - }); - } - const data = { - labels: this.data.map((investmentItem) => { - return investmentItem.date; + labels: this.performanceDataItems.map(({ date }) => { + return date; }), datasets: [ { backgroundColor: `rgb(${primaryColorRgb.r}, ${primaryColorRgb.g}, ${primaryColorRgb.b})`, borderColor: `rgb(${primaryColorRgb.r}, ${primaryColorRgb.g}, ${primaryColorRgb.b})`, borderWidth: 2, - data: this.data.map((position) => { - return position.investment; + data: this.performanceDataItems.map(({ value }) => { + return value; }), - label: $localize`Deposit`, - segment: { - borderColor: (context: unknown) => - this.isInFuture( - context, - `rgba(${primaryColorRgb.r}, ${primaryColorRgb.g}, ${primaryColorRgb.b}, 0.67)` - ), - borderDash: (context: unknown) => this.isInFuture(context, [2, 2]) - }, - stepped: true + label: $localize`Portfolio` }, { backgroundColor: `rgb(${secondaryColorRgb.r}, ${secondaryColorRgb.g}, ${secondaryColorRgb.b})`, borderColor: `rgb(${secondaryColorRgb.r}, ${secondaryColorRgb.g}, ${secondaryColorRgb.b})`, borderWidth: 2, - data: this.data.map((position) => { - return position.investment * 1.75; + data: this.benchmarkDataItems.map(({ value }) => { + return value; }), label: $localize`Benchmark` } @@ -212,7 +178,7 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { } }, y: { - display: !this.isInPercent, + display: true, grid: { borderColor: `rgba(${getTextColor()}, 0.1)`, color: `rgba(${getTextColor()}, 0.8)`, @@ -222,7 +188,7 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { position: 'right', ticks: { callback: (value: number) => { - return transformTickToAbbreviation(value); + return `${value} %`; }, display: true, mirror: true, @@ -243,8 +209,8 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { private getTooltipPluginConfiguration() { return { ...getTooltipOptions({ - locale: this.isInPercent ? undefined : this.locale, - unit: this.isInPercent ? undefined : this.currency + locale: this.locale, + unit: '%' }), mode: 'index', position: 'top', @@ -252,10 +218,4 @@ export class BenchmarkComparatorComponent implements OnChanges, OnDestroy { yAlign: 'bottom' }; } - - private isInFuture(aContext: any, aValue: T) { - return isAfter(new Date(aContext?.p1?.parsed?.x), new Date()) - ? aValue - : undefined; - } } 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 2017518e7..5d4fd6aa2 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 @@ -8,13 +8,13 @@ import { } from '@ghostfolio/client/services/settings-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { + LineChartItem, PortfolioPerformance, UniqueAsset, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { DateRange } from '@ghostfolio/common/types'; -import { LineChartItem } from '@ghostfolio/ui/line-chart/interfaces/line-chart.interface'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts index 3e9006111..f8d3038b7 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts @@ -9,9 +9,11 @@ import { import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { DataService } from '@ghostfolio/client/services/data.service'; import { DATE_FORMAT, downloadAsFile } from '@ghostfolio/common/helper'; -import { EnhancedSymbolProfile } from '@ghostfolio/common/interfaces'; +import { + EnhancedSymbolProfile, + LineChartItem +} from '@ghostfolio/common/interfaces'; import { OrderWithAccount } from '@ghostfolio/common/types'; -import { LineChartItem } from '@ghostfolio/ui/line-chart/interfaces/line-chart.interface'; import { Tag } from '@prisma/client'; import { format, isSameMonth, isToday, parseISO } from 'date-fns'; import { Subject } from 'rxjs'; 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 0f40cb983..124e46a78 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 @@ -2,7 +2,12 @@ import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { Position, UniqueAsset, User } from '@ghostfolio/common/interfaces'; +import { + HistoricalDataItem, + Position, + UniqueAsset, + User +} from '@ghostfolio/common/interfaces'; import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface'; import { GroupBy, ToggleOption } from '@ghostfolio/common/types'; import { differenceInDays } from 'date-fns'; @@ -18,10 +23,12 @@ import { takeUntil } from 'rxjs/operators'; templateUrl: './analysis-page.html' }) export class AnalysisPageComponent implements OnDestroy, OnInit { + public benchmarkDataItems: HistoricalDataItem[] = []; public benchmarks: UniqueAsset[]; public bottom3: Position[]; public daysInMarket: number; public deviceType: string; + public firstOrderDate: Date; public hasImpersonationId: boolean; public investments: InvestmentItem[]; public investmentsByMonth: InvestmentItem[]; @@ -30,6 +37,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { { label: $localize`Monthly`, value: 'month' }, { label: $localize`Accumulating`, value: undefined } ]; + public performanceDataItems: HistoricalDataItem[]; public top3: Position[]; public user: User; @@ -56,6 +64,16 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { this.hasImpersonationId = !!aId; }); + this.dataService + .fetchChart({ range: 'max', version: 2 }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(({ chart }) => { + this.firstOrderDate = new Date(chart?.[0]?.date); + this.performanceDataItems = chart; + + this.changeDetectorRef.markForCheck(); + }); + this.dataService .fetchInvestments() .pipe(takeUntil(this.unsubscribeSubject)) @@ -106,6 +124,26 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { }); } + public onChangeBenchmark({ dataSource, symbol }: UniqueAsset) { + this.dataService + .fetchBenchmarkBySymbol({ + dataSource, + symbol, + startDate: this.firstOrderDate + }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(({ marketData }) => { + this.benchmarkDataItems = marketData.map(({ date, value }) => { + return { + date, + value + }; + }); + + this.changeDetectorRef.markForCheck(); + }); + } + public onChangeGroupBy(aMode: GroupBy) { this.mode = aMode; } 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 8b7044770..0c09ae916 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -4,13 +4,13 @@
diff --git a/apps/client/src/app/pages/register/register-page.component.ts b/apps/client/src/app/pages/register/register-page.component.ts index 1a7278304..ee18a024c 100644 --- a/apps/client/src/app/pages/register/register-page.component.ts +++ b/apps/client/src/app/pages/register/register-page.component.ts @@ -4,9 +4,8 @@ import { Router } from '@angular/router'; import { DataService } from '@ghostfolio/client/services/data.service'; import { InternetIdentityService } from '@ghostfolio/client/services/internet-identity.service'; import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; -import { InfoItem } from '@ghostfolio/common/interfaces'; +import { InfoItem, LineChartItem } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import { LineChartItem } from '@ghostfolio/ui/line-chart/interfaces/line-chart.interface'; import { Role } from '@prisma/client'; import { format } from 'date-fns'; import { DeviceDetectorService } from 'ngx-device-detector'; diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index f21ebb25f..763bf582f 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -14,11 +14,13 @@ import { UserItem } from '@ghostfolio/api/app/user/interfaces/user-item.interfac import { UpdateUserSettingDto } from '@ghostfolio/api/app/user/update-user-setting.dto'; import { UpdateUserSettingsDto } from '@ghostfolio/api/app/user/update-user-settings.dto'; import { PropertyDto } from '@ghostfolio/api/services/property/property.dto'; +import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { Access, Accounts, AdminData, AdminMarketData, + BenchmarkMarketDataDetails, BenchmarkResponse, Export, Filter, @@ -31,12 +33,13 @@ import { PortfolioPublicDetails, PortfolioReport, PortfolioSummary, + UniqueAsset, User } from '@ghostfolio/common/interfaces'; import { filterGlobalPermissions } from '@ghostfolio/common/permissions'; import { AccountWithValue, DateRange } from '@ghostfolio/common/types'; import { DataSource, Order as OrderModel } from '@prisma/client'; -import { parseISO } from 'date-fns'; +import { format, parseISO } from 'date-fns'; import { cloneDeep, groupBy } from 'lodash'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -181,6 +184,21 @@ export class DataService { return this.http.get('/api/v1/access'); } + public fetchBenchmarkBySymbol({ + dataSource, + startDate, + symbol + }: { + startDate: Date; + } & UniqueAsset): Observable { + return this.http.get( + `/api/v1/benchmark/${dataSource}/${symbol}/${format( + startDate, + DATE_FORMAT + )}` + ); + } + public fetchBenchmarks() { return this.http.get('/api/v1/benchmark'); } diff --git a/libs/common/src/lib/interfaces/benchmark-market-data-details.interface.ts b/libs/common/src/lib/interfaces/benchmark-market-data-details.interface.ts new file mode 100644 index 000000000..10fdeff32 --- /dev/null +++ b/libs/common/src/lib/interfaces/benchmark-market-data-details.interface.ts @@ -0,0 +1,5 @@ +import { LineChartItem } from './line-chart-item.interface'; + +export interface BenchmarkMarketDataDetails { + marketData: LineChartItem[]; +} diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index fc55c0591..ef93845c5 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -7,6 +7,7 @@ import { AdminMarketData, AdminMarketDataItem } from './admin-market-data.interface'; +import { BenchmarkMarketDataDetails } from './benchmark-market-data-details.interface'; import { Benchmark } from './benchmark.interface'; import { Coupon } from './coupon.interface'; import { EnhancedSymbolProfile } from './enhanced-symbol-profile.interface'; @@ -15,6 +16,7 @@ import { FilterGroup } from './filter-group.interface'; import { Filter } from './filter.interface'; import { HistoricalDataItem } from './historical-data-item.interface'; import { InfoItem } from './info-item.interface'; +import { LineChartItem } from './line-chart-item.interface'; import { PortfolioChart } from './portfolio-chart.interface'; import { PortfolioDetails } from './portfolio-details.interface'; import { PortfolioInvestments } from './portfolio-investments.interface'; @@ -47,6 +49,7 @@ export { AdminMarketDataDetails, AdminMarketDataItem, Benchmark, + BenchmarkMarketDataDetails, BenchmarkResponse, Coupon, EnhancedSymbolProfile, @@ -55,6 +58,7 @@ export { FilterGroup, HistoricalDataItem, InfoItem, + LineChartItem, OAuthResponse, PortfolioChart, PortfolioDetails, diff --git a/libs/ui/src/lib/line-chart/interfaces/line-chart.interface.ts b/libs/common/src/lib/interfaces/line-chart-item.interface.ts similarity index 100% rename from libs/ui/src/lib/line-chart/interfaces/line-chart.interface.ts rename to libs/common/src/lib/interfaces/line-chart-item.interface.ts 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 4d0ceb218..5c5ac346c 100644 --- a/libs/ui/src/lib/line-chart/line-chart.component.ts +++ b/libs/ui/src/lib/line-chart/line-chart.component.ts @@ -25,6 +25,7 @@ import { getDateFormatString, getTextColor } from '@ghostfolio/common/helper'; +import { LineChartItem } from '@ghostfolio/common/interfaces'; import { Chart, Filler, @@ -36,8 +37,6 @@ import { Tooltip } from 'chart.js'; -import { LineChartItem } from './interfaces/line-chart.interface'; - @Component({ selector: 'gf-line-chart', changeDetection: ChangeDetectionStrategy.OnPush,