Search in sources :

Example 1 with XYChartBuilder

use of org.projectforge.charting.XYChartBuilder in project projectforge by micromata.

the class LiquidityChartBuilder method createBarChart.

/**
 * @param forecast
 * @param settings (next days)
 * @return
 */
public JFreeChart createBarChart(final LiquidityForecast forecast, final LiquidityForecastSettings settings) {
    if (!(settings.getNextDays() > 0 && settings.getNextDays() <= LiquidityForecastSettings.MAX_FORECAST_DAYS)) {
        settings.setNextDays(LiquidityForecastSettings.DEFAULT_FORECAST_DAYS);
    }
    final LiquidityForecastCashFlow cashFlow = new LiquidityForecastCashFlow(forecast, settings.getNextDays());
    final TimeSeries accumulatedSeriesExpected = new TimeSeries(I18n.getString("plugins.liquidityplanning.forecast.expected"));
    final TimeSeries creditSeries = new TimeSeries(I18n.getString("plugins.liquidityplanning.common.credit"));
    final TimeSeries debitSeries = new TimeSeries(I18n.getString("plugins.liquidityplanning.common.debit"));
    double accumulatedExpected = settings.getStartAmount().doubleValue();
    PFDay dt = PFDay.fromOrNow(forecast.getBaseDate());
    final Date lower = dt.getUtilDate();
    for (int i = 0; i < settings.getNextDays(); i++) {
        final Day day = new Day(dt.getDayOfMonth(), dt.getMonthValue(), dt.getYear());
        if (i > 0) {
            accumulatedExpected += cashFlow.getDebitsExpected()[i - 1].doubleValue() + cashFlow.getCreditsExpected()[i - 1].doubleValue();
        }
        accumulatedSeriesExpected.add(day, accumulatedExpected);
        creditSeries.add(day, cashFlow.getCreditsExpected()[i].doubleValue());
        debitSeries.add(day, cashFlow.getDebitsExpected()[i].doubleValue());
        dt = dt.plusDays(1);
    }
    dt = dt.minusDays(1);
    final XYChartBuilder cb = new XYChartBuilder(ChartFactory.createXYBarChart(null, null, false, null, null, PlotOrientation.VERTICAL, false, false, false));
    int counter = 0;
    final TimeSeriesCollection xyDataSeries = new TimeSeriesCollection();
    xyDataSeries.addSeries(accumulatedSeriesExpected);
    final XYLineAndShapeRenderer lineRenderer = new XYLineAndShapeRenderer(true, true);
    lineRenderer.setSeriesPaint(0, cb.getRedMarker());
    lineRenderer.setSeriesVisibleInLegend(0, true);
    cb.setRenderer(counter, lineRenderer).setDataset(counter++, xyDataSeries).setStrongStyle(lineRenderer, false, accumulatedSeriesExpected);
    final TimeSeriesCollection cashflowSet = new TimeSeriesCollection();
    cashflowSet.addSeries(debitSeries);
    cashflowSet.addSeries(creditSeries);
    final XYBarRenderer barRenderer = new XYBarRenderer(.2);
    barRenderer.setSeriesPaint(0, cb.getGreenFill());
    barRenderer.setSeriesPaint(1, cb.getRedFill());
    barRenderer.setShadowVisible(false);
    cb.setRenderer(counter, barRenderer).setDataset(counter++, cashflowSet);
    cb.setDateXAxis(true).setDateXAxisRange(lower, dt.getUtilDate()).setYAxis(true, null);
    return cb.getChart();
}
Also used : TimeSeries(org.jfree.data.time.TimeSeries) TimeSeriesCollection(org.jfree.data.time.TimeSeriesCollection) XYLineAndShapeRenderer(org.jfree.chart.renderer.xy.XYLineAndShapeRenderer) Day(org.jfree.data.time.Day) PFDay(org.projectforge.framework.time.PFDay) XYChartBuilder(org.projectforge.charting.XYChartBuilder) PFDay(org.projectforge.framework.time.PFDay) Date(java.util.Date) XYBarRenderer(org.jfree.chart.renderer.xy.XYBarRenderer)

Example 2 with XYChartBuilder

use of org.projectforge.charting.XYChartBuilder in project projectforge by micromata.

the class LiquidityChartBuilder method createXYPlot.

/**
 * @param forecast
 * @param settings (next days)
 * @return
 */
public JFreeChart createXYPlot(final LiquidityForecast forecast, final LiquidityForecastSettings settings) {
    if (!(settings.getNextDays() > 0 && settings.getNextDays() <= LiquidityForecastSettings.MAX_FORECAST_DAYS)) {
        settings.setNextDays(LiquidityForecastSettings.DEFAULT_FORECAST_DAYS);
    }
    final LiquidityForecastCashFlow cashFlow = new LiquidityForecastCashFlow(forecast, settings.getNextDays());
    final TimeSeries accumulatedSeries = new TimeSeries(I18n.getString("plugins.liquidityplanning.forecast.dueDate"));
    final TimeSeries accumulatedSeriesExpected = new TimeSeries(ThreadLocalUserContext.getLocalizedString("plugins.liquidityplanning.forecast.expected"));
    // The paranoia case assumes only costs and no incomes (no invoice will be paid by the customers).
    final TimeSeries paranoiaCaseSeries = new TimeSeries(I18n.getString("plugins.liquidityplanning.forecast.paranoiaCase"));
    double accumulatedExpected = settings.getStartAmount().doubleValue();
    double accumulated = accumulatedExpected;
    double paranoiaCase = accumulated;
    PFDay dt = PFDay.fromOrNow(forecast.getBaseDate());
    final Date lower = dt.getUtilDate();
    for (int i = 0; i < settings.getNextDays(); i++) {
        if (log.isDebugEnabled()) {
            log.debug("day: " + i + ", credits=" + cashFlow.getCredits()[i] + ", debits=" + cashFlow.getDebits()[i]);
        }
        final Day day = new Day(dt.getDayOfMonth(), dt.getMonthValue(), dt.getYear());
        if (i > 0) {
            accumulated += cashFlow.getDebits()[i - 1].doubleValue() + cashFlow.getCredits()[i - 1].doubleValue();
            accumulatedExpected += cashFlow.getDebitsExpected()[i - 1].doubleValue() + cashFlow.getCreditsExpected()[i - 1].doubleValue();
            paranoiaCase += cashFlow.getCredits()[i - 1].doubleValue();
        }
        accumulatedSeries.add(day, accumulated);
        accumulatedSeriesExpected.add(day, accumulatedExpected);
        paranoiaCaseSeries.add(day, paranoiaCase);
        dt = dt.plusDays(1);
    }
    dt = dt.minusDays(1);
    final XYChartBuilder cb = new XYChartBuilder(null, null, null, null, true);
    int counter = 0;
    final TimeSeriesCollection xyDataSeries = new TimeSeriesCollection();
    xyDataSeries.addSeries(accumulatedSeries);
    xyDataSeries.addSeries(paranoiaCaseSeries);
    final XYLineAndShapeRenderer lineRenderer = new XYLineAndShapeRenderer(true, false);
    lineRenderer.setSeriesPaint(0, Color.BLACK);
    lineRenderer.setSeriesVisibleInLegend(0, true);
    lineRenderer.setSeriesPaint(1, cb.getGrayMarker());
    lineRenderer.setSeriesStroke(1, cb.getDashedStroke());
    lineRenderer.setSeriesVisibleInLegend(1, true);
    cb.setRenderer(counter, lineRenderer).setDataset(counter++, xyDataSeries);
    final TimeSeriesCollection accumulatedSet = new TimeSeriesCollection();
    accumulatedSet.addSeries(accumulatedSeriesExpected);
    final XYDifferenceRenderer diffRenderer = new XYDifferenceRenderer(cb.getGreenFill(), cb.getRedFill(), true);
    diffRenderer.setSeriesPaint(0, cb.getRedMarker());
    cb.setRenderer(counter, diffRenderer).setDataset(counter++, accumulatedSet).setStrongStyle(diffRenderer, false, accumulatedSeriesExpected);
    diffRenderer.setSeriesVisibleInLegend(0, true);
    cb.setDateXAxis(true).setDateXAxisRange(lower, dt.getUtilDate()).setYAxis(true, null);
    return cb.getChart();
}
Also used : TimeSeries(org.jfree.data.time.TimeSeries) TimeSeriesCollection(org.jfree.data.time.TimeSeriesCollection) XYLineAndShapeRenderer(org.jfree.chart.renderer.xy.XYLineAndShapeRenderer) XYDifferenceRenderer(org.jfree.chart.renderer.xy.XYDifferenceRenderer) Day(org.jfree.data.time.Day) PFDay(org.projectforge.framework.time.PFDay) XYChartBuilder(org.projectforge.charting.XYChartBuilder) PFDay(org.projectforge.framework.time.PFDay) Date(java.util.Date)

Example 3 with XYChartBuilder

use of org.projectforge.charting.XYChartBuilder in project projectforge by micromata.

the class TimesheetDisciplineChartBuilder method create.

/**
 * Ein Diagramm, welches über die letzten n Tage die Tage visualisiert, die zwischen Zeitberichtsdatum und Zeitpunkt der tatsächlichen
 * Buchung liegen.
 * @param timesheetDao
 * @param userId
 * @param forLastNDays
 * @return
 */
public JFreeChart create(final TimesheetDao timesheetDao, final Integer userId, final short forLastNDays) {
    PFDateTime dt = PFDateTime.now();
    final TimesheetFilter filter = new TimesheetFilter();
    filter.setStopTime(dt.getUtilDate());
    dt = dt.minusDays(forLastNDays);
    filter.setStartTime(dt.getUtilDate());
    filter.setUserId(userId);
    filter.setOrderType(OrderDirection.ASC);
    final List<TimesheetDO> list = timesheetDao.getList(filter);
    final TimeSeries planSeries = new TimeSeries("Soll");
    final TimeSeries actualSeries = new TimeSeries("Ist");
    final Iterator<TimesheetDO> it = list.iterator();
    TimesheetDO current = null;
    if (it.hasNext()) {
        current = it.next();
    }
    long numberOfBookedDays = 0;
    long totalDifference = 0;
    for (int i = 0; i <= forLastNDays; i++) {
        long difference = 0;
        // Weight for average.
        long totalDuration = 0;
        PFDateTime dateTime = null;
        if (current != null)
            // not null
            dateTime = PFDateTime.from(current.getStartTime());
        while (current != null && (dt.isSameDay(dateTime) || dateTime.isBefore(dt))) {
            final long duration = current.getWorkFractionDuration();
            difference += (current.getCreated().getTime() - current.getStartTime().getTime()) * duration;
            totalDuration += duration;
            if (it.hasNext()) {
                current = it.next();
                // not null
                dateTime = PFDateTime.from(current.getStartTime());
            } else {
                current = null;
                break;
            }
        }
        // In days.
        final double averageDifference = difference > 0 ? ((double) difference) / totalDuration / 86400000 : 0;
        final Day day = new Day(dt.getDayOfMonth(), dt.getMonthValue(), dt.getYear());
        if (averageDifference > 0) {
            // plan average
            planSeries.add(day, PLANNED_AVERAGE_DIFFERENCE_BETWEEN_TIMESHEET_AND_BOOKING);
            // (PLANNED_AVERAGE_DIFFERENCE_BETWEEN_TIMESHEET_AND_BOOKING
            // days).
            actualSeries.add(day, averageDifference);
            totalDifference += averageDifference;
            numberOfBookedDays++;
        }
        dt = dt.plusDays(1);
    }
    averageDifferenceBetweenTimesheetAndBooking = numberOfBookedDays > 0 ? new BigDecimal(totalDifference).divide(new BigDecimal(numberOfBookedDays), 1, RoundingMode.HALF_UP) : BigDecimal.ZERO;
    final TimeSeriesCollection dataset = new TimeSeriesCollection();
    dataset.addSeries(actualSeries);
    dataset.addSeries(planSeries);
    final XYChartBuilder cb = new XYChartBuilder(null, null, null, dataset, false);
    final XYDifferenceRenderer diffRenderer = new XYDifferenceRenderer(cb.getRedFill(), cb.getGreenFill(), true);
    diffRenderer.setSeriesPaint(0, cb.getRedMarker());
    diffRenderer.setSeriesPaint(1, cb.getGreenMarker());
    cb.setRenderer(0, diffRenderer).setStrongStyle(diffRenderer, false, actualSeries, planSeries);
    cb.setDateXAxis(true).setYAxis(true, "days");
    return cb.getChart();
}
Also used : TimeSeries(org.jfree.data.time.TimeSeries) XYDifferenceRenderer(org.jfree.chart.renderer.xy.XYDifferenceRenderer) PFDateTime(org.projectforge.framework.time.PFDateTime) BigDecimal(java.math.BigDecimal) TimesheetFilter(org.projectforge.business.timesheet.TimesheetFilter) TimeSeriesCollection(org.jfree.data.time.TimeSeriesCollection) TimesheetDO(org.projectforge.business.timesheet.TimesheetDO) Day(org.jfree.data.time.Day) XYChartBuilder(org.projectforge.charting.XYChartBuilder)

Example 4 with XYChartBuilder

use of org.projectforge.charting.XYChartBuilder in project projectforge by micromata.

the class TimesheetDisciplineChartBuilder method create.

/**
 * Ein Diagramm, welches über die letzten n Tage die kummulierten IST-Arbeitsstunden und als Soll-Wert die tatsächlich gebuchten
 * Zeitberichte aufträgt. Dies wird in einem Differenz-XY-Diagramm visualisiert. Die Darstellung soll motivieren, dass Projektmitarbeiter
 * ihre Zeitberichte möglichst zeitnah eintragen.
 * @param timesheetDao
 * @param userId
 * @param workingHoursPerDay
 * @param forLastNDays
 * @return
 */
public JFreeChart create(final TimesheetDao timesheetDao, final Integer userId, final double workingHoursPerDay, final short forLastNDays, boolean useWorkingHours) {
    PFDateTime dt = PFDateTime.now();
    final TimesheetFilter filter = new TimesheetFilter();
    filter.setStopTime(dt.getUtilDate());
    dt = dt.minusDays(forLastNDays);
    filter.setStartTime(dt.getUtilDate());
    filter.setUserId(userId);
    filter.setOrderType(OrderDirection.ASC);
    final List<TimesheetDO> list = timesheetDao.getList(filter);
    final TimeSeries sollSeries = new TimeSeries("Soll");
    final TimeSeries istSeries = new TimeSeries("Ist");
    planWorkingHours = 0;
    actualWorkingHours = 0;
    final Iterator<TimesheetDO> it = list.iterator();
    TimesheetDO current = null;
    if (it.hasNext()) {
        current = it.next();
    }
    long numberOfBookedDays = 0;
    long totalDifference = 0;
    for (int i = 0; i <= forLastNDays; i++) {
        // NPE-Fix required: current may be null.
        long difference = 0;
        // Weight for average.
        long totalDuration = 0;
        PFDateTime dateTime = null;
        if (current != null)
            // not null
            dateTime = PFDateTime.from(current.getStartTime());
        while (current != null && (dt.isSameDay(dateTime) || dateTime.isBefore(dt))) {
            if (useWorkingHours) {
                actualWorkingHours += ((double) current.getWorkFractionDuration()) / 3600000;
            } else {
                final long duration = current.getWorkFractionDuration();
                difference += (current.getCreated().getTime() - current.getStartTime().getTime()) * duration;
                totalDuration += duration;
            }
            if (it.hasNext()) {
                current = it.next();
                // not null
                dateTime = PFDateTime.from(current.getStartTime());
            } else {
                current = null;
                break;
            }
        }
        final Day day = new Day(dt.getDayOfMonth(), dt.getMonthValue(), dt.getYear());
        if (useWorkingHours) {
            Holidays holidays = Holidays.getInstance();
            if (holidays.isWorkingDay(dt.getDateTime())) {
                final BigDecimal workFraction = holidays.getWorkFraction(dt);
                if (workFraction != null) {
                    planWorkingHours += workFraction.doubleValue() * workingHoursPerDay;
                } else {
                    planWorkingHours += workingHoursPerDay;
                }
            }
            sollSeries.add(day, planWorkingHours);
            istSeries.add(day, actualWorkingHours);
        } else {
            // In days.
            final double averageDifference = difference > 0 ? ((double) difference) / totalDuration / 86400000 : 0;
            if (averageDifference > 0) {
                // plan average
                sollSeries.add(day, PLANNED_AVERAGE_DIFFERENCE_BETWEEN_TIMESHEET_AND_BOOKING);
                // (PLANNED_AVERAGE_DIFFERENCE_BETWEEN_TIMESHEET_AND_BOOKING
                // days).
                istSeries.add(day, averageDifference);
                totalDifference += averageDifference;
                numberOfBookedDays++;
            }
        }
        dt = dt.plusDays(1);
    }
    final TimeSeriesCollection dataset = new TimeSeriesCollection();
    if (useWorkingHours) {
        dataset.addSeries(sollSeries);
        dataset.addSeries(istSeries);
    } else {
        dataset.addSeries(istSeries);
        dataset.addSeries(sollSeries);
    }
    final XYChartBuilder cb = new XYChartBuilder(null, null, null, dataset, false);
    final XYDifferenceRenderer diffRenderer = new XYDifferenceRenderer(cb.getRedFill(), cb.getGreenFill(), true);
    diffRenderer.setSeriesPaint(0, cb.getRedMarker());
    diffRenderer.setSeriesPaint(1, cb.getGreenMarker());
    cb.setRenderer(0, diffRenderer).setStrongStyle(diffRenderer, false, sollSeries, istSeries);
    if (useWorkingHours) {
        cb.setDateXAxis(true).setYAxis(true, "hours");
    } else {
        averageDifferenceBetweenTimesheetAndBooking = numberOfBookedDays > 0 ? new BigDecimal(totalDifference).divide(new BigDecimal(numberOfBookedDays), 1, RoundingMode.HALF_UP) : BigDecimal.ZERO;
        cb.setDateXAxis(true).setYAxis(true, "days");
    }
    return cb.getChart();
}
Also used : TimeSeries(org.jfree.data.time.TimeSeries) XYDifferenceRenderer(org.jfree.chart.renderer.xy.XYDifferenceRenderer) PFDateTime(org.projectforge.framework.time.PFDateTime) BigDecimal(java.math.BigDecimal) Holidays(org.projectforge.framework.calendar.Holidays) TimesheetFilter(org.projectforge.business.timesheet.TimesheetFilter) TimeSeriesCollection(org.jfree.data.time.TimeSeriesCollection) TimesheetDO(org.projectforge.business.timesheet.TimesheetDO) Day(org.jfree.data.time.Day) XYChartBuilder(org.projectforge.charting.XYChartBuilder)

Aggregations

Day (org.jfree.data.time.Day)4 TimeSeries (org.jfree.data.time.TimeSeries)4 TimeSeriesCollection (org.jfree.data.time.TimeSeriesCollection)4 XYChartBuilder (org.projectforge.charting.XYChartBuilder)4 XYDifferenceRenderer (org.jfree.chart.renderer.xy.XYDifferenceRenderer)3 BigDecimal (java.math.BigDecimal)2 Date (java.util.Date)2 XYLineAndShapeRenderer (org.jfree.chart.renderer.xy.XYLineAndShapeRenderer)2 TimesheetDO (org.projectforge.business.timesheet.TimesheetDO)2 TimesheetFilter (org.projectforge.business.timesheet.TimesheetFilter)2 PFDateTime (org.projectforge.framework.time.PFDateTime)2 PFDay (org.projectforge.framework.time.PFDay)2 XYBarRenderer (org.jfree.chart.renderer.xy.XYBarRenderer)1 Holidays (org.projectforge.framework.calendar.Holidays)1