From 9a59081fd46772234beff2789116a442a564b315 Mon Sep 17 00:00:00 2001 From: Shivam Paw Date: Thu, 18 Jan 2024 15:01:40 +0000 Subject: [PATCH] Add derived data series to statements of assets chart Uses DerivedDataSeries to hold a reference to the underlying data series (base) and the aspect to be shown (ClientDataSeries). Issue: #3754 Issue: #4235 Issue: #4396 Co-authored-by: Shivam Paw Co-authored-by: mierin12 <160436107+mierin12@users.noreply.github.com> Co-authored-by: Andreas Buchen --- .../name/abuchen/portfolio/ui/Messages.java | 1 + .../ui/dialogs/about.contributors.txt | 3 +- .../abuchen/portfolio/ui/messages.properties | 2 + .../portfolio/ui/messages_cs.properties | 2 + .../portfolio/ui/messages_da.properties | 2 + .../portfolio/ui/messages_de.properties | 2 + .../portfolio/ui/messages_es.properties | 2 + .../portfolio/ui/messages_fr.properties | 2 + .../portfolio/ui/messages_it.properties | 2 + .../portfolio/ui/messages_nl.properties | 2 + .../portfolio/ui/messages_pl.properties | 2 + .../portfolio/ui/messages_pt.properties | 2 + .../portfolio/ui/messages_pt_BR.properties | 2 + .../portfolio/ui/messages_ru.properties | 2 + .../portfolio/ui/messages_sk.properties | 2 + .../portfolio/ui/messages_zh.properties | 2 + .../portfolio/ui/messages_zh_TW.properties | 2 + .../BasicDataSeriesConfigurator.java | 29 ++++++++ .../ui/views/dataseries/DataSeries.java | 68 +++++++++++++++---- .../ui/views/dataseries/DataSeriesCache.java | 6 ++ .../dataseries/DataSeriesChartLegend.java | 3 + .../dataseries/DataSeriesSelectionDialog.java | 62 ++++++++++++++++- .../dataseries/DataSeriesSerializer.java | 3 + .../ui/views/dataseries/DataSeriesSet.java | 55 +++++++++++++++ .../views/dataseries/DerivedDataSeries.java | 32 +++++++++ .../StatementOfAssetsSeriesBuilder.java | 5 +- 26 files changed, 279 insertions(+), 18 deletions(-) create mode 100644 name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DerivedDataSeries.java diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java index a9362a8a8f..76024de453 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/Messages.java @@ -65,6 +65,7 @@ public class Messages extends NLS public static String ChartSeriesBenchmarkSuffix; public static String ChartSeriesCopySeriesFromOtherChart; public static String ChartSeriesPickerAddBenchmark; + public static String ChartSeriesPickerAddDerivedData; public static String ChartSeriesPickerAddItem; public static String ChartSeriesPickerColor; public static String ChartSeriesPickerDialogMsg; diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/about.contributors.txt b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/about.contributors.txt index 2a1baf64c5..c7c8dc66bd 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/about.contributors.txt +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/dialogs/about.contributors.txt @@ -160,4 +160,5 @@ cthiel myrdd mosswald82 verglor -liuhaoXD \ No newline at end of file +liuhaoXD +shivampaw \ No newline at end of file diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties index b5c596a8b1..1a388e6af8 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages.properties @@ -180,6 +180,8 @@ ChartSeriesCopySeriesFromOtherChart = Copy from ChartSeriesPickerAddBenchmark = Add benchmark... +ChartSeriesPickerAddDerivedData = Add derived data series ... + ChartSeriesPickerAddItem = Add data series... ChartSeriesPickerColor = Color... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_cs.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_cs.properties index 8959fee45e..dffe54391c 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_cs.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_cs.properties @@ -176,6 +176,8 @@ ChartSeriesCopySeriesFromOtherChart = Kop\u00EDrovat z ChartSeriesPickerAddBenchmark = P\u0159idat benchmark... +ChartSeriesPickerAddDerivedData = P\u0159id\u00E1n\u00ED odvozen\u00FDch datov\u00FDch \u0159ad ... + ChartSeriesPickerAddItem = P\u0159idat datovou \u0159adu... ChartSeriesPickerColor = Barva... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_da.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_da.properties index cf40076f4a..81e824ec15 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_da.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_da.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = Kopier fra ChartSeriesPickerAddBenchmark = Tilf\u00F8j ydeevne... +ChartSeriesPickerAddDerivedData = Tilf\u00F8j afledte dataserier ... + ChartSeriesPickerAddItem = Tilf\u00F8j dataserier... ChartSeriesPickerColor = Farve... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties index 64cbf7f24d..aa8f82b4fd 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_de.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = \u00DCbernehmen aus ChartSeriesPickerAddBenchmark = Benchmark hinzuf\u00FCgen... +ChartSeriesPickerAddDerivedData = Abgeleitete Datenreihen hinzuf\u00FCgen ... + ChartSeriesPickerAddItem = Datenreihe hinzuf\u00FCgen... ChartSeriesPickerColor = Farbe... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_es.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_es.properties index ecc01286b4..8ed9603b50 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_es.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_es.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = Incorporar las series de ChartSeriesPickerAddBenchmark = A\u00F1adir series de referencia... +ChartSeriesPickerAddDerivedData = A\u00F1adir series de datos derivados ... + ChartSeriesPickerAddItem = A\u00F1adir series de datos... ChartSeriesPickerColor = Color... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_fr.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_fr.properties index a7b9a7518d..707b3c6ca9 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_fr.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_fr.properties @@ -174,6 +174,8 @@ ChartSeriesCopySeriesFromOtherChart = Copier de ChartSeriesPickerAddBenchmark = Ajouter une r\u00E9f\u00E9rence/benchmark... +ChartSeriesPickerAddDerivedData = Ajouter des s\u00E9ries de donn\u00E9es d\u00E9riv\u00E9es ... + ChartSeriesPickerAddItem = Ajouter des s\u00E9ries de donn\u00E9es... ChartSeriesPickerColor = Couleur... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_it.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_it.properties index d7375d2b41..b2da91f1dc 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_it.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_it.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = Copia da ChartSeriesPickerAddBenchmark = Aggiungi un benchmark +ChartSeriesPickerAddDerivedData = Aggiungere serie di dati derivati ... + ChartSeriesPickerAddItem = Aggiungi serie dati... ChartSeriesPickerColor = Colore... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_nl.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_nl.properties index 53d84faaeb..8431fa2a01 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_nl.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_nl.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = Kopi\u00EBren van ChartSeriesPickerAddBenchmark = Benchmark toevoegen... +ChartSeriesPickerAddDerivedData = Afgeleide gegevensreeksen toevoegen ... + ChartSeriesPickerAddItem = Gegevensreeks toevoegen... ChartSeriesPickerColor = Kleur... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pl.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pl.properties index 697c5b7e7d..383c83053f 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pl.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pl.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = Kopiuj z ChartSeriesPickerAddBenchmark = Dodaj benchmark\u2026 +ChartSeriesPickerAddDerivedData = Dodaj pochodne serie danych ... + ChartSeriesPickerAddItem = Dodaj serie danych ... ChartSeriesPickerColor = Kolor... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt.properties index f1bd6c7717..84cbcb6969 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = Copiar de ChartSeriesPickerAddBenchmark = Adicionar refer\u00EAncia... +ChartSeriesPickerAddDerivedData = Adicionar s\u00E9ries de dados derivados ... + ChartSeriesPickerAddItem = Adicionar s\u00E9rie de dados... ChartSeriesPickerColor = Cor... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt_BR.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt_BR.properties index fd6f841209..7c071c24de 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt_BR.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_pt_BR.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = Copiar de ChartSeriesPickerAddBenchmark = Adicionar Benchmark... +ChartSeriesPickerAddDerivedData = Adicionar s\u00E9ries de dados derivados ... + ChartSeriesPickerAddItem = Adicionar s\u00E9rie de dados... ChartSeriesPickerColor = Cor... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_ru.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_ru.properties index 7b44d67e0a..9b1a20f028 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_ru.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_ru.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = \u041A\u043E\u043F\u0438\u0440\u043E\u0432 ChartSeriesPickerAddBenchmark = \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0431\u0435\u043D\u0447\u043C\u0430\u0440\u043A... +ChartSeriesPickerAddDerivedData = \u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u043D\u044B\u0435 \u0441\u0435\u0440\u0438\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 ... + ChartSeriesPickerAddItem = \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0441\u0435\u0440\u0438\u044E \u0434\u0430\u043D\u043D\u044B\u0445... ChartSeriesPickerColor = \u0426\u0432\u0435\u0442... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_sk.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_sk.properties index 52d400e49e..0deec6712a 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_sk.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_sk.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = Kop\u00EDrova\u0165 z ChartSeriesPickerAddBenchmark = Prida\u0165 Benchmark... +ChartSeriesPickerAddDerivedData = Pridanie odvoden\u00FDch radov \u00FAdajov ... + ChartSeriesPickerAddItem = Prida\u0165 d\u00E1tov\u00FA radu... ChartSeriesPickerColor = Farba... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_zh.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_zh.properties index 470a972e2c..0a8388ec7c 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_zh.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_zh.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = \u590D\u5236\u81EA ChartSeriesPickerAddBenchmark = \u6DFB\u52A0\u57FA\u51C6... +ChartSeriesPickerAddDerivedData = \u6DFB\u52A0\u6D3E\u751F\u6570\u636E\u7CFB\u5217 ... + ChartSeriesPickerAddItem = \u6DFB\u52A0\u6570\u636E\u7CFB\u5217... ChartSeriesPickerColor = \u989C\u8272... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_zh_TW.properties b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_zh_TW.properties index 6ef2862d41..36227657a8 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_zh_TW.properties +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/messages_zh_TW.properties @@ -173,6 +173,8 @@ ChartSeriesCopySeriesFromOtherChart = \u8907\u88FD\u81EA ChartSeriesPickerAddBenchmark = \u65B0\u589E\u6307\u6A19... +ChartSeriesPickerAddDerivedData = \u65B0\u589E\u884D\u751F\u8CC7\u6599\u7CFB\u5217 ... + ChartSeriesPickerAddItem = \u65B0\u589E\u6578\u5217... ChartSeriesPickerColor = \u984F\u8272... diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/BasicDataSeriesConfigurator.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/BasicDataSeriesConfigurator.java index 7b2ba6e7d0..eea0943adf 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/BasicDataSeriesConfigurator.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/BasicDataSeriesConfigurator.java @@ -100,6 +100,8 @@ public void configMenuAboutToShow(IMenuManager manager) if (dataSeriesSet.getUseCase() != DataSeries.UseCase.STATEMENT_OF_ASSETS) manager.add(new SimpleAction(Messages.ChartSeriesPickerAddBenchmark, a -> doAddSeries(true))); + else + manager.add(new SimpleAction(Messages.ChartSeriesPickerAddDerivedData, a -> doAddDerivedSeries())); addCopyFromOtherChartsMenu(manager); } @@ -136,6 +138,33 @@ private void doAddSeries(boolean showOnlyBenchmark) fireUpdate(); } + private void doAddDerivedSeries() + { + List list = new ArrayList<>(dataSeriesSet.getAvailableDerivedSeries()); + + // remove already selected items + for (DataSeries s : selectedSeries) + list.remove(s); + + DataSeriesSelectionDialog dialog = new DataSeriesSelectionDialog(Display.getDefault().getActiveShell(), client); + dialog.setElementsDerivedData(list); + dialog.setExpandTree(false); + + if (dialog.open() != DataSeriesSelectionDialog.OK) + return; + + List result = dialog.getResult(); + if (result.isEmpty()) + return; + + result.forEach(series -> { + series.setVisible(true); + selectedSeries.add(series); + }); + + fireUpdate(); + } + private void addCopyFromOtherChartsMenu(IMenuManager manager) { String[] charts = new String[] { // diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeries.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeries.java index 6e1b3e44c8..7153192a81 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeries.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeries.java @@ -35,9 +35,45 @@ public enum UseCase */ public enum ClientDataSeries { - TOTALS, INVESTED_CAPITAL, ABSOLUTE_INVESTED_CAPITAL, TRANSFERALS, TRANSFERALS_ACCUMULATED, TAXES, TAXES_ACCUMULATED, ABSOLUTE_DELTA, ABSOLUTE_DELTA_ALL_RECORDS, // - DIVIDENDS, DIVIDENDS_ACCUMULATED, INTEREST, INTEREST_ACCUMULATED, DELTA_PERCENTAGE, INTEREST_CHARGE, INTEREST_CHARGE_ACCUMULATED, // - EARNINGS, EARNINGS_ACCUMULATED, FEES, FEES_ACCUMULATED; + TOTALS(Messages.LabelTotalSum), // + TRANSFERALS(Messages.LabelTransferals), // + TRANSFERALS_ACCUMULATED(Messages.LabelAccumulatedTransferals), // + INVESTED_CAPITAL(Messages.LabelInvestedCapital), // + ABSOLUTE_INVESTED_CAPITAL(Messages.LabelAbsoluteInvestedCapital), // + ABSOLUTE_DELTA(Messages.LabelDelta), // + ABSOLUTE_DELTA_ALL_RECORDS(Messages.LabelAbsoluteDelta), // + DIVIDENDS(Messages.LabelDividends), // + DIVIDENDS_ACCUMULATED(Messages.LabelAccumulatedDividends), // + INTEREST(Messages.LabelInterest), // + INTEREST_ACCUMULATED(Messages.LabelAccumulatedInterest), // + INTEREST_CHARGE(Messages.LabelInterestCharge), // + INTEREST_CHARGE_ACCUMULATED(Messages.LabelAccumulatedInterestCharge), // + EARNINGS(Messages.LabelEarnings), // + EARNINGS_ACCUMULATED(Messages.LabelAccumulatedEarnings), // + FEES(Messages.LabelFees), // + FEES_ACCUMULATED(Messages.LabelFeesAccumulated), // + TAXES(Messages.ColumnTaxes), // + TAXES_ACCUMULATED(Messages.LabelAccumulatedTaxes), // + + DELTA_PERCENTAGE(Messages.LabelAggregationDaily); + + private String label; + + private ClientDataSeries(String label) + { + this.label = label; + } + + public String getLabel() + { + return label; + } + + @Override + public String toString() + { + return label; + } } /** @@ -52,6 +88,7 @@ public enum Type ACCOUNT("Account", i -> ((Account) i).getUUID()), //$NON-NLS-1$ ACCOUNT_PRETAX("Account-PreTax", i -> ((Account) i).getUUID()), //$NON-NLS-1$ PORTFOLIO("Portfolio", i -> ((Portfolio) i).getUUID()), //$NON-NLS-1$ + DERIVED_DATA_SERIES("Derived-", i -> ((DerivedDataSeries) i).getUUID()), //$NON-NLS-1$ PORTFOLIO_PRETAX("Portfolio-PreTax", i -> ((Portfolio) i).getUUID()), //$NON-NLS-1$ PORTFOLIO_PLUS_ACCOUNT("[+]Portfolio", i -> ((Portfolio) i).getUUID()), //$NON-NLS-1$ PORTFOLIO_PLUS_ACCOUNT_PRETAX("[+]Portfolio-PreTax", i -> ((Portfolio) i).getUUID()), //$NON-NLS-1$ @@ -146,6 +183,15 @@ public String getSearchLabel() buf.append(" (").append(parent.getPathName(false)).append(")"); //$NON-NLS-1$ //$NON-NLS-2$ } + if (instance instanceof DerivedDataSeries derived + && derived.getBaseDataSeries().getInstance() instanceof Classification classification) + { + Classification parent = classification.getParent(); + + if (parent.getParent() != null) + buf.append(" (").append(parent.getPathName(false)).append(")"); //$NON-NLS-1$ //$NON-NLS-2$ + } + if (isBenchmark()) buf.append(" ").append(Messages.ChartSeriesBenchmarkSuffix); //$NON-NLS-1$ @@ -214,23 +260,17 @@ public void setLineWidth(int lineWidth) public Image getImage() { - switch (type) + switch (instance instanceof DerivedDataSeries derived ? derived.getBaseDataSeries().getType() : type) { - case SECURITY: - case SECURITY_BENCHMARK: + case SECURITY, SECURITY_BENCHMARK: return Images.SECURITY.image(); - case ACCOUNT: - case ACCOUNT_PRETAX: + case ACCOUNT, ACCOUNT_PRETAX: return Images.ACCOUNT.image(); - case PORTFOLIO: - case PORTFOLIO_PRETAX: - case PORTFOLIO_PLUS_ACCOUNT: - case PORTFOLIO_PLUS_ACCOUNT_PRETAX: + case PORTFOLIO, PORTFOLIO_PRETAX, PORTFOLIO_PLUS_ACCOUNT, PORTFOLIO_PLUS_ACCOUNT_PRETAX: return Images.PORTFOLIO.image(); case CLASSIFICATION: return Images.CATEGORY.image(); - case CLIENT_FILTER: - case CLIENT_FILTER_PRETAX: + case CLIENT_FILTER, CLIENT_FILTER_PRETAX: return Images.FILTER_OFF.image(); default: return null; diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesCache.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesCache.java index 259efedd7f..da82510651 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesCache.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesCache.java @@ -135,6 +135,12 @@ private PerformanceIndex calculate(DataSeries series, Interval reportingPeriod) new WithoutTaxesFilter().filter(pretax.getFilter().filter(client)), converter, reportingPeriod, warnings); + case DERIVED_DATA_SERIES: + // redirect to the #lookup method to use the cached data, if + // available + var derivedDataSeries = (DerivedDataSeries) series.getInstance(); + return lookup(derivedDataSeries.getBaseDataSeries(), reportingPeriod); + default: throw new IllegalArgumentException(series.getType().name()); } diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesChartLegend.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesChartLegend.java index c4a4445474..a1180d54f2 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesChartLegend.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesChartLegend.java @@ -146,6 +146,9 @@ private PaintItem(Composite parent, DataSeries series) setToolTipText(TextUtil.wordwrap(security.toInfoString())); else if (series.getInstance() instanceof Classification classification) setToolTipText(classification.getPathName(true)); + else if (series.getInstance() instanceof DerivedDataSeries derived + && derived.getBaseDataSeries().getInstance() instanceof Classification classification) + setToolTipText(derived.getAspect().getLabel() + ": " + classification.getPathName(true)); //$NON-NLS-1$ else setToolTipText(series.getLabel()); } diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSelectionDialog.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSelectionDialog.java index 880d577e5e..7b260cf862 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSelectionDialog.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSelectionDialog.java @@ -111,6 +111,7 @@ public boolean select(Viewer viewer, Object parentElement, Object element) } } + private boolean isTreeExpanded = true; private boolean isMultiSelection = true; private Node[] elements; @@ -133,6 +134,11 @@ public void setMultiSelection(boolean isMultiSelection) this.isMultiSelection = isMultiSelection; } + public void setExpandTree(boolean isTreeExpanded) + { + this.isTreeExpanded = isTreeExpanded; + } + public void setElements(List elements) { Map type2node = new HashMap<>(); @@ -166,6 +172,50 @@ public void setElements(List elements) this.elements = type2node.values().toArray(new Node[0]); } + public void setElementsDerivedData(List elements) + { + Map type2node = new HashMap<>(); + Map group2node = new HashMap<>(); + + for (DataSeries series : elements) + { + Node child = new Node(series.getSearchLabel()); + child.dataSeries = series; + + DerivedDataSeries derivedDataSeries = (DerivedDataSeries) series.getInstance(); + + String topLevelNodeLabel = derivedDataSeries.getAspect().getLabel(); + Node gdparent = type2node.computeIfAbsent(topLevelNodeLabel, Node::new); + + String secondLevelNodeLabel = map(derivedDataSeries.getBaseDataSeries().getType()); + Node parent = group2node.computeIfAbsent(topLevelNodeLabel + "|" + secondLevelNodeLabel, g -> { //$NON-NLS-1$ + Node n = new Node(secondLevelNodeLabel); + n.parent = gdparent; + gdparent.children.add(n); + return n; + }); + + if (series.getGroup() != null) // for taxonomy + { + Node group = group2node.computeIfAbsent(topLevelNodeLabel + "|" + series.getGroup(), g -> { //$NON-NLS-1$ + Node n = new Node(series.getGroup().toString()); + n.parent = parent; + parent.children.add(n); + return n; + }); + child.parent = group; + group.children.add(child); + } + else + { + child.parent = parent; + parent.children.add(child); + } + } + + this.elements = type2node.values().toArray(new Node[0]); + } + /** * Reduce number of first-level folders to a meaningful set for the * end-user. @@ -266,6 +316,15 @@ public Image getImage(Object element) || node.dataSeries.getType() == DataSeries.Type.SECURITY_BENCHMARK) return LogoManager.instance().getDefaultColumnImage(node.dataSeries.getInstance(), client.getSettings()); + + if (node.dataSeries.getType() == DataSeries.Type.DERIVED_DATA_SERIES + && ((DerivedDataSeries) node.dataSeries.getInstance()).getBaseDataSeries() + .getType() == DataSeries.Type.SECURITY) + return LogoManager.instance() + .getDefaultColumnImage( + ((DerivedDataSeries) node.dataSeries.getInstance()) + .getBaseDataSeries().getInstance(), + client.getSettings()); else return node.dataSeries.getImage(); } @@ -283,7 +342,8 @@ public String getText(Object element) hookListener(); - treeViewer.expandAll(); + if (isTreeExpanded) + treeViewer.expandAll(); return composite; } diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSerializer.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSerializer.java index 62d1855563..b918d55f00 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSerializer.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSerializer.java @@ -38,6 +38,9 @@ private void load(DataSeriesSet set, String config, List series) Map uuid2series = set.getAvailableSeries().stream() .collect(Collectors.toMap(DataSeries::getUUID, s -> s)); + uuid2series.putAll(set.getAvailableDerivedSeries().stream() + .collect(Collectors.toMap(DataSeries::getUUID, s -> s))); + String[] items = config.split(","); //$NON-NLS-1$ for (String item : items) { diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSet.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSet.java index b06eecc80d..07e4cf76aa 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSet.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DataSeriesSet.java @@ -1,6 +1,7 @@ package name.abuchen.portfolio.ui.views.dataseries; import java.util.ArrayList; +import java.util.EnumSet; import java.util.List; import org.eclipse.jface.preference.IPreferenceStore; @@ -26,6 +27,7 @@ public class DataSeriesSet { private DataSeries.UseCase useCase; private final List availableSeries = new ArrayList<>(); + private final List availableDerivedSeries = new ArrayList<>(); public DataSeriesSet(Client client, IPreferenceStore preferences, DataSeries.UseCase useCase) { @@ -48,6 +50,12 @@ public DataSeriesSet(Client client, IPreferenceStore preferences, DataSeries.Use } buildCommonDataSeries(client, preferences, wheel); + + if (useCase == DataSeries.UseCase.STATEMENT_OF_ASSETS) + { + // created the derived data series based + buildStatementOfAssetsDerivedDataSeries(wheel); + } } public DataSeries.UseCase getUseCase() @@ -60,6 +68,11 @@ public List getAvailableSeries() return availableSeries; } + public List getAvailableDerivedSeries() + { + return availableDerivedSeries; + } + /** * Returns DataSeries matching the given UUID. */ @@ -68,6 +81,48 @@ public DataSeries lookup(String uuid) return availableSeries.stream().filter(d -> d.getUUID().equals(uuid)).findAny().orElse(null); } + private void buildStatementOfAssetsDerivedDataSeries(ColorWheel wheel) + { + for (var baseDataSeries : availableSeries) + { + // skip client - the client already defines all derived data series + // (but only for the total client) + if (baseDataSeries.getType() == DataSeries.Type.CLIENT) + continue; + + for (var type : DataSeries.ClientDataSeries.values()) + { + // skip totals - that is already covered by the base data series + // itself + if (type == ClientDataSeries.TOTALS) + continue; + // skip delta percentage - that is applicable only for + // performance data series + if (type == ClientDataSeries.DELTA_PERCENTAGE) + continue; // NOSONAR + + // skip interest and interest charge for portfolios and + // securities - not supported + if ((baseDataSeries.getType() == DataSeries.Type.SECURITY + || baseDataSeries.getType() == DataSeries.Type.PORTFOLIO) + && EnumSet.of(ClientDataSeries.INTEREST, ClientDataSeries.INTEREST_ACCUMULATED, + ClientDataSeries.INTEREST_CHARGE, + ClientDataSeries.INTEREST_CHARGE_ACCUMULATED).contains(type)) + continue; + + var label = type.getLabel() + ": " + baseDataSeries.getLabel(); //$NON-NLS-1$ + + var dataSeries = new DataSeries(DataSeries.Type.DERIVED_DATA_SERIES, baseDataSeries.getGroup(), + new DerivedDataSeries(baseDataSeries, type), label, wheel.next()); + + dataSeries.setLineChart(baseDataSeries.isLineChart()); + dataSeries.setShowArea(baseDataSeries.isShowArea()); + + availableDerivedSeries.add(dataSeries); + } + } + } + private void buildStatementOfAssetsDataSeries() { availableSeries.add(new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.TOTALS, Messages.LabelTotalSum, diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DerivedDataSeries.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DerivedDataSeries.java new file mode 100644 index 0000000000..3a5394228e --- /dev/null +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/DerivedDataSeries.java @@ -0,0 +1,32 @@ +package name.abuchen.portfolio.ui.views.dataseries; + +import name.abuchen.portfolio.ui.views.dataseries.DataSeries.ClientDataSeries; + +public class DerivedDataSeries +{ + private final DataSeries baseDataSeries; + private final ClientDataSeries aspect; + + public DerivedDataSeries(DataSeries baseDataSeries, ClientDataSeries aspect) + { + this.baseDataSeries = baseDataSeries; + this.aspect = aspect; + } + + public String getUUID() + { + // eventually, the UUID is constructed as + // Derived-(aspect)-(underlying data series) + return aspect.name() + "-" + baseDataSeries.getUUID(); //$NON-NLS-1$ + } + + public DataSeries getBaseDataSeries() + { + return baseDataSeries; + } + + public ClientDataSeries getAspect() + { + return aspect; + } +} diff --git a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/StatementOfAssetsSeriesBuilder.java b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/StatementOfAssetsSeriesBuilder.java index 89db87248b..1519181445 100644 --- a/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/StatementOfAssetsSeriesBuilder.java +++ b/name.abuchen.portfolio.ui/src/name/abuchen/portfolio/ui/views/dataseries/StatementOfAssetsSeriesBuilder.java @@ -24,7 +24,7 @@ public void build(DataSeries series, Interval reportingPeriod) PerformanceIndex index = getCache().lookup(series, reportingPeriod); - if (series.getType() == DataSeries.Type.CLIENT) + if (series.getType() == DataSeries.Type.CLIENT || series.getType() == DataSeries.Type.DERIVED_DATA_SERIES) { addClient(series, index); } @@ -40,7 +40,8 @@ private void addClient(DataSeries series, PerformanceIndex clientIndex) { double[] values; - switch ((ClientDataSeries) series.getInstance()) + switch (series.getInstance() instanceof DerivedDataSeries derived ? derived.getAspect() + : (ClientDataSeries) series.getInstance()) { case TOTALS: values = toDouble(clientIndex.getTotals(), Values.Amount.divider());