ResourceLoadRenderer.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
net.sourceforge.ganttproject.chart |
![]() |
![]() |
GanttProject |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* This code is provided under the terms of GPL version 2.
* Please see LICENSE file for details
* (C) Dmitry Barashev, GanttProject team, 2004-2008
*/
package net.sourceforge.ganttproject.chart;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import net.sourceforge.ganttproject.chart.ChartModelBase.Offset;
import net.sourceforge.ganttproject.chart.GraphicPrimitiveContainer.Rectangle;
import net.sourceforge.ganttproject.resource.LoadDistribution;
import net.sourceforge.ganttproject.resource.ProjectResource;
import net.sourceforge.ganttproject.resource.LoadDistribution.Load;
import net.sourceforge.ganttproject.task.ResourceAssignment;
import net.sourceforge.ganttproject.task.Task;
/**
* Renders resource load chart
*/
class ResourceLoadRenderer extends ChartRendererBase {
private List<LoadDistribution> myDistributions;
private ResourceChart myResourcechart;
public ResourceLoadRenderer(ChartModelResource model,
ResourceChart resourceChart) {
super(model);
myResourcechart = resourceChart;
}
/**
* Renders load distribution one by one, from top of the chart downwards
* If some resource is expanded, calls rendering of the load details
*/
public void render() {
beforeProcessingTimeFrames();
int ypos = 0;
for (LoadDistribution nextDistribution: myDistributions) {
List<Load> loads = nextDistribution.getLoads();
renderLoads(nextDistribution.getDaysOff(), ypos);
renderLoads(loads, ypos);
if (myResourcechart.isExpanded(nextDistribution.getResource())) {
renderLoadDetails(nextDistribution, ypos);
ypos += calculateGap(nextDistribution.getResource());
}
ypos += getConfig().getRowHeight();
}
}
/**
* Renders resource load details, that is, tasks where the resource
* is assigned to, with that resource load percentage
*/
private void renderLoadDetails(LoadDistribution distribution, int ypos) {
int yPos2 = ypos;
Map<Task, List<Load>> task2loads = distribution.getSeparatedTaskLoads();
for (ResourceAssignment assignment : distribution.getResource().getAssignments()) {
List<Load> nextLoads = task2loads.get(assignment.getTask());
yPos2 += getConfig().getRowHeight();
if (nextLoads==null) {
continue;
}
buildTasksLoadsRectangles(nextLoads, yPos2);
}
}
/**
* Renders the list of loads in a single chart row
* Preconditions: loads come from the same distribution and are ordered by
* their time offsets
*/
private void renderLoads(List<Load> loads, int ypos) {
Load prevLoad = null;
Load curLoad = null;
Queue<Offset> offsets = getOffsets();
String suffix = "";
for (int curIndex=1; curIndex<loads.size() && offsets.peek()!=null; curIndex++) {
curLoad = loads.get(curIndex);
prevLoad = loads.get(curIndex-1);
if (prevLoad.load!=0) {
renderLoads(prevLoad, curLoad, offsets, ypos, suffix);
suffix = "";
}
else if (curLoad.load > 0) {
suffix = ".first";
}
}
}
/**
* Renders prevLoad, with curLoad serving as a load right border marker and style hint
*/
private void renderLoads(
Load prevLoad, Load curLoad, Queue<Offset> offsets, int ypos, String suffix) {
final Date prevEnd = curLoad.startDate;
final Date prevStart = prevLoad.startDate;
Rectangle nextRect = createRectangle(offsets, prevStart, prevEnd, ypos);
if (nextRect==null) {
return;
}
String style;
if (prevLoad.isResourceUnavailable()) {
style = "dayoff";
}
else {
suffix += curLoad.load == 0 ? ".last" : "";
if (prevLoad.load < 100f) {
style = "load.underload";
}
else if (prevLoad.load > 100f) {
style = "load.overload";
}
else {
style = "load.normal";
}
style += suffix;
}
nextRect.setStyle(style);
nextRect.setModelObject(new ResourceLoad(prevLoad.load));
}
/**
* Renders a list of loads in a single chart row
* Precondition: loads belong to the same pair (resource,task) and are ordered
* by their time values
*/
private void buildTasksLoadsRectangles(List<Load> partition, int ypos) {
Queue<Offset> offsets = getOffsets();
Iterator<Load> loads = partition.iterator();
while (loads.hasNext() && offsets.peek()!=null) {
final Load nextLoad = loads.next();
final Date nextStart = nextLoad.startDate;
final Date nextEnd = nextLoad.endDate;
Rectangle nextRect = createRectangle(offsets, nextStart, nextEnd, ypos);
if (nextRect==null) {
continue;
}
String style;
if (nextLoad.load < 100f) {
style = "load.underload";
}
else if (nextLoad.load > 100f) {
style = "load.overload";
}
else {
style = "load.normal";
}
style += ".first.last";
nextRect.setStyle(style);
nextRect.setModelObject(new ResourceLoad(nextLoad.load));
}
}
private Rectangle createRectangle(Queue<Offset> offsets, Date start, Date end, int ypos) {
if (start.after(getChartEndDate()) || end.compareTo(getChartStartDate())<=0) {
return null;
}
Offset offsetBefore = null;
Offset offsetAfter = null;
while (offsets.peek()!=null) {
Offset offset = offsets.peek();
if (offset.getOffsetEnd().compareTo(start)<=0) {
offsetBefore = offset;
}
if (offsets.peek().getOffsetEnd().after(end)) {
offsetAfter = offsets.peek();
break;
}
if (offset.getOffsetEnd().equals(end)) {
offsetAfter = offset;
break;
}
offsets.poll();
}
int rectStart;
int rectEnd;
if (offsetAfter==null) {
rectEnd = getChartModel().getBounds().width;
}
else if (offsetAfter.getOffsetEnd().equals(end)) {
rectEnd = offsetAfter.getOffsetPixels();
}
else {
rectEnd = -1;
}
if (offsetBefore == null) {
rectStart = 0;
}
else if (offsetBefore.getOffsetEnd().equals(start)) {
rectStart = offsetBefore.getOffsetPixels();
}
else {
rectStart = -1;
}
if (rectStart==-1 || rectEnd==-1) {
return createRectangle(getDefaultOffsetsInRange(offsetBefore, offsetAfter), start, end, ypos);
}
Rectangle nextRect = getPrimitiveContainer().createRectangle(
rectStart, ypos, rectEnd-rectStart, getConfig().getRowHeight());
return nextRect;
}
private Queue<Offset> getDefaultOffsetsInRange(Offset offsetBefore, Offset offsetAfter) {
LinkedList<Offset> result = new LinkedList<Offset>(
getChartModel().getDefaultUnitOffsetsInRange(offsetBefore, offsetAfter));
if (offsetBefore!=null) {
result.addFirst(offsetBefore);
}
return result;
}
private Date getChartStartDate() {
return getChartModel().getStartDate();
}
private Date getChartEndDate() {
return getChartModel().getBottomUnitOffsets().get(getChartModel().getBottomUnitOffsets().size()-1).getOffsetEnd();
}
private Queue<Offset> getOffsets() {
return new LinkedList<Offset>(getChartModel().getBottomUnitOffsets());
}
public void beforeProcessingTimeFrames() {
myDistributions = new ArrayList<LoadDistribution>();
getPrimitiveContainer().clear();
getPrimitiveContainer().setOffset(0, getChartModel().getChartUIConfiguration().getHeaderHeight());
ProjectResource[] resources = ((ChartModelResource) getChartModel())
.getVisibleResources();
for (int i = 0; i < resources.length; i++) {
ProjectResource nextResource = resources[i];
LoadDistribution nextDistribution = nextResource.getLoadDistribution();
myDistributions.add(nextDistribution);
}
}
/**
* Class to use as Model object to display the load percentage in the
* rectangle.
*
* @author bbaranne
*/
static class ResourceLoad {
private float load;
ResourceLoad(float load) {
this.load = load;
}
public float getLoad() {
return load;
}
public String toString() {
return Float.toString(load);
}
}
private int calculateGap(ProjectResource resource) {
return resource.getAssignments().length * getConfig().getRowHeight();
}
}
The table below shows all metrics for ResourceLoadRenderer.java.




