package name.abuchen.portfolio.ui.views.dataseries; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Display; import org.swtchart.LineStyle; import name.abuchen.portfolio.model.Account; import name.abuchen.portfolio.model.Classification; import name.abuchen.portfolio.model.Client; import name.abuchen.portfolio.model.ConsumerPriceIndex; import name.abuchen.portfolio.model.Portfolio; import name.abuchen.portfolio.model.Security; import name.abuchen.portfolio.model.Taxonomy; import name.abuchen.portfolio.ui.Messages; import name.abuchen.portfolio.ui.util.ClientFilterMenu; import name.abuchen.portfolio.ui.util.Colors; import name.abuchen.portfolio.ui.views.dataseries.DataSeries.ClientDataSeries; /** * The set of available data series for a given presentation use case. */ public class DataSeriesSet { private DataSeries.UseCase useCase; private final List<DataSeries> availableSeries = new ArrayList<>(); public DataSeriesSet(Client client, IPreferenceStore preferences, DataSeries.UseCase useCase) { this.useCase = useCase; ColorWheel wheel = new ColorWheel(30); switch (useCase) { case STATEMENT_OF_ASSETS: buildStatementOfAssetsDataSeries(); break; case PERFORMANCE: buildPerformanceDataSeries(client, wheel); break; case RETURN_VOLATILITY: buildReturnVolatilitySeries(client, wheel); break; default: throw new IllegalArgumentException(useCase.name()); } buildCommonDataSeries(client, preferences, wheel); } public DataSeries.UseCase getUseCase() { return useCase; } public List<DataSeries> getAvailableSeries() { return availableSeries; } /** * Returns DataSeries matching the given UUID. */ public DataSeries lookup(String uuid) { return availableSeries.stream().filter(d -> d.getUUID().equals(uuid)).findAny().orElse(null); } private void buildStatementOfAssetsDataSeries() { availableSeries.add(new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.TOTALS, Messages.LabelTotalSum, Colors.TOTALS.swt())); DataSeries series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.TRANSFERALS, Messages.LabelTransferals, Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY).getRGB()); series.setLineChart(false); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.INVESTED_CAPITAL, Messages.LabelInvestedCapital, Display.getDefault().getSystemColor(SWT.COLOR_GRAY).getRGB()); series.setShowArea(true); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.ABSOLUTE_INVESTED_CAPITAL, Messages.LabelAbsoluteInvestedCapital, Display.getDefault().getSystemColor(SWT.COLOR_GRAY).getRGB()); series.setShowArea(true); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.ABSOLUTE_DELTA, Messages.LabelDelta, Display.getDefault().getSystemColor(SWT.COLOR_GRAY).getRGB()); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.ABSOLUTE_DELTA_ALL_RECORDS, Messages.LabelAbsoluteDelta, Display.getDefault().getSystemColor(SWT.COLOR_GRAY).getRGB()); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.TAXES, Messages.LabelAccumulatedTaxes, Display.getDefault().getSystemColor(SWT.COLOR_RED).getRGB()); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.DIVIDENDS, Messages.LabelDividends, Display.getDefault().getSystemColor(SWT.COLOR_DARK_MAGENTA).getRGB()); series.setLineChart(false); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.DIVIDENDS_ACCUMULATED, Messages.LabelAccumulatedDividends, Display.getDefault().getSystemColor(SWT.COLOR_DARK_MAGENTA).getRGB()); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.INTEREST, Messages.LabelInterest, Display.getDefault().getSystemColor(SWT.COLOR_DARK_GREEN).getRGB()); series.setLineChart(false); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.INTEREST_ACCUMULATED, Messages.LabelAccumulatedInterest, Display.getDefault().getSystemColor(SWT.COLOR_DARK_GREEN).getRGB()); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.INTEREST_CHARGE, Messages.LabelInterestCharge, Display.getDefault().getSystemColor(SWT.COLOR_DARK_GREEN).getRGB()); series.setLineChart(false); availableSeries.add(series); series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.INTEREST_CHARGE_ACCUMULATED, Messages.LabelAccumulatedInterestCharge, Display.getDefault().getSystemColor(SWT.COLOR_DARK_GREEN).getRGB()); availableSeries.add(series); } private void buildPerformanceDataSeries(Client client, ColorWheel wheel) { // accumulated performance availableSeries.add(new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.TOTALS, Messages.PerformanceChartLabelEntirePortfolio, Colors.TOTALS.swt())); DataSeries series = new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.DELTA_PERCENTAGE, Messages.LabelAggregationDaily, Display.getDefault().getSystemColor(SWT.COLOR_DARK_GRAY).getRGB()); series.setLineChart(false); availableSeries.add(series); // consumer price index series = new DataSeries(DataSeries.Type.CONSUMER_PRICE_INDEX, ConsumerPriceIndex.class, Messages.LabelConsumerPriceIndex, Colors.CPI.swt()); series.setBenchmark(true); series.setLineStyle(LineStyle.DASHDOTDOT); availableSeries.add(series); // securities as benchmark int index = 0; for (Security security : client.getSecurities()) { series = new DataSeries(DataSeries.Type.SECURITY_BENCHMARK, security, security.getName(), // wheel.getRGB(index++)); series.setBenchmark(true); availableSeries.add(series); } } private void buildReturnVolatilitySeries(Client client, ColorWheel wheel) { // accumulated performance availableSeries.add(new DataSeries(DataSeries.Type.CLIENT, ClientDataSeries.TOTALS, Messages.PerformanceChartLabelEntirePortfolio, Colors.TOTALS.swt())); // securities as benchmark int index = 0; for (Security security : client.getSecurities()) { DataSeries series = new DataSeries(DataSeries.Type.SECURITY_BENCHMARK, security, security.getName(), // wheel.getRGB(index++)); series.setBenchmark(true); availableSeries.add(series); } } private void buildCommonDataSeries(Client client, IPreferenceStore preferences, ColorWheel wheel) { int index = client.getSecurities().size(); for (Security security : client.getSecurities()) { // securites w/o currency code (e.g. a stock index) cannot be added // as equity data series (only as benchmark) if (security.getCurrencyCode() == null) continue; availableSeries.add(new DataSeries(DataSeries.Type.SECURITY, security, security.getName(), // wheel.getRGB(index++))); } for (Portfolio portfolio : client.getPortfolios()) availableSeries.add(new DataSeries(DataSeries.Type.PORTFOLIO, portfolio, portfolio.getName(), // wheel.getRGB(index++))); // portfolio + reference account for (Portfolio portfolio : client.getPortfolios()) { DataSeries series = new DataSeries(DataSeries.Type.PORTFOLIO_PLUS_ACCOUNT, portfolio, portfolio.getName() + " + " + portfolio.getReferenceAccount().getName(), //$NON-NLS-1$ wheel.getRGB(index++)); availableSeries.add(series); } // custom client filters ClientFilterMenu menu = new ClientFilterMenu(client, preferences); // quick fix: users can create duplicate client filters that end up to // have the same UUID. Avoid adding both violates the precondition that // every data series must have a unique id Set<String> addedSeries = new HashSet<>(); for (ClientFilterMenu.Item item : menu.getCustomItems()) { DataSeries series = new DataSeries(DataSeries.Type.CLIENT_FILTER, item, item.getLabel(), wheel.getRGB(index++)); if (addedSeries.add(series.getUUID())) availableSeries.add(series); } for (Account account : client.getAccounts()) availableSeries.add( new DataSeries(DataSeries.Type.ACCOUNT, account, account.getName(), wheel.getRGB(index++))); for (Taxonomy taxonomy : client.getTaxonomies()) { taxonomy.foreach(new Taxonomy.Visitor() { @Override public void visit(Classification classification) { if (classification.getParent() == null) return; availableSeries.add(new DataSeries(DataSeries.Type.CLASSIFICATION, classification, classification.getName(), Colors.toRGB(classification.getColor()))); } }); } } }