ItEr30S11CUVistaRecursosTempoEmpresaItEr29S13: Refactoring code in charge to show the chart in the company view.

This commit is contained in:
Manuel Rego Casasnovas 2009-10-16 18:25:34 +02:00 committed by Javier Moran Rua
parent 98cf958be6
commit 3b112ce335
3 changed files with 320 additions and 196 deletions

View file

@ -20,8 +20,6 @@
package org.navalplanner.web.planner;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -31,10 +29,6 @@ import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.LocalDate;
import org.navalplanner.business.calendars.entities.ResourceCalendar;
import org.navalplanner.business.calendars.entities.SameWorkHoursEveryDay;
@ -50,8 +44,6 @@ import org.navalplanner.business.planner.entities.TaskGroup;
import org.navalplanner.business.planner.entities.TaskMilestone;
import org.navalplanner.business.resources.daos.IResourceDAO;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.web.servlets.CallbackServlet;
import org.navalplanner.web.servlets.CallbackServlet.IServletRequestHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
@ -82,12 +74,6 @@ import org.zkoss.zul.Div;
@Scope(BeanDefinition.SCOPE_SINGLETON)
public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
/**
* Number of days to Thursday since the beginning of the week. In order to
* calculate the middle of a week.
*/
private final static int DAYS_TO_THURSDAY = 3;
@Autowired
private IOrderDAO orderDAO;
@ -100,11 +86,9 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
@Autowired
private IAdHocTransactionService transactionService;
private Integer maximunValueForChart = 0;
private IZoomLevelChangedListener zoomListener;
private ZoomLevel zoomLevel = ZoomLevel.DETAIL_ONE;
private ILoadChartFiller loadChartFiller = new CompanyLoadChartFiller();
private final class TaskElementNavigator implements
IStructureNavigator<TaskElement> {
@ -154,7 +138,8 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
}
private void setupChart(Timeplot chartComponent, TimeTracker timeTracker) {
fillChart(chartComponent, timeTracker.getRealInterval(), timeTracker
loadChartFiller.fillChart(chartComponent,
timeTracker.getRealInterval(), timeTracker
.getHorizontalSize());
fillChartOnZoomChange(chartComponent, timeTracker);
}
@ -166,15 +151,15 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
@Override
public void zoomLevelChanged(final ZoomLevel detailLevel) {
zoomLevel = detailLevel;
loadChartFiller.setZoomLevel(detailLevel);
transactionService
.runOnReadOnlyTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
fillChart(chartComponent,
timeTracker.getRealInterval(), timeTracker
.getHorizontalSize());
loadChartFiller.fillChart(chartComponent,
timeTracker.getRealInterval(),
timeTracker.getHorizontalSize());
return null;
}
});
@ -262,165 +247,6 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
// spring method injection
protected abstract ITaskElementAdapter getTaskElementAdapter();
private void fillChart(Timeplot chart, Interval interval, Integer size) {
chart.getChildren().clear();
chart.invalidate();
maximunValueForChart = 0;
Plotinfo plotInfoLoad = getLoadPlotInfo(interval.getStart(), interval
.getFinish());
plotInfoLoad.setFillColor("0000FF");
Plotinfo plotInfoMax = getCalendarMaximumAvailabilityPlotInfo(interval
.getStart(), interval.getFinish());
plotInfoMax.setLineColor("FF0000");
ValueGeometry valueGeometry = new DefaultValueGeometry();
valueGeometry.setMin(0);
valueGeometry.setMax(maximunValueForChart);
valueGeometry.setGridColor("#000000");
valueGeometry.setAxisLabelsPlacement("left");
plotInfoLoad.setValueGeometry(valueGeometry);
plotInfoMax.setValueGeometry(valueGeometry);
chart.appendChild(plotInfoMax);
chart.appendChild(plotInfoLoad);
size = size + (16 * 2);
chart.setWidth(size + "px");
chart.setHeight("100px");
}
private Plotinfo getLoadPlotInfo(Date start, Date finish) {
List<DayAssignment> dayAssignments = dayAssignmentDAO.list(DayAssignment.class);
SortedMap<LocalDate, Integer> mapDayAssignments = calculateHoursAdditionByDay(dayAssignments);
String uri = getServletUri(mapDayAssignments, start, finish);
PlotDataSource pds = new PlotDataSource();
pds.setDataSourceUri(uri);
pds.setSeparator(" ");
Plotinfo plotInfo = new Plotinfo();
plotInfo.setPlotDataSource(pds);
return plotInfo;
}
private void printLine(PrintWriter writer, LocalDate day, Integer hours) {
writer.println(day.toString("yyyyMMdd") + " " + hours);
}
private void fillZeroValueFromStart(PrintWriter writer, Date start,
SortedMap<LocalDate, Integer> mapDayAssignments) {
LocalDate day = new LocalDate(start);
if (mapDayAssignments.isEmpty()) {
printLine(writer, day, 0);
} else if (day.compareTo(mapDayAssignments.firstKey()) < 0) {
printLine(writer, day, 0);
if (!day.equals(mapDayAssignments.firstKey().minusDays(1))) {
printLine(writer, mapDayAssignments.firstKey().minusDays(1), 0);
}
}
}
private void fillZeroValueToFinish(PrintWriter writer, Date finish,
SortedMap<LocalDate, Integer> mapDayAssignments) {
LocalDate day = new LocalDate(finish);
if (mapDayAssignments.isEmpty()) {
printLine(writer, day, 0);
} else if (day.compareTo(mapDayAssignments.lastKey()) > 0) {
if (!day.equals(mapDayAssignments.lastKey().plusDays(1))) {
printLine(writer, mapDayAssignments.lastKey().plusDays(1), 0);
}
printLine(writer, day, 0);
}
}
private Plotinfo getCalendarMaximumAvailabilityPlotInfo(Date start,
Date finish) {
SortedMap<LocalDate, Integer> mapDayAssignments = calculateHoursAdditionByDay(
resourceDAO.list(Resource.class), start, finish);
String uri = getServletUri(mapDayAssignments, start, finish);
PlotDataSource pds = new PlotDataSource();
pds.setDataSourceUri(uri);
pds.setSeparator(" ");
Plotinfo plotInfo = new Plotinfo();
plotInfo.setPlotDataSource(pds);
return plotInfo;
}
private String getServletUri(
final SortedMap<LocalDate, Integer> mapDayAssignments,
final Date start, final Date finish) {
if (mapDayAssignments.isEmpty()) {
return "";
}
setMaximunValueForChartIfGreater(Collections.max(mapDayAssignments.values()));
String uri = CallbackServlet
.registerAndCreateURLFor(new IServletRequestHandler() {
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter writer = response.getWriter();
fillZeroValueFromStart(writer, start, mapDayAssignments);
LocalDate firstDay = firstDay(mapDayAssignments);
LocalDate lastDay = lastDay(mapDayAssignments);
for (LocalDate day = firstDay; day.compareTo(lastDay) <= 0; day = nextDay(day)) {
Integer hours = mapDayAssignments.get(day) != null ? mapDayAssignments
.get(day)
: 0;
printLine(writer, day, hours);
}
fillZeroValueToFinish(writer, finish, mapDayAssignments);
writer.close();
}
});
return uri;
}
private LocalDate firstDay(SortedMap<LocalDate, Integer> mapDayAssignments) {
LocalDate date = mapDayAssignments.firstKey();
if (zoomByDay()) {
return date;
} else {
return date.dayOfWeek().withMinimumValue().plusDays(
DAYS_TO_THURSDAY);
}
}
private LocalDate lastDay(SortedMap<LocalDate, Integer> mapDayAssignments) {
LocalDate date = mapDayAssignments.lastKey();
if (zoomByDay()) {
return date;
} else {
return date.dayOfWeek().withMinimumValue().plusDays(
DAYS_TO_THURSDAY);
}
}
private LocalDate nextDay(LocalDate date) {
if (zoomByDay()) {
return date;
} else {
return date.plusWeeks(1);
}
}
/**
* Calculate the hours by day for all the {@link DayAssignment} in the list.
*
@ -456,7 +282,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
}
}
if (zoomLevel.equals(ZoomLevel.DETAIL_FIVE)) {
if (loadChartFiller.zoomByDay()) {
return map;
} else {
return groupByWeek(map);
@ -485,7 +311,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
map.put(date, hours);
}
if (zoomLevel.equals(ZoomLevel.DETAIL_FIVE)) {
if (loadChartFiller.zoomByDay()) {
return map;
} else {
return groupByWeek(map);
@ -497,7 +323,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
SortedMap<LocalDate, Integer> result = new TreeMap<LocalDate, Integer>();
for (LocalDate day : map.keySet()) {
LocalDate key = getKey(day);
LocalDate key = loadChartFiller.getThursdayOfThisWeek(day);
if (result.get(key) == null) {
result.put(key, map.get(day));
@ -513,16 +339,6 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
return result;
}
private LocalDate getKey(LocalDate date) {
return date.dayOfWeek().withMinimumValue().plusDays(3);
}
private void setMaximunValueForChartIfGreater(Integer max) {
if (maximunValueForChart < max) {
maximunValueForChart = max;
}
}
private org.zkoss.zk.ui.Component getChartLegend() {
Div div = new Div();
@ -532,8 +348,75 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
return div;
}
private boolean zoomByDay() {
return zoomLevel.equals(ZoomLevel.DETAIL_FIVE);
private class CompanyLoadChartFiller extends LoadChartFiller {
@Override
public void fillChart(Timeplot chart, Interval interval, Integer size) {
chart.getChildren().clear();
chart.invalidate();
resetMaximunValueForChart();
Plotinfo plotInfoLoad = getLoadPlotInfo(interval.getStart(),
interval.getFinish());
plotInfoLoad.setFillColor("0000FF");
Plotinfo plotInfoMax = getCalendarMaximumAvailabilityPlotInfo(
interval.getStart(), interval.getFinish());
plotInfoMax.setLineColor("FF0000");
ValueGeometry valueGeometry = new DefaultValueGeometry();
valueGeometry.setMin(0);
valueGeometry.setMax(getMaximunValueForChart());
valueGeometry.setGridColor("#000000");
valueGeometry.setAxisLabelsPlacement("left");
plotInfoLoad.setValueGeometry(valueGeometry);
plotInfoMax.setValueGeometry(valueGeometry);
chart.appendChild(plotInfoMax);
chart.appendChild(plotInfoLoad);
size = size + (16 * 2);
chart.setWidth(size + "px");
chart.setHeight("100px");
}
private Plotinfo getLoadPlotInfo(Date start, Date finish) {
List<DayAssignment> dayAssignments = dayAssignmentDAO
.list(DayAssignment.class);
SortedMap<LocalDate, Integer> mapDayAssignments = calculateHoursAdditionByDay(dayAssignments);
String uri = getServletUri(mapDayAssignments,
start, finish);
PlotDataSource pds = new PlotDataSource();
pds.setDataSourceUri(uri);
pds.setSeparator(" ");
Plotinfo plotInfo = new Plotinfo();
plotInfo.setPlotDataSource(pds);
return plotInfo;
}
private Plotinfo getCalendarMaximumAvailabilityPlotInfo(Date start,
Date finish) {
SortedMap<LocalDate, Integer> mapDayAssignments = calculateHoursAdditionByDay(
resourceDAO.list(Resource.class), start, finish);
String uri = getServletUri(mapDayAssignments,
start, finish);
PlotDataSource pds = new PlotDataSource();
pds.setDataSourceUri(uri);
pds.setSeparator(" ");
Plotinfo plotInfo = new Plotinfo();
plotInfo.setPlotDataSource(pds);
return plotInfo;
}
}
}

View file

@ -0,0 +1,53 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.planner;
import java.util.Date;
import java.util.SortedMap;
import org.joda.time.LocalDate;
import org.zkforge.timeplot.Timeplot;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.Interval;
/**
* Contract for {@link LoadChartFiller}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public interface ILoadChartFiller {
void fillChart(Timeplot chart, Interval interval, Integer size);
String getServletUri(final SortedMap<LocalDate, Integer> mapDayAssignments,
final Date start, final Date finish);
void setZoomLevel(ZoomLevel zoomLevel);
void resetMaximunValueForChart();
Integer getMaximunValueForChart();
boolean zoomByDay();
LocalDate getThursdayOfThisWeek(LocalDate date);
}

View file

@ -0,0 +1,188 @@
/*
* This file is part of ###PROJECT_NAME###
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.web.planner;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Date;
import java.util.SortedMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.joda.time.LocalDate;
import org.navalplanner.web.servlets.CallbackServlet;
import org.navalplanner.web.servlets.CallbackServlet.IServletRequestHandler;
import org.zkforge.timeplot.Timeplot;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.Interval;
/**
* Abstract class with the basic functionality to fill the chart.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public abstract class LoadChartFiller implements ILoadChartFiller {
/**
* Number of days to Thursday since the beginning of the week. In order to
* calculate the middle of a week.
*/
private final static int DAYS_TO_THURSDAY = 3;
private ZoomLevel zoomLevel = ZoomLevel.DETAIL_ONE;
private Integer maximunValueForChart = 0;
@Override
public abstract void fillChart(Timeplot chart, Interval interval,
Integer size);
@Override
public String getServletUri(
final SortedMap<LocalDate, Integer> mapDayAssignments,
final Date start, final Date finish) {
if (mapDayAssignments.isEmpty()) {
return "";
}
setMaximunValueForChartIfGreater(Collections.max(mapDayAssignments
.values()));
String uri = CallbackServlet
.registerAndCreateURLFor(new IServletRequestHandler() {
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
PrintWriter writer = response.getWriter();
fillZeroValueFromStart(writer, start, mapDayAssignments);
LocalDate firstDay = firstDay(mapDayAssignments);
LocalDate lastDay = lastDay(mapDayAssignments);
for (LocalDate day = firstDay; day.compareTo(lastDay) <= 0; day = nextDay(day)) {
Integer hours = mapDayAssignments.get(day) != null ? mapDayAssignments
.get(day)
: 0;
printLine(writer, day, hours);
}
fillZeroValueToFinish(writer, finish, mapDayAssignments);
writer.close();
}
});
return uri;
}
private void setMaximunValueForChartIfGreater(Integer max) {
if (maximunValueForChart < max) {
maximunValueForChart = max;
}
}
private LocalDate firstDay(SortedMap<LocalDate, Integer> mapDayAssignments) {
LocalDate date = mapDayAssignments.firstKey();
if (zoomByDay()) {
return date;
} else {
return getThursdayOfThisWeek(date);
}
}
private LocalDate lastDay(SortedMap<LocalDate, Integer> mapDayAssignments) {
LocalDate date = mapDayAssignments.lastKey();
if (zoomByDay()) {
return date;
} else {
return getThursdayOfThisWeek(date);
}
}
@Override
public LocalDate getThursdayOfThisWeek(LocalDate date) {
return date.dayOfWeek().withMinimumValue().plusDays(DAYS_TO_THURSDAY);
}
private LocalDate nextDay(LocalDate date) {
if (zoomByDay()) {
return date;
} else {
return date.plusWeeks(1);
}
}
@Override
public boolean zoomByDay() {
return zoomLevel.equals(ZoomLevel.DETAIL_FIVE);
}
private void fillZeroValueFromStart(PrintWriter writer, Date start,
SortedMap<LocalDate, Integer> mapDayAssignments) {
LocalDate day = new LocalDate(start);
if (mapDayAssignments.isEmpty()) {
printLine(writer, day, 0);
} else if (day.compareTo(mapDayAssignments.firstKey()) < 0) {
printLine(writer, day, 0);
if (!day.equals(mapDayAssignments.firstKey().minusDays(1))) {
printLine(writer, mapDayAssignments.firstKey().minusDays(1), 0);
}
}
}
private void fillZeroValueToFinish(PrintWriter writer, Date finish,
SortedMap<LocalDate, Integer> mapDayAssignments) {
LocalDate day = new LocalDate(finish);
if (mapDayAssignments.isEmpty()) {
printLine(writer, day, 0);
} else if (day.compareTo(mapDayAssignments.lastKey()) > 0) {
if (!day.equals(mapDayAssignments.lastKey().plusDays(1))) {
printLine(writer, mapDayAssignments.lastKey().plusDays(1), 0);
}
printLine(writer, day, 0);
}
}
private void printLine(PrintWriter writer, LocalDate day, Integer hours) {
writer.println(day.toString("yyyyMMdd") + " " + hours);
}
@Override
public void setZoomLevel(ZoomLevel zoomLevel) {
this.zoomLevel = zoomLevel;
}
@Override
public void resetMaximunValueForChart() {
this.maximunValueForChart = 0;
}
@Override
public Integer getMaximunValueForChart() {
return maximunValueForChart;
}
}