diff --git a/src/org/april/agirstatool/core/AgirStatoolUtils.java b/src/org/april/agirstatool/core/AgirStatoolUtils.java index ecfc59e..fbf41f0 100644 --- a/src/org/april/agirstatool/core/AgirStatoolUtils.java +++ b/src/org/april/agirstatool/core/AgirStatoolUtils.java @@ -198,6 +198,42 @@ public class AgirStatoolUtils return result; } + /** + * Builds the week median ages. + * + * @param project + * the project + * @param start + * the start + * @param end + * the end + * @return the string list + */ + public static StringList buildWeekMedianAges(final Project project, final LocalDate start, final LocalDate end) + { + StringList result; + + result = new StringList(); + + if (start != null) + { + LocalDate date = AgirStatoolUtils.normaliseWeekDate(start); + LocalDate normalizedEnd = AgirStatoolUtils.normaliseWeekDate(end); + while (date.isBefore(normalizedEnd) || date.isEqual(normalizedEnd)) + { + double stat = project.issues().extractActivedAt(date).computeMedian(date); + + result.add(String.valueOf(stat)); + + // + date = date.plusWeeks(1); + } + } + + // + return result; + } + /** * Builds the week min ages. * diff --git a/src/org/april/agirstatool/core/Issues.java b/src/org/april/agirstatool/core/Issues.java index 941ee88..2646f7e 100644 --- a/src/org/april/agirstatool/core/Issues.java +++ b/src/org/april/agirstatool/core/Issues.java @@ -47,6 +47,30 @@ public class Issues extends ArrayList super(capacity); } + /** + * Compute median. + * + * @param date + * the date + * @return the double + */ + public double computeMedian(final LocalDate date) + { + double result; + + LongList values = new LongList(); + for (Issue issue : this) + { + int age = issue.getAgeInDays(date); + values.add(Long.valueOf(age)); + } + + result = values.median(); + + // + return result; + } + /** * Compute stat. * diff --git a/src/org/april/agirstatool/core/LongList.java b/src/org/april/agirstatool/core/LongList.java new file mode 100644 index 0000000..d24e27f --- /dev/null +++ b/src/org/april/agirstatool/core/LongList.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2021 Christian Pierre MOMON + * + * This file is part of AgirStatool, simple key value database. + * + * AgirStatool 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. + * + * AgirStatool 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 AgirStatool. If not, see . + */ +package org.april.agirstatool.core; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * The Class LongList. + */ +public class LongList extends ArrayList +{ + private static final long serialVersionUID = 2724688980125113107L; + + /** + * Instantiates a new stat. + */ + public LongList() + { + super(); + } + + /** + * Median. + * + * @return the double + */ + public double median() + { + double result; + + sort(); + + if (this.isEmpty()) + { + result = 0; + } + else if (this.size() % 2 == 0) + { + long a = get(this.size() / 2 - 1); + long b = get(this.size() / 2); + result = (a + b) / 2; + } + else + { + result = get(this.size() / 2); + } + + // + return result; + } + + /** + * Sort. + */ + public void sort() + { + Collections.sort(this); + } +} diff --git a/src/org/april/agirstatool/core/pages/IssueAgeChartView.java b/src/org/april/agirstatool/core/pages/IssueAgeChartView.java index 41815ac..8304812 100644 --- a/src/org/april/agirstatool/core/pages/IssueAgeChartView.java +++ b/src/org/april/agirstatool/core/pages/IssueAgeChartView.java @@ -78,6 +78,9 @@ public class IssueAgeChartView values = AgirStatoolUtils.buildWeekMaxAges(project, start, end); code = code.replaceAll("data : \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values)); + values = AgirStatoolUtils.buildWeekMedianAges(project, start, end); + code = code.replaceAll("data : \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values)); + result = code.toString(); } else diff --git a/src/org/april/agirstatool/core/pages/issueAgeChartView.xhtml b/src/org/april/agirstatool/core/pages/issueAgeChartView.xhtml index ad13e7c..c45cba3 100644 --- a/src/org/april/agirstatool/core/pages/issueAgeChartView.xhtml +++ b/src/org/april/agirstatool/core/pages/issueAgeChartView.xhtml @@ -38,12 +38,23 @@ var myChart = new Chart(ctx, backgroundColor: 'rgba(75, 192, 192, 0.2)', borderColor: 'rgba(75, 192, 192, 1)', borderWidth: 1, - fill: +2, + fill: +3, cubicInterpolationMode: 'monotone', lineTension: 0, pointBorderWidth: 0.00000001, data : [1, 5, 9, 13, 15, 22], }, + { + label: 'median', + backgroundColor: 'rgba(54, 162, 235, 0.2)', + borderColor: 'rgba(54, 162, 235, 1)', + borderWidth: 1, + fill: false, + cubicInterpolationMode: 'monotone', + lineTension: 0, + pointBorderWidth: 0.00000001, + data : [1, 5, 9, 13, 15, 22], + }, { label: 'max', backgroundColor: 'rgba(153, 102, 255, 0.2)', @@ -55,7 +66,7 @@ var myChart = new Chart(ctx, pointBorderWidth: 0.00000001, data : [1, 5, 9, 13, 15, 22], } - ] + ] }, options: { diff --git a/src/org/april/agirstatool/core/pages/project.xhtml b/src/org/april/agirstatool/core/pages/project.xhtml index 512b2f7..91e639d 100644 --- a/src/org/april/agirstatool/core/pages/project.xhtml +++ b/src/org/april/agirstatool/core/pages/project.xhtml @@ -81,7 +81,7 @@
CREATED/CLOSED CHART MINI
CREATED-CLOSED CHART MINI
-
CREATED-CLOSED MONTHS CHART MINI
+
CREATED-CLOSED MONTHS CHART MINI