Handle projects with no tasks in a nicer way.
Now charts are hidden if the project still has no tasks and a warning message is shown instead, telling the user why charts are not being loaded. FEA: ItEr75S27PerProjectDashboard
This commit is contained in:
parent
b478d4c3e6
commit
0ff16a4f7f
3 changed files with 74 additions and 28 deletions
|
|
@ -36,6 +36,7 @@ import org.springframework.stereotype.Component;
|
|||
import org.zkoss.zk.ui.util.GenericForwardComposer;
|
||||
import org.zkoss.zul.CategoryModel;
|
||||
import org.zkoss.zul.Chart;
|
||||
import org.zkoss.zul.Label;
|
||||
import org.zkoss.zul.PieModel;
|
||||
import org.zkoss.zul.SimpleCategoryModel;
|
||||
import org.zkoss.zul.SimplePieModel;
|
||||
|
|
@ -63,6 +64,8 @@ public class DashboardController extends GenericForwardComposer {
|
|||
private Chart timeKPIEstimationAccuracyChart;
|
||||
private Chart timeKPILagInTaskCompletionChart;
|
||||
|
||||
private Label noTasksWarningLabel;
|
||||
|
||||
public DashboardController() {
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +82,11 @@ public class DashboardController extends GenericForwardComposer {
|
|||
|
||||
public void reload() {
|
||||
dashboardModel.setCurrentOrder(order);
|
||||
this.reloadCharts();
|
||||
if(dashboardModel.tasksAvailable()) {
|
||||
this.reloadCharts();
|
||||
} else {
|
||||
this.hideChartsAndShowWarningMessage();
|
||||
}
|
||||
if (this.dashboardWindow != null) {
|
||||
Util.reloadBindings(this.dashboardWindow);
|
||||
}
|
||||
|
|
@ -94,6 +101,16 @@ public class DashboardController extends GenericForwardComposer {
|
|||
generateTimeKPILagInTaskCompletionChart();
|
||||
}
|
||||
|
||||
private void hideChartsAndShowWarningMessage() {
|
||||
progressKPIglobalProgressChart.setVisible(false);
|
||||
progressKPItaskStatusChart.setVisible(false);
|
||||
progressKPItaskDeadlineViolationStatusChart.setVisible(false);
|
||||
timeKPImarginWithDeadlineChart.setVisible(false);
|
||||
timeKPIEstimationAccuracyChart.setVisible(false);
|
||||
timeKPILagInTaskCompletionChart.setVisible(false);
|
||||
noTasksWarningLabel.setVisible(true);
|
||||
}
|
||||
|
||||
private void generateTimeKPILagInTaskCompletionChart() {
|
||||
CategoryModel categoryModel;
|
||||
categoryModel = refreshTimeKPILagInTaskCompletionCategoryModel();
|
||||
|
|
@ -119,6 +136,10 @@ public class DashboardController extends GenericForwardComposer {
|
|||
private void generateTimeKPImarginWithDeadlineChart() {
|
||||
CategoryModel categoryModel;
|
||||
categoryModel = refreshTimeKPImarginWithDeadlineCategoryModel();
|
||||
if (categoryModel == null) { // Project has no deadline set.
|
||||
timeKPImarginWithDeadlineChart.setVisible(false);
|
||||
return;
|
||||
}
|
||||
timeKPImarginWithDeadlineChart.setAttribute("range-axis-lower-bound",
|
||||
new Double(-3.0));
|
||||
timeKPImarginWithDeadlineChart.setAttribute("range-axis-upper-bound",
|
||||
|
|
@ -189,9 +210,12 @@ public class DashboardController extends GenericForwardComposer {
|
|||
}
|
||||
|
||||
private CategoryModel refreshTimeKPImarginWithDeadlineCategoryModel() {
|
||||
CategoryModel result = new SimpleCategoryModel();
|
||||
result.setValue(_("None"), _("Deviation"),
|
||||
dashboardModel.getMarginWithDeadLine());
|
||||
CategoryModel result = null;
|
||||
BigDecimal marginWithDeadLine = dashboardModel.getMarginWithDeadLine();
|
||||
if (marginWithDeadLine != null) {
|
||||
result = new SimpleCategoryModel();
|
||||
result.setValue(_("None"), _("Deviation"), marginWithDeadLine);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,11 +82,13 @@ public class DashboardModel {
|
|||
public void setCurrentOrder(Order order) {
|
||||
this.currentOrder = order;
|
||||
this.taskCount = null;
|
||||
this.calculateTaskStatusStatistics();
|
||||
this.calculateTaskViolationStatusStatistics();
|
||||
this.calculateMarginWithDeadLine();
|
||||
this.calculateFinishedTasksEstimationAccuracyHistogram();
|
||||
this.calculateLagInTaskCompletionHistogram();
|
||||
if(tasksAvailable()) {
|
||||
this.calculateTaskStatusStatistics();
|
||||
this.calculateTaskViolationStatusStatistics();
|
||||
this.calculateMarginWithDeadLine();
|
||||
this.calculateFinishedTasksEstimationAccuracyHistogram();
|
||||
this.calculateLagInTaskCompletionHistogram();
|
||||
}
|
||||
}
|
||||
|
||||
/* Progress KPI: "Number of tasks by status" */
|
||||
|
|
@ -122,8 +124,8 @@ public class DashboardModel {
|
|||
/* Progress KPI: "Global Progress of the Project" */
|
||||
public BigDecimal getAdvancePercentageByHours(){
|
||||
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
|
||||
if (rootAsTaskGroup == null) {
|
||||
return BigDecimal.ZERO;
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
BigDecimal ratio = rootAsTaskGroup.getProgressAllByNumHours();
|
||||
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
|
||||
|
|
@ -131,8 +133,8 @@ public class DashboardModel {
|
|||
|
||||
public BigDecimal getTheoreticalAdvancePercentageByHoursUntilNow(){
|
||||
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
|
||||
if (rootAsTaskGroup == null) {
|
||||
return BigDecimal.ZERO;
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
BigDecimal ratio = rootAsTaskGroup.getTheoreticalProgressByNumHoursForAllTasksUntilNow();
|
||||
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
|
||||
|
|
@ -140,8 +142,8 @@ public class DashboardModel {
|
|||
|
||||
public BigDecimal getCriticalPathProgressByNumHours() {
|
||||
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
|
||||
if (rootAsTaskGroup == null) {
|
||||
return BigDecimal.ZERO;
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
BigDecimal ratio = rootAsTaskGroup.getCriticalPathProgressByNumHours();
|
||||
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
|
||||
|
|
@ -149,8 +151,8 @@ public class DashboardModel {
|
|||
|
||||
public BigDecimal getTheoreticalProgressByNumHoursForCriticalPathUntilNow() {
|
||||
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
|
||||
if (rootAsTaskGroup == null) {
|
||||
return BigDecimal.ZERO;
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
BigDecimal ratio = rootAsTaskGroup.getTheoreticalProgressByNumHoursForCriticalPathUntilNow();
|
||||
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
|
||||
|
|
@ -158,8 +160,8 @@ public class DashboardModel {
|
|||
|
||||
public BigDecimal getCriticalPathProgressByDuration() {
|
||||
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
|
||||
if (rootAsTaskGroup == null) {
|
||||
return BigDecimal.ZERO;
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
BigDecimal ratio = rootAsTaskGroup.getCriticalPathProgressByDuration();
|
||||
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
|
||||
|
|
@ -167,8 +169,8 @@ public class DashboardModel {
|
|||
|
||||
public BigDecimal getTheoreticalProgressByDurationForCriticalPathUntilNow() {
|
||||
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
|
||||
if (rootAsTaskGroup == null) {
|
||||
return BigDecimal.ZERO;
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
BigDecimal ratio = rootAsTaskGroup.getTheoreticalProgressByDurationForCriticalPathUntilNow();
|
||||
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
|
||||
|
|
@ -180,9 +182,12 @@ public class DashboardModel {
|
|||
}
|
||||
|
||||
private void calculateMarginWithDeadLine() {
|
||||
if (this.currentOrder.getDeadline() == null ||
|
||||
this.getRootTask() == null) {
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
if (this.currentOrder.getDeadline() == null) {
|
||||
this.marginWithDeadLine = null;
|
||||
return;
|
||||
}
|
||||
TaskElement rootTask = getRootTask();
|
||||
Days orderDuration = Days.daysBetween(rootTask.getStartAsLocalDate(),
|
||||
|
|
@ -206,6 +211,9 @@ public class DashboardModel {
|
|||
}
|
||||
|
||||
private void calculateFinishedTasksEstimationAccuracyHistogram() {
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
CalculateFinishedTasksEstimationDeviationVisitor visitor =
|
||||
new CalculateFinishedTasksEstimationDeviationVisitor();
|
||||
TaskElement rootTask = getRootTask();
|
||||
|
|
@ -226,6 +234,9 @@ public class DashboardModel {
|
|||
}
|
||||
|
||||
private void calculateLagInTaskCompletionHistogram() {
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
CalculateFinishedTasksLagInCompletionVisitor visitor =
|
||||
new CalculateFinishedTasksLagInCompletionVisitor();
|
||||
TaskElement rootTask = getRootTask();
|
||||
|
|
@ -277,10 +288,11 @@ public class DashboardModel {
|
|||
private void calculateTaskStatusStatistics() {
|
||||
AccumulateTasksStatusVisitor visitor = new AccumulateTasksStatusVisitor();
|
||||
TaskElement rootTask = getRootTask();
|
||||
if (rootTask != null) {
|
||||
resetTasksStatusInGraph();
|
||||
rootTask.acceptVisitor(visitor);
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
resetTasksStatusInGraph();
|
||||
rootTask.acceptVisitor(visitor);
|
||||
Map<TaskStatusEnum, Integer> count = visitor.getTaskStatusData();
|
||||
mapAbsoluteValuesToPercentages(count, taskStatusStats);
|
||||
}
|
||||
|
|
@ -288,9 +300,10 @@ public class DashboardModel {
|
|||
private void calculateTaskViolationStatusStatistics() {
|
||||
AccumulateTasksDeadlineStatusVisitor visitor = new AccumulateTasksDeadlineStatusVisitor();
|
||||
TaskElement rootTask = getRootTask();
|
||||
if (rootTask != null) {
|
||||
rootTask.acceptVisitor(visitor);
|
||||
if (this.getRootTask() == null) {
|
||||
throw new RuntimeException("Root task is null");
|
||||
}
|
||||
rootTask.acceptVisitor(visitor);
|
||||
Map<TaskDeadlineViolationStatusEnum, Integer> count = visitor.getTaskDeadlineViolationStatusData();
|
||||
mapAbsoluteValuesToPercentages(count, taskDeadlineViolationStatusStats);
|
||||
}
|
||||
|
|
@ -336,4 +349,8 @@ public class DashboardModel {
|
|||
return sum;
|
||||
}
|
||||
|
||||
public boolean tasksAvailable() {
|
||||
return getRootTask() != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@
|
|||
title="${i18n:_('Margin with deadline')}"
|
||||
paneColor="#FFFFFF" showLegend="false" />
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label id="noTasksWarningLabel"
|
||||
value="${i18n:_('No tasks available yet')}"
|
||||
visible="false"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</window>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue