Feature/extend tooltip of treemap chart (#4323)

* feat(ui): Extend tooltip

* allocation
* change
* performance

* feat(sb): add story for treemap chart

* Update changelog
This commit is contained in:
Ken Tandrian 2025-02-18 01:21:08 +07:00 committed by GitHub
parent 02a4e27083
commit ec098c8d68
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 417 additions and 6 deletions

View File

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Extended the tooltip in the chart of the holdings tab on the home page by the allocation, change and performance
- Added a new static portfolio analysis rule: _Regional Market Cluster Risk_ (Asia-Pacific Markets)
- Added a new static portfolio analysis rule: _Regional Market Cluster Risk_ (Japan)
- Added support to create custom tags in the holding detail dialog (experimental)

View File

@ -0,0 +1,392 @@
import { CommonModule } from '@angular/common';
import '@angular/localize/init';
import { moduleMetadata } from '@storybook/angular';
import type { Meta, StoryObj } from '@storybook/angular';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { GfTreemapChartComponent } from './treemap-chart.component';
export default {
title: 'Treemap Chart',
component: GfTreemapChartComponent,
decorators: [
moduleMetadata({
imports: [CommonModule, NgxSkeletonLoaderModule]
})
],
argTypes: {
colorScheme: {
control: {
type: 'select'
},
options: ['DARK', 'LIGHT']
},
cursor: {
control: {
type: 'select'
},
options: ['', 'pointer']
}
}
} as Meta<GfTreemapChartComponent>;
type Story = StoryObj<GfTreemapChartComponent>;
export const Default: Story = {
args: {
baseCurrency: 'USD',
colorScheme: 'LIGHT',
cursor: undefined,
dateRange: 'mtd',
holdings: [
{
allocationInPercentage: 0.042990776363386086,
assetClass: 'EQUITY',
assetSubClass: 'STOCK',
countries: [],
currency: 'USD',
dataSource: 'YAHOO',
dateOfFirstActivity: new Date('2021-12-01T00:00:00.000Z'),
dividend: 0,
grossPerformance: 3856,
grossPerformancePercent: 0.46047289228564603,
grossPerformancePercentWithCurrencyEffect: 0.46047289228564603,
grossPerformanceWithCurrencyEffect: 3856,
holdings: [],
investment: 8374,
marketPrice: 244.6,
name: 'Apple Inc',
netPerformance: 3855,
netPerformancePercent: 0.460353475041796,
netPerformancePercentWithCurrencyEffect: 0.036440677966101696,
netPerformanceWithCurrencyEffect: 430,
quantity: 50,
sectors: [],
symbol: 'AAPL',
tags: [],
transactionCount: 1,
url: 'https://www.apple.com',
valueInBaseCurrency: 12230
},
{
allocationInPercentage: 0.02377401948293552,
assetClass: 'EQUITY',
assetSubClass: 'STOCK',
countries: [],
currency: 'EUR',
dataSource: 'YAHOO',
dateOfFirstActivity: new Date('2021-04-23T00:00:00.000Z'),
dividend: 192,
grossPerformance: 2226.700251889169,
grossPerformancePercent: 0.49083842309827874,
grossPerformancePercentWithCurrencyEffect: 0.29306136948826367,
grossPerformanceWithCurrencyEffect: 1532.8272791336772,
holdings: [],
investment: 4536.523929471033,
marketPrice: 322.2,
name: 'Allianz SE',
netPerformance: 2222.2921914357685,
netPerformancePercent: 0.48986674069961134,
netPerformancePercentWithCurrencyEffect: 0.034489367670592026,
netPerformanceWithCurrencyEffect: 225.48257403052068,
quantity: 20,
sectors: [],
symbol: 'ALV.DE',
tags: [],
transactionCount: 2,
url: 'https://www.allianz.com',
valueInBaseCurrency: 6763.224181360202
},
{
allocationInPercentage: 0.08038536990007467,
assetClass: 'EQUITY',
assetSubClass: 'STOCK',
countries: [],
currency: 'USD',
dataSource: 'YAHOO',
dateOfFirstActivity: new Date('2018-10-01T00:00:00.000Z'),
dividend: 0,
grossPerformance: 12758.05,
grossPerformancePercent: 1.2619300787837724,
grossPerformancePercentWithCurrencyEffect: 1.2619300787837724,
grossPerformanceWithCurrencyEffect: 12758.05,
holdings: [],
investment: 10109.95,
marketPrice: 228.68,
name: 'Amazon.com, Inc.',
netPerformance: 12677.26,
netPerformancePercent: 1.253938941339967,
netPerformancePercentWithCurrencyEffect: -0.037866008722316276,
netPerformanceWithCurrencyEffect: -899.99926757812,
quantity: 100,
sectors: [],
symbol: 'AMZN',
tags: [],
transactionCount: 1,
url: 'https://www.aboutamazon.com',
valueInBaseCurrency: 22868
},
{
allocationInPercentage: 0.19216416482928922,
assetClass: 'LIQUIDITY',
assetSubClass: 'CRYPTOCURRENCY',
countries: [],
currency: 'USD',
dataSource: 'COINGECKO',
dateOfFirstActivity: new Date('2017-08-16T00:00:00.000Z'),
dividend: 0,
grossPerformance: 52666.7898248,
grossPerformancePercent: 26.333394912400003,
grossPerformancePercentWithCurrencyEffect: 26.333394912400003,
grossPerformanceWithCurrencyEffect: 52666.7898248,
holdings: [],
investment: 1999.9999999999998,
marketPrice: 97364,
name: 'Bitcoin',
netPerformance: 52636.8898248,
netPerformancePercent: 26.3184449124,
netPerformancePercentWithCurrencyEffect: -0.04760906442310894,
netPerformanceWithCurrencyEffect: -2732.737808972287,
quantity: 0.5614682,
sectors: [],
symbol: 'bitcoin',
tags: [],
transactionCount: 1,
url: null,
valueInBaseCurrency: 54666.7898248
},
{
allocationInPercentage: 0.007378652850073097,
assetClass: 'FIXED_INCOME',
assetSubClass: 'BOND',
countries: [],
currency: 'EUR',
dataSource: 'MANUAL',
dateOfFirstActivity: new Date('2021-02-01T00:00:00.000Z'),
dividend: 11.45,
grossPerformance: 0,
grossPerformancePercent: 0,
grossPerformancePercentWithCurrencyEffect: -0.1247202380342517,
grossPerformanceWithCurrencyEffect: -258.2576430160448,
holdings: [],
investment: 2099.0764063811926,
marketPrice: 1,
name: 'Bondora Go & Grow',
netPerformance: 0,
netPerformancePercent: 0,
netPerformancePercentWithCurrencyEffect: 0.009445843828715519,
netPerformanceWithCurrencyEffect: 19.6420125363184,
quantity: 2000,
sectors: [],
symbol: 'BONDORA_GO_AND_GROW',
tags: [],
transactionCount: 5,
url: null,
valueInBaseCurrency: 2099.0764063811926
},
{
allocationInPercentage: 0.07787531695543741,
assetClass: 'EQUITY',
assetSubClass: 'ETF',
countries: [],
currency: 'CHF',
dataSource: 'MANUAL',
dateOfFirstActivity: new Date('2021-04-01T00:00:00.000Z'),
dividend: 0,
grossPerformance: 4550.843985045582,
grossPerformancePercent: 0.3631417324494093,
grossPerformancePercentWithCurrencyEffect: 0.42037247857285137,
grossPerformanceWithCurrencyEffect: 5107.057936556927,
holdings: [],
investment: 17603.097090932337,
marketPrice: 188.22,
name: 'frankly Extreme 95 Index',
netPerformance: 4550.843985045582,
netPerformancePercent: 0.3631417324494093,
netPerformancePercentWithCurrencyEffect: 0.026190604904358043,
netPerformanceWithCurrencyEffect: 565.4165171873152,
quantity: 105.87328656807,
sectors: [],
symbol: 'FRANKLY95P',
tags: [],
transactionCount: 6,
url: 'https://www.frankly.ch',
valueInBaseCurrency: 22153.941075977917
},
{
allocationInPercentage: 0.04307127421937313,
assetClass: 'EQUITY',
assetSubClass: 'STOCK',
countries: [],
currency: 'USD',
dataSource: 'YAHOO',
dateOfFirstActivity: new Date('2023-01-03T00:00:00.000Z'),
dividend: 0,
grossPerformance: 5065.5,
grossPerformancePercent: 0.7047750229568411,
grossPerformancePercentWithCurrencyEffect: 0.7047750229568411,
grossPerformanceWithCurrencyEffect: 5065.5,
holdings: [],
investment: 7187.4,
marketPrice: 408.43,
name: 'Microsoft Corporation',
netPerformance: 5065.5,
netPerformancePercent: 0.7047750229568411,
netPerformancePercentWithCurrencyEffect: -0.015973588391056275,
netPerformanceWithCurrencyEffect: -198.899926757814,
quantity: 30,
sectors: [],
symbol: 'MSFT',
tags: [],
transactionCount: 1,
url: 'https://www.microsoft.com',
valueInBaseCurrency: 12252.9
},
{
allocationInPercentage: 0.18762679306394897,
assetClass: 'EQUITY',
assetSubClass: 'STOCK',
countries: [],
currency: 'USD',
dataSource: 'YAHOO',
dateOfFirstActivity: new Date('2017-01-03T00:00:00.000Z'),
dividend: 0,
grossPerformance: 51227.500000005,
grossPerformancePercent: 23.843379101756675,
grossPerformancePercentWithCurrencyEffect: 23.843379101756675,
grossPerformanceWithCurrencyEffect: 51227.500000005,
holdings: [],
investment: 2148.499999995,
marketPrice: 355.84,
name: 'Tesla, Inc.',
netPerformance: 51197.500000005,
netPerformancePercent: 23.829415871596066,
netPerformancePercentWithCurrencyEffect: -0.12051410125545206,
netPerformanceWithCurrencyEffect: -7314.00091552734,
quantity: 150,
sectors: [],
symbol: 'TSLA',
tags: [],
transactionCount: 1,
url: 'https://www.tesla.com',
valueInBaseCurrency: 53376
},
{
allocationInPercentage: 0.053051250766657634,
assetClass: 'EQUITY',
assetSubClass: 'ETF',
countries: [],
currency: 'USD',
dataSource: 'YAHOO',
dateOfFirstActivity: new Date('2019-03-01T00:00:00.000Z'),
dividend: 0,
grossPerformance: 6845.8,
grossPerformancePercent: 1.0164758094605268,
grossPerformancePercentWithCurrencyEffect: 1.0164758094605268,
grossPerformanceWithCurrencyEffect: 6845.8,
holdings: [],
investment: 8246.2,
marketPrice: 301.84,
name: 'Vanguard Total Stock Market Index Fund ETF Shares',
netPerformance: 6746.3,
netPerformancePercent: 1.0017018833976383,
netPerformancePercentWithCurrencyEffect: 0.01085061564051406,
netPerformanceWithCurrencyEffect: 161.99969482422,
quantity: 50,
sectors: [],
symbol: 'VTI',
tags: [],
transactionCount: 5,
url: 'https://www.vanguard.com',
valueInBaseCurrency: 15092
},
{
allocationInPercentage: 0.0836576192450555,
assetClass: 'EQUITY',
assetSubClass: 'ETF',
countries: [],
currency: 'CHF',
dataSource: 'YAHOO',
dateOfFirstActivity: new Date('2018-03-01T00:00:00.000Z'),
dividend: 0,
grossPerformance: 6462.42356864925,
grossPerformancePercent: 0.5463044783973836,
grossPerformancePercentWithCurrencyEffect: 0.6282343505275325,
grossPerformanceWithCurrencyEffect: 7121.935580698947,
holdings: [],
investment: 17336.464702612564,
marketPrice: 129.74,
name: 'Vanguard FTSE All-World UCITS ETF',
netPerformance: 6373.040578098944,
netPerformancePercent: 0.5387484388540966,
netPerformancePercentWithCurrencyEffect: 0.008409682389650015,
netPerformanceWithCurrencyEffect: 198.47200506226807,
quantity: 165,
sectors: [],
symbol: 'VWRL.SW',
tags: [],
transactionCount: 5,
url: 'https://www.vanguard.com',
valueInBaseCurrency: 23798.888271261814
},
{
allocationInPercentage: 0.03265192235898284,
assetClass: 'EQUITY',
assetSubClass: 'ETF',
countries: [],
currency: 'EUR',
dataSource: 'YAHOO',
dateOfFirstActivity: new Date('2021-08-19T00:00:00.000Z'),
dividend: 0,
grossPerformance: 3112.7991183879094,
grossPerformancePercent: 0.5040147846036197,
grossPerformancePercentWithCurrencyEffect: 0.3516875105542396,
grossPerformanceWithCurrencyEffect: 2416.799201046856,
holdings: [],
investment: 6176.007556675063,
marketPrice: 118.005,
name: 'Xtrackers MSCI World UCITS ETF 1C',
netPerformance: 3081.4179261125105,
netPerformancePercent: 0.4989336392216841,
netPerformancePercentWithCurrencyEffect: 0.006460676966633529,
netPerformanceWithCurrencyEffect: 59.626750161726044,
quantity: 75,
sectors: [],
symbol: 'XDWD.DE',
tags: [],
transactionCount: 1,
url: null,
valueInBaseCurrency: 9288.806675062973
},
{
allocationInPercentage: 0.17537283996478595,
assetClass: 'LIQUIDITY',
assetSubClass: 'CASH',
countries: [],
currency: 'USD',
dataSource: 'MANUAL',
dateOfFirstActivity: new Date('2021-04-01T00:00:00.000Z'),
dividend: 0,
grossPerformance: 0,
grossPerformancePercent: 0,
grossPerformancePercentWithCurrencyEffect: 0,
grossPerformanceWithCurrencyEffect: 0,
holdings: [],
investment: 49890,
marketPrice: 0,
name: 'USD',
netPerformance: 0,
netPerformancePercent: 0,
netPerformancePercentWithCurrencyEffect: 0,
netPerformanceWithCurrencyEffect: 0,
quantity: 0,
sectors: [],
symbol: 'USD',
tags: [],
transactionCount: 0,
valueInBaseCurrency: 49890
}
],
locale: 'en-US'
}
};

View File

@ -342,24 +342,42 @@ export class GfTreemapChartComponent
}),
callbacks: {
label: (context) => {
const allocationInPercentage = `${((context.raw._data.allocationInPercentage as number) * 100).toFixed(2)}%`;
const name = context.raw._data.name;
const sign =
context.raw._data.netPerformancePercentWithCurrencyEffect > 0
? '+'
: '';
const symbol = context.raw._data.symbol;
const netPerformanceInPercentageWithSign = `${sign}${(context.raw._data.netPerformancePercentWithCurrencyEffect * 100).toFixed(2)}%`;
if (context.raw._data.valueInBaseCurrency !== null) {
const value = context.raw._data.valueInBaseCurrency as number;
return [
`${name ?? symbol}`,
`${name ?? symbol} (${allocationInPercentage})`,
`${value.toLocaleString(this.locale, {
maximumFractionDigits: 2,
minimumFractionDigits: 2
})} ${this.baseCurrency}`
})} ${this.baseCurrency}`,
'',
$localize`Change` + ' (' + $localize`Performance` + ')',
`${sign}${context.raw._data.netPerformanceWithCurrencyEffect.toLocaleString(
this.locale,
{
maximumFractionDigits: 2,
minimumFractionDigits: 2
}
)} ${this.baseCurrency} (${netPerformanceInPercentageWithSign})`
];
} else {
const percentage =
(context.raw._data.allocationInPercentage as number) * 100;
return [`${name ?? symbol}`, `${percentage.toFixed(2)}%`];
return [
`${name ?? symbol} (${allocationInPercentage})`,
'',
$localize`Performance`,
netPerformanceInPercentageWithSign
];
}
},
title: () => {