Package name.abuchen.portfolio.ui.views

Source Code of name.abuchen.portfolio.ui.views.PerformanceChartView$ExportDropDown

package name.abuchen.portfolio.ui.views;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.snapshot.Aggregation;
import name.abuchen.portfolio.snapshot.PerformanceIndex;
import name.abuchen.portfolio.snapshot.ReportingPeriod;
import name.abuchen.portfolio.ui.Messages;
import name.abuchen.portfolio.ui.PortfolioPart;
import name.abuchen.portfolio.ui.PortfolioPlugin;
import name.abuchen.portfolio.ui.util.AbstractCSVExporter;
import name.abuchen.portfolio.ui.util.AbstractDropDown;
import name.abuchen.portfolio.ui.util.chart.TimelineChart;
import name.abuchen.portfolio.ui.util.chart.TimelineChartCSVExporter;
import name.abuchen.portfolio.ui.views.ChartConfigurator.ClientDataSeries;
import name.abuchen.portfolio.ui.views.ChartConfigurator.DataSeries;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ToolBar;
import org.swtchart.IBarSeries;
import org.swtchart.ILineSeries;
import org.swtchart.ISeries;

public class PerformanceChartView extends AbstractHistoricView
{
    private static final String KEY_AGGREGATION_PERIOD = "performance-chart-aggregation-period"; //$NON-NLS-1$

    private TimelineChart chart;
    private ChartConfigurator picker;

    private Aggregation.Period aggregationPeriod;

    private Map<Object, Object> dataCache = new HashMap<Object, Object>();

    @Override
    protected String getTitle()
    {
        return Messages.LabelPerformanceChart;
    }

    @Override
    public void init(PortfolioPart part, Object parameter)
    {
        super.init(part, parameter);

        String key = part.getPreferenceStore().getString(KEY_AGGREGATION_PERIOD);
        if (key != null && key.length() > 0)
        {
            try
            {
                aggregationPeriod = Aggregation.Period.valueOf(key);
            }
            catch (IllegalArgumentException ignore)
            {
                // ignore if key is not a valid aggregation period
            }
        }
    }

    @Override
    protected void addButtons(ToolBar toolBar)
    {
        super.addButtons(toolBar);
        new AggregationPeriodDropDown(toolBar);
        new ExportDropDown(toolBar);
        addConfigButton(toolBar);
    }

    private void addConfigButton(ToolBar toolBar)
    {
        Action save = new Action()
        {
            @Override
            public void run()
            {
                picker.showSaveMenu(getActiveShell());
            }
        };
        save.setImageDescriptor(PortfolioPlugin.descriptor(PortfolioPlugin.IMG_SAVE));
        save.setToolTipText(Messages.MenuSaveChart);
        new ActionContributionItem(save).fill(toolBar, -1);

        Action config = new Action()
        {
            @Override
            public void run()
            {
                picker.showMenu(getActiveShell());
            }
        };
        config.setImageDescriptor(PortfolioPlugin.descriptor(PortfolioPlugin.IMG_CONFIG));
        config.setToolTipText(Messages.MenuConfigureChart);
        new ActionContributionItem(config).fill(toolBar, -1);
    }

    @Override
    protected Composite createBody(Composite parent)
    {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));

        chart = new TimelineChart(composite);
        chart.getTitle().setText(getTitle());
        chart.getTitle().setVisible(false);
        chart.getAxisSet().getYAxis(0).getTick().setFormat(new DecimalFormat("0.#%")); //$NON-NLS-1$
        chart.getToolTip().setValueFormat(new DecimalFormat("0.##%")); //$NON-NLS-1$

        picker = new ChartConfigurator(composite, this, ChartConfigurator.Mode.PERFORMANCE);
        picker.setListener(new ChartConfigurator.Listener()
        {
            @Override
            public void onUpdate()
            {
                updateChart();
            }
        });

        GridLayoutFactory.fillDefaults().numColumns(1).margins(0, 0).spacing(0, 0).applyTo(composite);
        GridDataFactory.fillDefaults().grab(true, true).applyTo(chart);
        GridDataFactory.fillDefaults().grab(true, false).align(SWT.CENTER, SWT.FILL).applyTo(picker);

        setChartSeries();

        return composite;
    }

    @Override
    public void setFocus()
    {
        chart.getAxisSet().adjustRange();
        chart.setFocus();
    }

    @Override
    public void reportingPeriodUpdated()
    {
        dataCache.clear();
        updateChart();
    }

    @Override
    public void notifyModelUpdated()
    {
        dataCache.clear();
        updateChart();
    }

    private void updateChart()
    {
        try
        {
            chart.suspendUpdate(true);
            for (ISeries s : chart.getSeriesSet().getSeries())
                chart.getSeriesSet().deleteSeries(s.getId());

            setChartSeries();

            chart.getAxisSet().adjustRange();
        }
        finally
        {
            chart.suspendUpdate(false);
        }
        chart.redraw();
    }

    private void setChartSeries()
    {
        List<Exception> warnings = new ArrayList<Exception>();

        for (DataSeries item : picker.getSelectedDataSeries())
        {
            if (item.getType() == Client.class)
                addClient(item, (ClientDataSeries) item.getInstance(), warnings);
            else if (item.getType() == ConsumerPriceIndex.class)
                addConsumerPriceIndex(item, warnings);
            else if (item.getType() == Security.class)
                addSecurity(item, (Security) item.getInstance(), warnings);
            else if (item.getType() == Portfolio.class)
                addPortfolio(item, (Portfolio) item.getInstance(), warnings);
            else if (item.getType() == Account.class)
                addAccount(item, (Account) item.getInstance(), warnings);
            else if (item.getType() == Classification.class)
                addClassification(item, (Classification) item.getInstance(), warnings);
        }

        PortfolioPlugin.log(warnings);
    }

    private PerformanceIndex getClientIndex(List<Exception> warnings)
    {
        PerformanceIndex index = (PerformanceIndex) dataCache.get(Client.class);
        if (index == null)
        {
            ReportingPeriod interval = getReportingPeriod();
            index = PerformanceIndex.forClient(getClient(), interval, warnings);
            dataCache.put(Client.class, index);
        }
        return index;
    }

    private void addClient(DataSeries item, ClientDataSeries type, List<Exception> warnings)
    {
        PerformanceIndex clientIndex = getClientIndex(warnings);
        PerformanceIndex aggregatedIndex = aggregationPeriod != null ? Aggregation.aggregate(clientIndex,
                        aggregationPeriod) : clientIndex;

        switch (type)
        {
            case TOTALS:
                ILineSeries series = chart.addDateSeries(aggregatedIndex.getDates(), //
                                aggregatedIndex.getAccumulatedPercentage(), //
                                Messages.PerformanceChartLabelAccumulatedIRR);
                item.configure(series);
                break;
            case TRANSFERALS:
                IBarSeries barSeries = chart.addDateBarSeries(aggregatedIndex.getDates(), //
                                aggregatedIndex.getDeltaPercentage(), //
                                aggregationPeriod != null ? aggregationPeriod.toString()
                                                : Messages.LabelAggregationDaily);
                item.configure(barSeries);
                break;
            default:
                break;
        }
    }

    private void addConsumerPriceIndex(DataSeries item, List<Exception> warnings)
    {
        PerformanceIndex cpiIndex = (PerformanceIndex) dataCache.get(ConsumerPriceIndex.class);

        if (cpiIndex == null)
        {
            PerformanceIndex clientIndex = getClientIndex(warnings);
            cpiIndex = PerformanceIndex.forConsumerPriceIndex(clientIndex, warnings);
            dataCache.put(ConsumerPriceIndex.class, cpiIndex);
        }

        if (cpiIndex.getDates().length > 0
                        && (aggregationPeriod == null || aggregationPeriod != Aggregation.Period.YEARLY))
        {
            ILineSeries series = chart.addDateSeries(cpiIndex.getDates(), //
                            cpiIndex.getAccumulatedPercentage(), //
                            Messages.PerformanceChartLabelCPI);
            item.configure(series);
        }
    }

    private void addSecurity(DataSeries item, Security security, List<Exception> warnings)
    {
        if (item.isBenchmark())
            addSecurityBenchmark(item, security, warnings);
        else
            addSecurityPerformance(item, security, warnings);
    }

    private void addSecurityBenchmark(DataSeries item, Security security, List<Exception> warnings)
    {
        PerformanceIndex securityIndex = (PerformanceIndex) dataCache.get(security);

        if (securityIndex == null)
        {
            PerformanceIndex clientIndex = getClientIndex(warnings);
            securityIndex = PerformanceIndex.forSecurity(clientIndex, security, warnings);
            dataCache.put(security, securityIndex);
        }

        if (aggregationPeriod != null)
            securityIndex = Aggregation.aggregate(securityIndex, aggregationPeriod);

        ILineSeries series = chart.addDateSeries(securityIndex.getDates(), //
                        securityIndex.getAccumulatedPercentage(), //
                        item.getLabel());
        item.configure(series);
    }

    private void addSecurityPerformance(DataSeries item, Security security, List<Exception> warnings)
    {
        PerformanceIndex securityIndex = (PerformanceIndex) dataCache.get(security.getUUID());

        if (securityIndex == null)
        {
            securityIndex = PerformanceIndex.forInvestment(getClient(), security, getReportingPeriod(), warnings);
            dataCache.put(security.getUUID(), securityIndex);
        }

        if (aggregationPeriod != null)
            securityIndex = Aggregation.aggregate(securityIndex, aggregationPeriod);

        ILineSeries series = chart.addDateSeries(securityIndex.getDates(), //
                        securityIndex.getAccumulatedPercentage(), //
                        item.getLabel());
        item.configure(series);
    }

    private void addPortfolio(DataSeries item, Portfolio portfolio, List<Exception> warnings)
    {
        PerformanceIndex portfolioIndex = (PerformanceIndex) dataCache.get(portfolio);

        if (portfolioIndex == null)
        {
            portfolioIndex = PerformanceIndex.forPortfolio(getClient(), portfolio, getReportingPeriod(), warnings);
            dataCache.put(portfolio, portfolioIndex);
        }

        if (aggregationPeriod != null)
            portfolioIndex = Aggregation.aggregate(portfolioIndex, aggregationPeriod);

        ILineSeries series = chart.addDateSeries(portfolioIndex.getDates(), //
                        portfolioIndex.getAccumulatedPercentage(), //
                        portfolio.getName());
        item.configure(series);
    }

    private void addAccount(DataSeries item, Account account, List<Exception> warnings)
    {
        PerformanceIndex accountIndex = (PerformanceIndex) dataCache.get(account);

        if (accountIndex == null)
        {
            accountIndex = PerformanceIndex.forAccount(getClient(), account, getReportingPeriod(), warnings);
            dataCache.put(account, accountIndex);
        }

        if (aggregationPeriod != null)
            accountIndex = Aggregation.aggregate(accountIndex, aggregationPeriod);

        ILineSeries series = chart.addDateSeries(accountIndex.getDates(), //
                        accountIndex.getAccumulatedPercentage(), //
                        account.getName());
        item.configure(series);
    }

    private void addClassification(DataSeries item, Classification classification, List<Exception> warnings)
    {
        PerformanceIndex index = (PerformanceIndex) dataCache.get(classification);

        if (index == null)
        {
            index = PerformanceIndex.forClassification(getClient(), classification, getReportingPeriod(), warnings);
            dataCache.put(classification, index);
        }

        if (aggregationPeriod != null)
            index = Aggregation.aggregate(index, aggregationPeriod);

        ILineSeries series = chart.addDateSeries(index.getDates(), //
                        index.getAccumulatedPercentage(), //
                        item.getLabel());
        item.configure(series);
    }

    private final class AggregationPeriodDropDown extends AbstractDropDown
    {
        private AggregationPeriodDropDown(ToolBar toolBar)
        {
            super(toolBar, aggregationPeriod == null ? Messages.LabelAggregationDaily : aggregationPeriod.toString());
        }

        @Override
        public void menuAboutToShow(IMenuManager manager)
        {
            Action daily = new Action(Messages.LabelAggregationDaily)
            {
                @Override
                public void run()
                {
                    setLabel(Messages.LabelAggregationDaily);
                    aggregationPeriod = null;
                    getPart().getPreferenceStore().setValue(KEY_AGGREGATION_PERIOD, ""); //$NON-NLS-1$
                    updateChart();
                }
            };
            daily.setChecked(aggregationPeriod == null);
            manager.add(daily);

            for (final Aggregation.Period period : Aggregation.Period.values())
            {
                Action action = new Action(period.toString())
                {
                    @Override
                    public void run()
                    {
                        setLabel(period.toString());
                        aggregationPeriod = period;
                        getPart().getPreferenceStore().setValue(KEY_AGGREGATION_PERIOD, period.name());
                        updateChart();
                    }
                };
                action.setChecked(aggregationPeriod == period);
                manager.add(action);
            }
        }
    }

    private final class ExportDropDown extends AbstractDropDown
    {
        private ExportDropDown(ToolBar toolBar)
        {
            super(toolBar, Messages.MenuExportData, PortfolioPlugin.image(PortfolioPlugin.IMG_EXPORT), SWT.NONE);
        }

        @Override
        public void menuAboutToShow(IMenuManager manager)
        {
            manager.add(new Action(Messages.MenuExportChartData)
            {
                @Override
                public void run()
                {
                    TimelineChartCSVExporter exporter = new TimelineChartCSVExporter(chart);
                    exporter.addDiscontinousSeries(Messages.PerformanceChartLabelCPI);
                    exporter.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); //$NON-NLS-1$
                    exporter.setValueFormat(new DecimalFormat("0.##########")); //$NON-NLS-1$
                    exporter.export(getTitle() + ".csv"); //$NON-NLS-1$
                }
            });

            addMenu(manager, Client.class, Messages.PerformanceChartLabelAccumulatedIRR);

            Set<Class<?>> exportTypes = new HashSet<Class<?>>(Arrays.asList(new Class<?>[] { //
                            Security.class, Portfolio.class, Account.class }));

            for (DataSeries series : picker.getSelectedDataSeries())
            {
                if (exportTypes.contains(series.getType()))
                    addMenu(manager, series.getInstance(), series.getLabel());
            }

            manager.add(new Separator());
            chart.exportMenuAboutToShow(manager, getTitle());
        }

        private void addMenu(IMenuManager manager, final Object instance, final String label)
        {
            manager.add(new Action(MessageFormat.format(Messages.LabelExport, label))
            {
                @Override
                public void run()
                {
                    AbstractCSVExporter exporter = new AbstractCSVExporter()
                    {
                        @Override
                        protected void writeToFile(File file) throws IOException
                        {
                            PerformanceIndex index = (PerformanceIndex) dataCache.get(instance);
                            if (aggregationPeriod != null)
                                index = Aggregation.aggregate(index, aggregationPeriod);
                            index.exportTo(file);
                        }

                        @Override
                        protected Control getControl()
                        {
                            return ExportDropDown.this.getToolBar();
                        }
                    };
                    exporter.export(getTitle() + "_" + label + ".csv"); //$NON-NLS-1$ //$NON-NLS-2$
                }
            });
        }
    }
}
TOP

Related Classes of name.abuchen.portfolio.ui.views.PerformanceChartView$ExportDropDown

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.