Revamp 'Estimation Accuracy' chart
FEA: ItEr76S15OrganizingPerProjectDashboard
This commit is contained in:
parent
7b3ca0da29
commit
5dc4a59da2
4 changed files with 143 additions and 3 deletions
|
|
@ -95,6 +95,7 @@ public class DashboardController extends GenericForwardComposer {
|
|||
renderTasksSummary();
|
||||
renderDeadlineViolation();
|
||||
renderMarginWithDeadline();
|
||||
renderEstimationAccuracy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -172,6 +173,30 @@ public class DashboardController extends GenericForwardComposer {
|
|||
renderChart(barChart, divId);
|
||||
}
|
||||
|
||||
private void renderEstimationAccuracy() {
|
||||
final String divId = "estimation-accuracy";
|
||||
|
||||
BarChart<Integer> barChart;
|
||||
barChart = new BarChart<Integer>("Estimation Accuracy");
|
||||
|
||||
barChart.setFillZero(true);
|
||||
barChart.setHighlightMouseDown(true);
|
||||
barChart.setStackSeries(false);
|
||||
barChart.setBarMargin(30);
|
||||
|
||||
barChart.addSeries(new Serie("Tasks"));
|
||||
|
||||
EstimationAccuracy estimationAccuracyData = EstimationAccuracy
|
||||
.create(dashboardModel);
|
||||
barChart.setTicks(estimationAccuracyData.getTicks());
|
||||
barChart.addValues(estimationAccuracyData.getValues());
|
||||
|
||||
barChart.getAxes().getXaxis()
|
||||
.setLabel(_("Number of Tasks / % Deviation"));
|
||||
|
||||
renderChart(barChart, divId);
|
||||
}
|
||||
|
||||
private void renderTasksSummary() {
|
||||
Map<TaskStatusEnum, Integer> taskStatus = dashboardModel
|
||||
.calculateTaskStatus();
|
||||
|
|
@ -407,4 +432,48 @@ public class DashboardController extends GenericForwardComposer {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino García<dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
static class EstimationAccuracy {
|
||||
|
||||
private final IDashboardModel dashboardModel;
|
||||
|
||||
private Map<Interval, Integer> estimationAccuracyData;
|
||||
|
||||
private EstimationAccuracy(IDashboardModel dashboardModel) {
|
||||
this.dashboardModel = dashboardModel;
|
||||
}
|
||||
|
||||
public static EstimationAccuracy create(IDashboardModel dashboardModel) {
|
||||
return new EstimationAccuracy(dashboardModel);
|
||||
}
|
||||
|
||||
private Map<Interval, Integer> getData() {
|
||||
if (estimationAccuracyData == null) {
|
||||
estimationAccuracyData = dashboardModel
|
||||
.calculateEstimationAccuracy();
|
||||
}
|
||||
return estimationAccuracyData;
|
||||
}
|
||||
|
||||
public String[] getTicks() {
|
||||
Set<Interval> intervals = getData().keySet();
|
||||
String[] result = new String[intervals.size()];
|
||||
int i = 0;
|
||||
for (Interval each : intervals) {
|
||||
result[i++] = each.toString();
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Collection<Integer> getValues() {
|
||||
return getData().values();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
/**
|
||||
* Model for UI operations related to Order Dashboard View
|
||||
*
|
||||
*
|
||||
* @author Nacho Barrientos <nacho@igalia.com>
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
|
|
@ -383,9 +383,70 @@ public class DashboardModel implements IDashboardModel {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Calculates the estimation accuracy deviations for the current order
|
||||
*
|
||||
* All the deviations are groups in Interval.MAX_INTERVALS intervals of
|
||||
* equal size. If the order contains just one single task then, the upper
|
||||
* limit will be the deviation of the task + 30, and the lower limit will be
|
||||
* deviation of the task - 20
|
||||
*
|
||||
* Each {@link Interval} contains the number of tasks that fit in that
|
||||
* interval
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<Interval, Integer> calculateEstimationAccuracy() {
|
||||
final Integer one = Integer.valueOf(1);
|
||||
Map<Interval, Integer> result = new LinkedHashMap<Interval, Integer>();
|
||||
Double max, min;
|
||||
|
||||
// Get deviations of finished tasks, calculate max, min and delta
|
||||
List<Double> deviations = getEstimationAccuracyDeviations();
|
||||
if (deviations.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
if (deviations.size() == 1) {
|
||||
max = deviations.get(0).doubleValue() + 30;
|
||||
min = deviations.get(0).doubleValue() - 20;
|
||||
} else {
|
||||
max = Collections.max(deviations);
|
||||
min = Collections.min(deviations);
|
||||
}
|
||||
double delta = (max - min) / Interval.MAX_INTERVALS;
|
||||
|
||||
// Create MAX_INTERVALS
|
||||
double from = min;
|
||||
for (int i = 0; i < Interval.MAX_INTERVALS; i++) {
|
||||
result.put(Interval.create(from, from + delta), Integer.valueOf(0));
|
||||
from = from + delta;
|
||||
}
|
||||
|
||||
// Construct map with number of tasks for each interval
|
||||
final Set<Interval> intervals = result.keySet();
|
||||
for (Double each : deviations) {
|
||||
Interval interval = Interval.containingValue(intervals, each);
|
||||
if (interval != null) {
|
||||
Integer value = result.get(interval);
|
||||
result.put(interval, value + one);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Double> getEstimationAccuracyDeviations() {
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
CalculateFinishedTasksEstimationDeviationVisitor visitor = new CalculateFinishedTasksEstimationDeviationVisitor();
|
||||
TaskElement rootTask = getRootTask();
|
||||
rootTask.acceptVisitor(visitor);
|
||||
return visitor.getDeviations();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino García<dpino@igalia.com>
|
||||
*
|
||||
*
|
||||
*/
|
||||
static class Interval {
|
||||
|
||||
|
|
|
|||
|
|
@ -77,4 +77,6 @@ interface IDashboardModel {
|
|||
|
||||
Map<Interval, Integer> calculateTaskCompletation();
|
||||
|
||||
Map<Interval, Integer> calculateEstimationAccuracy();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,14 @@
|
|||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<!-- Resources -->
|
||||
<groupbox closable="false">
|
||||
<caption label="${i18n:_('Resources')}" />
|
||||
<hbox>
|
||||
<n:div id="estimation-accuracy" style="height:200px; width:580px;"></n:div>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="projectDashboardNoTasksWarningDiv" visible="false">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue