Extract class for filling load charts

ResourceLoadController and CompanyPlanningModel now use this class.

FEA: ItEr75S11PreventLooseChanges
This commit is contained in:
Óscar González Fernández 2011-08-02 19:18:30 +02:00
parent 4aba29d69c
commit fbf97300c4
6 changed files with 202 additions and 251 deletions

View file

@ -49,13 +49,13 @@ import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.labels.entities.LabelType;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.planner.chart.ResourceLoadChartData;
import org.navalplanner.business.planner.daos.IDayAssignmentDAO;
import org.navalplanner.business.planner.daos.ITaskElementDAO;
import org.navalplanner.business.planner.entities.DayAssignment;
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
import org.navalplanner.business.planner.entities.ICostCalculator;
import org.navalplanner.business.planner.entities.ResourceAllocation;
import org.navalplanner.business.planner.entities.ResourceLoadChartData;
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
import org.navalplanner.business.planner.entities.Task;
import org.navalplanner.business.planner.entities.TaskElement;

View file

@ -0,0 +1,18 @@
package org.navalplanner.business.planner.chart;
import java.util.SortedMap;
import org.joda.time.LocalDate;
import org.navalplanner.business.workingday.EffortDuration;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public interface ILoadChartData {
SortedMap<LocalDate, EffortDuration> getLoad();
SortedMap<LocalDate, EffortDuration> getAvailability();
SortedMap<LocalDate, EffortDuration> getOverload();
}

View file

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.navalplanner.business.planner.entities;
package org.navalplanner.business.planner.chart;
import static org.navalplanner.business.workingday.EffortDuration.min;
import static org.navalplanner.business.workingday.EffortDuration.zero;
@ -36,6 +36,7 @@ import java.util.TreeMap;
import org.joda.time.LocalDate;
import org.navalplanner.business.calendars.entities.ICalendar;
import org.navalplanner.business.hibernate.notification.PredefinedDatabaseSnapshots;
import org.navalplanner.business.planner.entities.DayAssignment;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.EffortDuration.IEffortFrom;
@ -50,7 +51,7 @@ import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
* @author Jacobo Aragunde Pérez<jaragunde@igalia.com>
*
*/
public class ResourceLoadChartData {
public class ResourceLoadChartData implements ILoadChartData {
private SortedMap<LocalDate, EffortDuration> load;
@ -92,6 +93,43 @@ public class ResourceLoadChartData {
return availability;
}
public ILoadChartData on(final LocalDate startInclusive,
final LocalDate endExclusive) {
final ResourceLoadChartData original = ResourceLoadChartData.this;
if (startInclusive == null && endExclusive == null) {
return original;
}
return new ILoadChartData() {
@Override
public SortedMap<LocalDate, EffortDuration> getOverload() {
return filter(original.getOverload());
}
@Override
public SortedMap<LocalDate, EffortDuration> getLoad() {
return filter(original.getLoad());
}
@Override
public SortedMap<LocalDate, EffortDuration> getAvailability() {
return filter(original.getAvailability());
}
private SortedMap<LocalDate, EffortDuration> filter(
SortedMap<LocalDate, EffortDuration> map) {
if (startInclusive != null) {
return map.tailMap(startInclusive);
}
if (endExclusive != null) {
return map.headMap(endExclusive);
}
return map.subMap(startInclusive, endExclusive);
}
};
}
private SortedMap<LocalDate, Map<Resource, EffortDuration>> groupDurationsByDayAndResource(
List<DayAssignment> dayAssignments) {
SortedMap<LocalDate, Map<Resource, EffortDuration>> map =

View file

@ -0,0 +1,117 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 Igalia, S.L.
*
* 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.chart;
import static java.util.Arrays.asList;
import java.util.Collections;
import java.util.SortedMap;
import org.joda.time.LocalDate;
import org.navalplanner.business.planner.chart.ILoadChartData;
import org.navalplanner.business.workingday.EffortDuration;
import org.zkforge.timeplot.Plotinfo;
import org.zkforge.timeplot.Timeplot;
import org.zkforge.timeplot.geometry.TimeGeometry;
import org.zkforge.timeplot.geometry.ValueGeometry;
import org.zkoss.ganttz.util.Interval;
import org.zkoss.zk.ui.util.Clients;
public abstract class LoadChartFiller extends ChartFiller {
public static final String COLOR_CAPABILITY_LINE = "#000000"; // Black
public static final String COLOR_ASSIGNED_LOAD_GLOBAL = "#98D471"; // Green
public static final String COLOR_OVERLOAD_GLOBAL = "#FF5A11"; // Red
@Override
public void fillChart(Timeplot chart, Interval interval, Integer size) {
chart.getChildren().clear();
chart.invalidate();
if (getOptionalJavascriptCall() != null) {
Clients.evalJavaScript(getOptionalJavascriptCall());
}
resetMinimumAndMaximumValueForChart();
final ILoadChartData data = getDataOn(interval);
Plotinfo plotInfoLoad = createPlotinfoFromDurations(getLoad(data),
interval);
plotInfoLoad.setFillColor(COLOR_ASSIGNED_LOAD_GLOBAL);
plotInfoLoad.setLineWidth(0);
Plotinfo plotInfoMax = createPlotinfoFromDurations(
getCalendarMaximumAvailability(data), interval);
plotInfoMax.setLineColor(COLOR_CAPABILITY_LINE);
plotInfoMax.setFillColor("#FFFFFF");
plotInfoMax.setLineWidth(2);
Plotinfo plotInfoOverload = createPlotinfoFromDurations(
getOverload(data), interval);
plotInfoOverload.setFillColor(COLOR_OVERLOAD_GLOBAL);
plotInfoOverload.setLineWidth(0);
ValueGeometry valueGeometry = getValueGeometry();
TimeGeometry timeGeometry = getTimeGeometry(interval);
appendPlotinfo(chart, plotInfoOverload, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoMax, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoLoad, valueGeometry, timeGeometry);
chart.setWidth(size + "px");
chart.setHeight("150px");
}
protected abstract String getOptionalJavascriptCall();
protected abstract ILoadChartData getDataOn(Interval interval);
protected LocalDate getStart(LocalDate explicitlySpecifiedStart,
Interval interval) {
if (explicitlySpecifiedStart == null) {
return interval.getStart();
}
return Collections.max(asList(explicitlySpecifiedStart,
interval.getStart()));
}
@SuppressWarnings("unchecked")
protected LocalDate getEnd(LocalDate explicitlySpecifiedEnd,
Interval interval) {
if (explicitlySpecifiedEnd == null) {
return interval.getFinish();
}
return Collections.min(asList(explicitlySpecifiedEnd,
interval.getFinish()));
}
private SortedMap<LocalDate, EffortDuration> getLoad(ILoadChartData data) {
return groupAsNeededByZoom(data.getLoad());
}
private SortedMap<LocalDate, EffortDuration> getOverload(ILoadChartData data) {
return groupAsNeededByZoom(data.getOverload());
}
private SortedMap<LocalDate, EffortDuration> getCalendarMaximumAvailability(
ILoadChartData data) {
return data.getAvailability();
}
}

View file

@ -54,6 +54,8 @@ import org.navalplanner.business.hibernate.notification.PredefinedDatabaseSnapsh
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.orders.entities.OrderStatusEnum;
import org.navalplanner.business.planner.chart.ILoadChartData;
import org.navalplanner.business.planner.chart.ResourceLoadChartData;
import org.navalplanner.business.planner.entities.TaskElement;
import org.navalplanner.business.planner.entities.TaskGroup;
import org.navalplanner.business.planner.entities.TaskMilestone;
@ -63,16 +65,15 @@ import org.navalplanner.business.templates.entities.OrderTemplate;
import org.navalplanner.business.users.daos.IUserDAO;
import org.navalplanner.business.users.entities.User;
import org.navalplanner.business.users.entities.UserRole;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workreports.entities.WorkReportLine;
import org.navalplanner.web.orders.assigntemplates.TemplateFinderPopup;
import org.navalplanner.web.orders.assigntemplates.TemplateFinderPopup.IOnResult;
import org.navalplanner.web.planner.ITaskElementAdapter;
import org.navalplanner.web.planner.chart.Chart;
import org.navalplanner.web.planner.chart.ChartFiller;
import org.navalplanner.web.planner.chart.EarnedValueChartFiller;
import org.navalplanner.web.planner.chart.EarnedValueChartFiller.EarnedValueType;
import org.navalplanner.web.planner.chart.IChartFiller;
import org.navalplanner.web.planner.chart.LoadChartFiller;
import org.navalplanner.web.planner.order.BankHolidaysMarker;
import org.navalplanner.web.planner.order.OrderPlanningModel;
import org.navalplanner.web.planner.tabs.MultipleTabsPlannerController;
@ -85,8 +86,6 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.zkforge.timeplot.Plotinfo;
import org.zkforge.timeplot.Timeplot;
import org.zkforge.timeplot.geometry.TimeGeometry;
import org.zkforge.timeplot.geometry.ValueGeometry;
import org.zkoss.ganttz.IChartVisibilityChangedListener;
import org.zkoss.ganttz.IPredicate;
import org.zkoss.ganttz.Planner;
@ -130,10 +129,6 @@ import org.zkoss.zul.Vbox;
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class CompanyPlanningModel implements ICompanyPlanningModel {
public static final String COLOR_CAPABILITY_LINE = "#000000"; // Black
public static final String COLOR_ASSIGNED_LOAD_GLOBAL = "#98D471"; // Green
public static final String COLOR_OVERLOAD_GLOBAL = "#FF5A11"; // Red
@Autowired
private IOrderDAO orderDAO;
@ -800,66 +795,19 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
getFilterFinishDate());
}
private class CompanyLoadChartFiller extends ChartFiller {
private class CompanyLoadChartFiller extends LoadChartFiller {
@Override
public void fillChart(Timeplot chart, Interval interval, Integer size) {
chart.getChildren().clear();
chart.invalidate();
String javascript = "ganttz.GanttPanel.getInstance().timeplotContainerRescroll()";
Clients.evalJavaScript(javascript);
resetMinimumAndMaximumValueForChart();
LocalDate start = filterStartDate != null ? filterStartDate
: interval.getStart();
LocalDate finish = filterFinishDate != null ? filterFinishDate
: interval.getFinish();
Plotinfo plotInfoLoad = createPlotinfoFromDurations(
getLoad(start, finish), interval);
plotInfoLoad.setFillColor(COLOR_ASSIGNED_LOAD_GLOBAL);
plotInfoLoad.setLineWidth(0);
Plotinfo plotInfoMax = createPlotinfoFromDurations(
getCalendarMaximumAvailability(start, finish), interval);
plotInfoMax.setLineColor(COLOR_CAPABILITY_LINE);
plotInfoMax.setFillColor("#FFFFFF");
plotInfoMax.setLineWidth(2);
Plotinfo plotInfoOverload = createPlotinfoFromDurations(
getOverload(start, finish), interval);
plotInfoOverload.setFillColor(COLOR_OVERLOAD_GLOBAL);
plotInfoOverload.setLineWidth(0);
ValueGeometry valueGeometry = getValueGeometry();
TimeGeometry timeGeometry = getTimeGeometry(interval);
appendPlotinfo(chart, plotInfoOverload, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoMax, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoLoad, valueGeometry, timeGeometry);
chart.setWidth(size + "px");
chart.setHeight("150px");
protected String getOptionalJavascriptCall() {
return "ganttz.GanttPanel.getInstance().timeplotContainerRescroll()";
}
private SortedMap<LocalDate, EffortDuration> getLoad(LocalDate start,
LocalDate finish) {
return groupAsNeededByZoom(databaseSnapshots.
snapshotResourceLoadChartData().getLoad().subMap(start, finish));
}
private SortedMap<LocalDate, EffortDuration> getOverload(
LocalDate start, LocalDate finish) {
return groupAsNeededByZoom(
databaseSnapshots.snapshotResourceLoadChartData().getOverload().subMap(start, finish));
}
private SortedMap<LocalDate, EffortDuration> getCalendarMaximumAvailability(
LocalDate start, LocalDate finish) {
return databaseSnapshots.snapshotResourceLoadChartData().getAvailability().subMap(start, finish);
@Override
protected ILoadChartData getDataOn(Interval interval) {
ResourceLoadChartData data = databaseSnapshots
.snapshotResourceLoadChartData();
return data.on(getStart(filterStartDate, interval),
getEnd(filterFinishDate, interval));
}
}

View file

@ -21,20 +21,12 @@
package org.navalplanner.web.resourceload;
import static org.navalplanner.business.workingday.EffortDuration.min;
import static org.navalplanner.business.workingday.EffortDuration.zero;
import static org.navalplanner.web.I18nHelper._;
import static org.navalplanner.web.resourceload.ResourceLoadModel.asDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.lang.Validate;
import org.joda.time.LocalDate;
@ -43,16 +35,16 @@ import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.common.daos.IConfigurationDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.planner.chart.ILoadChartData;
import org.navalplanner.business.planner.chart.ResourceLoadChartData;
import org.navalplanner.business.planner.entities.DayAssignment;
import org.navalplanner.business.planner.entities.TaskElement;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.IntraDayDate.PartialDay;
import org.navalplanner.web.common.components.bandboxsearch.BandboxMultipleSearch;
import org.navalplanner.web.common.components.finders.FilterPair;
import org.navalplanner.web.planner.chart.Chart;
import org.navalplanner.web.planner.chart.ChartFiller;
import org.navalplanner.web.planner.chart.LoadChartFiller;
import org.navalplanner.web.planner.company.CompanyPlanningModel;
import org.navalplanner.web.planner.order.BankHolidaysMarker;
import org.navalplanner.web.planner.order.IOrderPlanningGate;
@ -65,8 +57,6 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.zkforge.timeplot.Plotinfo;
import org.zkforge.timeplot.Timeplot;
import org.zkforge.timeplot.geometry.TimeGeometry;
import org.zkforge.timeplot.geometry.ValueGeometry;
import org.zkoss.ganttz.IChartVisibilityChangedListener;
import org.zkoss.ganttz.data.resourceload.LoadTimeLine;
import org.zkoss.ganttz.resourceload.IFilterChangedListener;
@ -623,183 +613,23 @@ public class ResourceLoadController implements Composer {
return timeplot;
}
private class ResourceLoadChartFiller extends ChartFiller {
private class ResourceLoadChartFiller extends LoadChartFiller {
@Override
public void fillChart(Timeplot chart, Interval interval, Integer size) {
chart.getChildren().clear();
chart.invalidate();
resetMinimumAndMaximumValueForChart();
LocalDate start = interval.getStart();
LocalDate finish = interval.getFinish();
if ((resourceLoadModel.getInitDateFilter() != null)
&& (resourceLoadModel.getInitDateFilter().compareTo(start) > 0)) {
start = resourceLoadModel.getInitDateFilter();
}
if ((resourceLoadModel.getEndDateFilter() != null)
&& (resourceLoadModel.getEndDateFilter().compareTo(finish) < 0)) {
finish = resourceLoadModel.getEndDateFilter();
}
Plotinfo plotInfoLoad = createPlotinfoFromDurations(
getLoad(start, finish), interval);
plotInfoLoad
.setFillColor(CompanyPlanningModel.COLOR_ASSIGNED_LOAD_GLOBAL);
plotInfoLoad.setLineWidth(0);
Plotinfo plotInfoMax = createPlotinfoFromDurations(
getCalendarMaximumAvailability(interval.getStart(),
interval.getFinish()), interval);
plotInfoMax
.setLineColor(CompanyPlanningModel.COLOR_CAPABILITY_LINE);
plotInfoMax.setFillColor("#FFFFFF");
plotInfoMax.setLineWidth(2);
Plotinfo plotInfoOverload = createPlotinfoFromDurations(
getOverload(start, finish), interval);
plotInfoOverload
.setFillColor(CompanyPlanningModel.COLOR_OVERLOAD_GLOBAL);
plotInfoOverload.setLineWidth(0);
ValueGeometry valueGeometry = getValueGeometry();
TimeGeometry timeGeometry = getTimeGeometry(interval);
appendPlotinfo(chart, plotInfoOverload, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoMax, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoLoad, valueGeometry, timeGeometry);
chart.setWidth(size + "px");
chart.setHeight("150px");
protected String getOptionalJavascriptCall() {
return null;
}
private SortedMap<LocalDate, EffortDuration> getLoad(LocalDate start,
LocalDate finish) {
@Override
protected ILoadChartData getDataOn(Interval interval) {
List<DayAssignment> dayAssignments = resourceLoadModel
.getDayAssignments();
SortedMap<LocalDate, EffortDuration> result = new TreeMap<LocalDate, EffortDuration>();
SortedMap<LocalDate, Map<Resource, EffortDuration>> dayAssignmentGrouped = groupDurationsByDayAndResource(dayAssignments);
SortedMap<LocalDate, EffortDuration> mapDayAssignments = calculateHoursAdditionByDayWithoutOverload(dayAssignmentGrouped);
for (Entry<LocalDate, EffortDuration> each : mapDayAssignments
.entrySet()) {
LocalDate day = each.getKey();
if (day.compareTo(start) >= 0 && day.compareTo(finish) <= 0) {
result.put(day, each.getValue());
}
}
return result;
}
private SortedMap<LocalDate, EffortDuration> getOverload(
LocalDate start, LocalDate finish) {
List<DayAssignment> dayAssignments = resourceLoadModel
.getDayAssignments();
SortedMap<LocalDate, Map<Resource, EffortDuration>> dayAssignmentGrouped = groupDurationsByDayAndResource(dayAssignments);
SortedMap<LocalDate, EffortDuration> mapDayAssignments = calculateHoursAdditionByDayJustOverload(dayAssignmentGrouped);
SortedMap<LocalDate, EffortDuration> mapMaxAvailability = calculateHoursAdditionByDay(
resourceLoadModel.getResources(), start, finish);
for (Entry<LocalDate, EffortDuration> each : mapDayAssignments
.entrySet()) {
LocalDate day = each.getKey();
EffortDuration overload = each.getValue();
if (day.compareTo(start) >= 0 && day.compareTo(finish) <= 0) {
EffortDuration maxAvailability = mapMaxAvailability
.get(day);
mapDayAssignments.put(day, overload.plus(maxAvailability));
}
}
SortedMap<LocalDate, EffortDuration> result = new TreeMap<LocalDate, EffortDuration>();
for (LocalDate day : mapDayAssignments.keySet()) {
if (day.compareTo(start) >= 0 && day.compareTo(finish) <= 0) {
result.put(day, mapDayAssignments.get(day));
}
}
return result;
}
private SortedMap<LocalDate, EffortDuration> calculateHoursAdditionByDayWithoutOverload(
SortedMap<LocalDate, Map<Resource, EffortDuration>> dayAssignmentGrouped) {
SortedMap<LocalDate, EffortDuration> map = new TreeMap<LocalDate, EffortDuration>();
for (Entry<LocalDate, Map<Resource, EffortDuration>> each : dayAssignmentGrouped
.entrySet()) {
LocalDate date = each.getKey();
PartialDay day = PartialDay.wholeDay(date);
EffortDuration result = zero();
for (Entry<Resource, EffortDuration> resourceWithDuration : each
.getValue().entrySet()) {
Resource resource = resourceWithDuration.getKey();
EffortDuration assignedDuration = resourceWithDuration
.getValue();
EffortDuration resourceCapacity = resource
.getCalendarOrDefault().getCapacityOn(day);
result = result
.plus(min(assignedDuration, resourceCapacity));
}
map.put(date, result);
}
return groupAsNeededByZoom(map);
}
private SortedMap<LocalDate, EffortDuration> calculateHoursAdditionByDayJustOverload(
SortedMap<LocalDate, Map<Resource, EffortDuration>> dayAssignmentGrouped) {
SortedMap<LocalDate, EffortDuration> map = new TreeMap<LocalDate, EffortDuration>();
for (Entry<LocalDate, Map<Resource, EffortDuration>> each : dayAssignmentGrouped
.entrySet()) {
final LocalDate date = each.getKey();
final PartialDay day = PartialDay.wholeDay(date);
EffortDuration result = zero();
for (Entry<Resource, EffortDuration> resourceWithDuration : each
.getValue().entrySet()) {
Resource resource = resourceWithDuration.getKey();
EffortDuration assignedDuration = resourceWithDuration
.getValue();
EffortDuration resourceCapacity = resource
.getCalendarOrDefault().getCapacityOn(day);
EffortDuration overloadIncrement = assignedDuration
.minus(min(resourceCapacity, assignedDuration));
result = result.plus(overloadIncrement);
}
map.put(date, result);
}
return groupAsNeededByZoom(map);
}
private SortedMap<LocalDate, EffortDuration> getCalendarMaximumAvailability(
LocalDate start, LocalDate finish) {
return calculateHoursAdditionByDay(
resourceLoadModel.getResources(), start, finish);
}
private SortedMap<LocalDate, EffortDuration> calculateHoursAdditionByDay(
List<Resource> resources, LocalDate start, LocalDate finish) {
return new EffortByDayCalculator<Entry<LocalDate, List<Resource>>>() {
@Override
protected LocalDate getDayFor(
Entry<LocalDate, List<Resource>> element) {
return element.getKey();
}
@Override
protected EffortDuration getDurationFor(
Entry<LocalDate, List<Resource>> element) {
return sumCalendarCapacitiesForDay(element.getValue(),
element.getKey());
}
}.calculate(getResourcesByDateBetween(resources, start, finish));
}
private Set<Entry<LocalDate, List<Resource>>> getResourcesByDateBetween(
List<Resource> resources, LocalDate start, LocalDate finish) {
Map<LocalDate, List<Resource>> result = new HashMap<LocalDate, List<Resource>>();
for (LocalDate date = start; date.compareTo(finish) <= 0; date = date
.plusDays(1)) {
result.put(date, resources);
}
return result.entrySet();
List<Resource> resources = resourceLoadModel.getResources();
ResourceLoadChartData data = new ResourceLoadChartData(
dayAssignments, resources);
return data.on(
getStart(resourceLoadModel.getInitDateFilter(), interval),
getEnd(resourceLoadModel.getEndDateFilter(), interval));
}
}