Browse Source

Fix alignment of average price in chart of holding detail dialog

pull/7937/head
GabeSilvaDev 6 days ago
parent
commit
73f576a997
  1. 8
      apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts
  2. 61
      libs/common/src/lib/helper.spec.ts
  3. 22
      libs/common/src/lib/helper.ts

8
apps/client/src/app/components/holding-detail-dialog/holding-detail-dialog.component.ts

@ -9,6 +9,7 @@ import {
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { CreateOrderDto } from '@ghostfolio/common/dtos'; import { CreateOrderDto } from '@ghostfolio/common/dtos';
import { import {
alignLineChartItemsToDates,
DATE_FORMAT, DATE_FORMAT,
downloadAsFile, downloadAsFile,
getCountryName getCountryName
@ -725,6 +726,13 @@ export class GfHoldingDetailDialogComponent implements OnInit {
} }
); );
this.benchmarkDataItems = alignLineChartItemsToDates({
dates: this.historicalDataItems.map(({ date }) => {
return date;
}),
items: this.benchmarkDataItems
});
this.changeDetectorRef.markForCheck(); this.changeDetectorRef.markForCheck();
}); });
} }

61
libs/common/src/lib/helper.spec.ts

@ -3,6 +3,7 @@ import {
TAG_ID_EXCLUDE_FROM_ANALYSIS TAG_ID_EXCLUDE_FROM_ANALYSIS
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { import {
alignLineChartItemsToDates,
canApplyFiltersToAccess, canApplyFiltersToAccess,
extractNumberFromString, extractNumberFromString,
getCountryCodeFromCurrency, getCountryCodeFromCurrency,
@ -23,6 +24,66 @@ import {
import { UserSettings } from '@ghostfolio/common/interfaces'; import { UserSettings } from '@ghostfolio/common/interfaces';
describe('Helper', () => { describe('Helper', () => {
describe('Align line chart items to dates', () => {
it('Dates before the first item', () => {
expect(
alignLineChartItemsToDates({
dates: ['2025-01-02', '2025-01-03'],
items: [{ date: '2026-01-09', value: 100 }]
})
).toEqual([
{ date: '2025-01-02', value: null },
{ date: '2025-01-03', value: null }
]);
});
it('Dates on and after the items', () => {
expect(
alignLineChartItemsToDates({
dates: [
'2026-01-08',
'2026-01-09',
'2026-01-10',
'2026-01-12',
'2026-01-13'
],
items: [
{ date: '2026-01-09', value: 100 },
{ date: '2026-01-12', value: 110 }
]
})
).toEqual([
{ date: '2026-01-08', value: null },
{ date: '2026-01-09', value: 100 },
{ date: '2026-01-10', value: 100 },
{ date: '2026-01-12', value: 110 },
{ date: '2026-01-13', value: 110 }
]);
});
it('Null values', () => {
expect(
alignLineChartItemsToDates({
dates: ['2026-01-09', '2026-01-10', '2026-01-11'],
items: [
{ date: '2026-01-09', value: 100 },
{ date: '2026-01-10', value: null }
]
})
).toEqual([
{ date: '2026-01-09', value: 100 },
{ date: '2026-01-10', value: null },
{ date: '2026-01-11', value: null }
]);
});
it('No items', () => {
expect(
alignLineChartItemsToDates({ dates: ['2026-01-09'], items: [] })
).toEqual([{ date: '2026-01-09', value: null }]);
});
});
describe('Can apply filters to access', () => { describe('Can apply filters to access', () => {
it('An access of the model context protocol', () => { it('An access of the model context protocol', () => {
expect(canApplyFiltersToAccess({ type: 'MCP' })).toEqual(false); expect(canApplyFiltersToAccess({ type: 'MCP' })).toEqual(false);

22
libs/common/src/lib/helper.ts

@ -57,6 +57,7 @@ import {
AssetProfileIdentifier, AssetProfileIdentifier,
AssetProfileItem, AssetProfileItem,
Benchmark, Benchmark,
NullableLineChartItem,
PortfolioPosition, PortfolioPosition,
UserSettings UserSettings
} from './interfaces'; } from './interfaces';
@ -91,6 +92,27 @@ const USER_SETTINGS_KEYS_OF_AUTHENTICATED_USER: (keyof UserSettings)[] = [
const VALID_COUNTRY_CODES = new Set([...Object.keys(countries), 'EU']); const VALID_COUNTRY_CODES = new Set([...Object.keys(countries), 'EU']);
export function alignLineChartItemsToDates({
dates,
items
}: {
dates: string[];
items: NullableLineChartItem[];
}): NullableLineChartItem[] {
let index = -1;
return dates.map((date) => {
while (
index + 1 < items.length &&
!isAfter(parseISO(items[index + 1].date), parseISO(date))
) {
index++;
}
return { date, value: items[index]?.value ?? null };
});
}
export function applyAssetProfileOverrides<T extends Partial<SymbolProfile>>( export function applyAssetProfileOverrides<T extends Partial<SymbolProfile>>(
assetProfile: T, assetProfile: T,
assetProfileOverrides: AssetProfileOverrides | null assetProfileOverrides: AssetProfileOverrides | null

Loading…
Cancel
Save