Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
62b95f1ccf | |||
43a21307d3 | |||
349a378f46 | |||
c4d466bf54 | |||
10bc11baf4 | |||
4c28fe2dc7 | |||
292b33d126 | |||
a2f50008a5 | |||
79703f2fd7 | |||
a057a40b56 | |||
a68e01bf19 | |||
5c95e5e3ae | |||
419b765c21 | |||
9e40534df6 | |||
380b368538 | |||
5d71a64ead | |||
37576413f8 | |||
6b046b3c03 | |||
428800b856 | |||
a1e35e5df9 | |||
924b865624 | |||
928c902aef | |||
afa45130a4 | |||
90ea99494a | |||
73199d704a | |||
c1035161db | |||
a7612aae3d | |||
c7d1381d9b | |||
394b8fd17d | |||
81b45bb45d | |||
d5d189a0be | |||
0300e19c82 | |||
8d177e5f35 | |||
0f58eccab9 |
14
.classpath
14
.classpath
|
@ -8,19 +8,19 @@
|
|||
<classpathentry kind="lib" path="lib/Logs/log4j-1.2.17.jar" sourcepath="lib/Logs/log4j-1.2.17-source.zip"/>
|
||||
<classpathentry kind="lib" path="lib/UnitTesting/hamcrest-core-1.3.jar" sourcepath="lib/UnitTesting/hamcrest-core-1.3-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/hsqldb-2.3.0.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="owner.project.facets" value="java"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="lib/Logs/slf4j-api-1.7.25.jar" sourcepath="lib/Logs/slf4j-api-1.7.25-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/Logs/slf4j-log4j12-1.7.25.jar" sourcepath="lib/Logs/slf4j-log4j12-1.7.25-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/UnitTesting/junit-4.12.jar" sourcepath="lib/UnitTesting/junit-4.12-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-io-2.6.jar" sourcepath="lib/commons-io-2.6-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/commons-lang3-3.7.jar" sourcepath="lib/commons-lang3-3.7-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/devinsy-strings-0.8.2.jar" sourcepath="lib/devinsy-strings-0.8.2-sources.zip"/>
|
||||
<classpathentry kind="lib" path="lib/devinsy-xml-0.8.2.jar" sourcepath="lib/devinsy-xml-0.8.2-sources.zip"/>
|
||||
<classpathentry kind="lib" path="lib/xidyn-1.8.2.jar" sourcepath="lib/xidyn-1.8.2-sources.zip"/>
|
||||
<classpathentry kind="lib" path="lib/commons-cli-1.4.jar" sourcepath="lib/commons-cli-1.4-sources.jar"/>
|
||||
<classpathentry kind="lib" path="lib/devinsy-strings-0.11.0.jar" sourcepath="lib/devinsy-strings-0.11.0-sources.zip"/>
|
||||
<classpathentry kind="lib" path="lib/devinsy-xml-0.8.2.jar" sourcepath="lib/devinsy-xml-0.8.2-sources.zip"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="owner.project.facets" value="java"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=11
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.release=enabled
|
||||
org.eclipse.jdt.core.compiler.source=11
|
||||
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
|
@ -18,20 +22,23 @@ org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_c
|
|||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=49
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
|
@ -121,11 +128,12 @@ org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
|||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
|
@ -156,6 +164,8 @@ org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
|||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
|
@ -180,13 +190,17 @@ org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
|||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
|
@ -234,6 +248,8 @@ org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do no
|
|||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
|
@ -270,9 +286,12 @@ org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not inser
|
|||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
|
@ -308,9 +327,13 @@ org.eclipse.jdt.core.formatter.tabulation.char=tab
|
|||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=false
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
<fixed facet="java"/>
|
||||
<fixed facet="jst.utility"/>
|
||||
<installed facet="jst.utility" version="1.0"/>
|
||||
<installed facet="java" version="1.8"/>
|
||||
<installed facet="java" version="11"/>
|
||||
</faceted-project>
|
||||
|
|
15
README.md
15
README.md
|
@ -1,25 +1,26 @@
|
|||
# Welcome
|
||||
# AgirStatool
|
||||
|
||||
AgirStatool is a simple statistic tool software for Redmine.
|
||||
|
||||
|
||||
# LICENSE
|
||||
## LICENSE
|
||||
|
||||
AgirStatool is released under the GNU AGPL license. Enjoy!
|
||||
AgirStatool is released under the GNU AGPL+ license. Enjoy!
|
||||
|
||||
# AUTHOR
|
||||
## AUTHOR
|
||||
|
||||
Christian Pierre MOMON <christian.momon@devinsy.fr>
|
||||
|
||||
# Developer install
|
||||
## Developer install
|
||||
|
||||
TODO
|
||||
|
||||
## Unit test environment
|
||||
### Unit test environment
|
||||
For unit tests, install the TestNG:
|
||||
* https://marketplace.eclipse.org/content/testng-eclipse
|
||||
* Eclipse menu > Help > Eclipse Marketplace > Find "TestNG" > TestNG for Eclipse: Install button
|
||||
|
||||
# LOGO
|
||||
## LOGO
|
||||
Author: Christian Pierre MOMON <christian.momon@devinsy.fr>
|
||||
|
||||
License: Creative Commons CC-BY-SA last version.
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#Build Number for ANT. Do not edit!
|
||||
#Wed Feb 05 18:54:17 CET 2020
|
||||
build.number=27
|
||||
#Sat May 08 22:44:18 CEST 2021
|
||||
build.number=5
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
product.name=agirstatool
|
||||
product.revision.major=0
|
||||
product.revision.minor=0
|
||||
product.revision.minor=11
|
||||
|
|
18
build.sh
18
build.sh
|
@ -41,11 +41,11 @@ function build_snapshot
|
|||
|
||||
# Java version check.
|
||||
javaVersionCheck=`javac -version 2>&1`
|
||||
if [[ "$javaVersionCheck" =~ ^.*\ 1.8 ]]; then
|
||||
echo "Java 8 version requirement..... OK"
|
||||
if [[ "$javaVersionCheck" =~ ^.*\ 11\. ]]; then
|
||||
echo "Java 11 version requirement..... OK"
|
||||
let "okCount+=1"
|
||||
else
|
||||
echo "Java 8 version requirement..... MISSING"
|
||||
echo "Java 11 version requirement..... MISSING"
|
||||
fi
|
||||
|
||||
if [ "$okCount" == 3 ]; then
|
||||
|
@ -83,11 +83,11 @@ function build_local
|
|||
|
||||
# Java version check.
|
||||
javaVersionCheck=`javac -version 2>&1`
|
||||
if [[ "$javaVersionCheck" =~ ^.*\ 1.8 ]]; then
|
||||
echo "Java 8 version requirement..... OK"
|
||||
if [[ "$javaVersionCheck" =~ ^.*\ 11\. ]]; then
|
||||
echo "Java 11 version requirement..... OK"
|
||||
let "okCount+=1"
|
||||
else
|
||||
echo "Java 8 version requirement..... MISSING"
|
||||
echo "Java 11 version requirement..... MISSING"
|
||||
fi
|
||||
|
||||
if [ "$okCount" == 3 ]; then
|
||||
|
@ -125,11 +125,11 @@ function build_tagandpush
|
|||
|
||||
# Java version check.
|
||||
javaVersionCheck=`javac -version 2>&1`
|
||||
if [[ "$javaVersionCheck" =~ ^.*\ 1.8 ]]; then
|
||||
echo "Java 8 version requirement..... OK"
|
||||
if [[ "$javaVersionCheck" =~ ^.*\ 11\. ]]; then
|
||||
echo "Java 11 version requirement..... OK"
|
||||
let "okCount+=1"
|
||||
else
|
||||
echo "Java 8 version requirement..... MISSING"
|
||||
echo "Java 11 version requirement..... MISSING"
|
||||
fi
|
||||
|
||||
# Git check.
|
||||
|
|
BIN
lib/devinsy-strings-0.11.0-sources.zip
Normal file
BIN
lib/devinsy-strings-0.11.0-sources.zip
Normal file
Binary file not shown.
BIN
lib/devinsy-strings-0.11.0.jar
Normal file
BIN
lib/devinsy-strings-0.11.0.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -211,6 +211,7 @@ public class AgirStatool
|
|||
FileUtils.copyURLToFile(AgirStatool.class.getResource("/org/april/agirstatool/core/pages/index.html"), new File(this.targetDirectory, "index.html"));
|
||||
FileUtils.copyURLToFile(AgirStatool.class.getResource("/org/april/agirstatool/core/pages/agirstatool.css"), new File(this.targetDirectory, "agirstatool.css"));
|
||||
FileUtils.copyURLToFile(AgirStatool.class.getResource("/org/april/agirstatool/core/pages/Chart.bundle.min.js"), new File(this.targetDirectory, "Chart.bundle.min.js"));
|
||||
FileUtils.copyURLToFile(AgirStatool.class.getResource("/org/april/agirstatool/core/pages/about.xhtml"), new File(this.targetDirectory, "about.xhtml"));
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -245,7 +246,7 @@ public class AgirStatool
|
|||
* @throws AgirStatoolException
|
||||
* the agir statool exception
|
||||
*/
|
||||
public Issues fetchIssue(final Project project) throws AgirStatoolException
|
||||
public Issues fetchIssues(final Project project) throws AgirStatoolException
|
||||
{
|
||||
Issues result;
|
||||
|
||||
|
@ -895,7 +896,7 @@ public class AgirStatool
|
|||
// Fill created and concluded issues history.
|
||||
{
|
||||
{
|
||||
Issues issues = fetchIssue(result);
|
||||
Issues issues = fetchIssues(result);
|
||||
result.issues().addAll(issues);
|
||||
}
|
||||
{
|
||||
|
@ -915,7 +916,7 @@ public class AgirStatool
|
|||
if (project.hasIssue())
|
||||
{
|
||||
{
|
||||
Issues issues = fetchIssue(project);
|
||||
Issues issues = fetchIssues(project);
|
||||
project.issues().addAll(issues);
|
||||
}
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.time.LocalDate;
|
|||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -29,7 +30,6 @@ import org.apache.commons.lang3.math.NumberUtils;
|
|||
import org.april.agirstatool.charts.DateCount;
|
||||
import org.april.agirstatool.charts.DateCountList;
|
||||
import org.april.agirstatool.charts.DateCountMap;
|
||||
import org.april.agirstatool.core.pages.ProjectPage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -41,10 +41,10 @@ import fr.devinsy.strings.StringsUtils;
|
|||
*/
|
||||
public class AgirStatoolUtils
|
||||
{
|
||||
private static Logger logger = LoggerFactory.getLogger(ProjectPage.class);
|
||||
private static Logger logger = LoggerFactory.getLogger(AgirStatoolUtils.class);
|
||||
|
||||
public static final DateTimeFormatter PATTERN_SHORTDATE = DateTimeFormatter.ofPattern("dd/MM/yyyy", Locale.FRANCE);
|
||||
public static final DateTimeFormatter PATTERN_LONGDATE = DateTimeFormatter.ofPattern("dd/MM/yyyy hh':'mm", Locale.FRANCE);
|
||||
public static final DateTimeFormatter PATTERN_LONGDATE = DateTimeFormatter.ofPattern("dd/MM/yyyy HH':'mm", Locale.FRANCE);
|
||||
|
||||
public static StringList buildWeekDuration(final Project project, final LocalDate start, final LocalDate end)
|
||||
{
|
||||
|
@ -113,7 +113,10 @@ public class AgirStatoolUtils
|
|||
LocalDate date = AgirStatoolUtils.normaliseWeekDate(start);
|
||||
while (date.isBefore(normalizedEnd) || date.isEqual(normalizedEnd))
|
||||
{
|
||||
String label = date.format(DateTimeFormatter.ofPattern("yyyy-MMM", Locale.FRANCE));
|
||||
// The normalized date is set to the first day of the week.
|
||||
// The displayed date is set to the last day of the week. So
|
||||
// plus 6.
|
||||
String label = date.plusDays(6).format(DateTimeFormatter.ISO_DATE);
|
||||
result.add(label);
|
||||
date = date.plusWeeks(1);
|
||||
}
|
||||
|
@ -142,8 +145,8 @@ public class AgirStatoolUtils
|
|||
|
||||
if (start != null)
|
||||
{
|
||||
LocalDate date = AgirStatoolUtils.normaliseWeekDate(start);
|
||||
LocalDate normalizedEnd = AgirStatoolUtils.normaliseWeekDate(end);
|
||||
LocalDate date = normaliseWeekDate(start).plusDays(6);
|
||||
LocalDate normalizedEnd = normaliseWeekDate(end).plusDays(6);
|
||||
while (date.isBefore(normalizedEnd) || date.isEqual(normalizedEnd))
|
||||
{
|
||||
Stat stat = project.issues().extractActivedAt(date).computeStat(date);
|
||||
|
@ -178,8 +181,8 @@ public class AgirStatoolUtils
|
|||
|
||||
if (start != null)
|
||||
{
|
||||
LocalDate date = AgirStatoolUtils.normaliseWeekDate(start);
|
||||
LocalDate normalizedEnd = AgirStatoolUtils.normaliseWeekDate(end);
|
||||
LocalDate date = normaliseWeekDate(start).plusDays(6);
|
||||
LocalDate normalizedEnd = normaliseWeekDate(end).plusDays(6);
|
||||
while (date.isBefore(normalizedEnd) || date.isEqual(normalizedEnd))
|
||||
{
|
||||
Stat stat = project.issues().extractActivedAt(date).computeStat(date);
|
||||
|
@ -195,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 = normaliseWeekDate(start).plusDays(6);
|
||||
LocalDate normalizedEnd = normaliseWeekDate(end).plusDays(6);
|
||||
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.
|
||||
*
|
||||
|
@ -214,8 +253,8 @@ public class AgirStatoolUtils
|
|||
|
||||
if (start != null)
|
||||
{
|
||||
LocalDate date = AgirStatoolUtils.normaliseWeekDate(start);
|
||||
LocalDate normalizedEnd = AgirStatoolUtils.normaliseWeekDate(end);
|
||||
LocalDate date = normaliseWeekDate(start).plusDays(6);
|
||||
LocalDate normalizedEnd = normaliseWeekDate(end).plusDays(6);
|
||||
while (date.isBefore(normalizedEnd) || date.isEqual(normalizedEnd))
|
||||
{
|
||||
Stat stat = project.issues().extractActivedAt(date).computeStat(date);
|
||||
|
@ -530,6 +569,38 @@ public class AgirStatoolUtils
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* To J son numbers.
|
||||
*
|
||||
* @param labels
|
||||
* the labels
|
||||
* @param values
|
||||
* the source
|
||||
* @return the string
|
||||
*/
|
||||
public static String toJSonNumbers(final StringList labels, final StringList values)
|
||||
{
|
||||
String result;
|
||||
|
||||
Iterator<String> labelIterator = labels.iterator();
|
||||
Iterator<String> valueIterator = values.iterator();
|
||||
|
||||
StringList buffer = new StringList();
|
||||
while (labelIterator.hasNext())
|
||||
{
|
||||
String label = labelIterator.next();
|
||||
String value = valueIterator.next();
|
||||
|
||||
// buffer.append("{t: new Date('" + label + "'), y: " + value +
|
||||
// "}");
|
||||
buffer.append("{t: '" + label + "', y: " + value + "}");
|
||||
}
|
||||
result = StringsUtils.toString(buffer, "[", ",", "]");
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* To Json strings.
|
||||
*
|
||||
|
|
|
@ -47,6 +47,30 @@ public class Issues extends ArrayList<Issue>
|
|||
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.
|
||||
*
|
||||
|
|
76
src/org/april/agirstatool/core/LongList.java
Normal file
76
src/org/april/agirstatool/core/LongList.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Christian Pierre MOMON <christian.momon@devinsy.fr>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.april.agirstatool.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* The Class LongList.
|
||||
*/
|
||||
public class LongList extends ArrayList<Long>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -69,15 +69,14 @@ public class CreatedClosedCountChartView
|
|||
code = code.replaceAll("myChart", "myChart_" + DigestUtils.md5Hex(title + "lineChart"));
|
||||
|
||||
StringList labels = AgirStatoolUtils.buildWeekLabels(start, end);
|
||||
code = code.replaceAll("labels: \\[.*\\]", "labels: " + AgirStatoolUtils.toJSonStrings(labels));
|
||||
|
||||
DateCountList dates = project.issueStats().getWeekCreatedIssueCounts();
|
||||
StringList values = AgirStatoolUtils.normalizedWeekCountList(dates, start, end).toValueList();
|
||||
code = code.replaceAll("data: \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(values));
|
||||
code = code.replaceAll("data: \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values));
|
||||
|
||||
dates = project.issueStats().getWeekConcludedIssueCounts();
|
||||
values = AgirStatoolUtils.normalizedWeekCountList(dates, start, end).toValueList();
|
||||
code = code.replaceAll("data: \\[.*\\] ", "data: " + AgirStatoolUtils.toJSonNumbers(values));
|
||||
code = code.replaceAll("data: \\[.*\\] ", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values));
|
||||
|
||||
result = code.toString();
|
||||
}
|
||||
|
@ -122,13 +121,12 @@ public class CreatedClosedCountChartView
|
|||
code = code.replaceAll("myChart", "myChart_" + DigestUtils.md5Hex(title + "lineBar"));
|
||||
|
||||
StringList labels = AgirStatoolUtils.buildWeekLabels(project.issueStats().getFirstCreate().toLocalDate());
|
||||
code = code.replaceAll("labels: \\[.*\\]", "labels: " + AgirStatoolUtils.toJSonStrings(labels));
|
||||
|
||||
StringList values = project.issueStats().getWeekCreatedIssueCounts().toValueList();
|
||||
code = code.replaceAll("data: \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(values));
|
||||
code = code.replaceAll("data: \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values));
|
||||
|
||||
values = project.issueStats().getWeekConcludedIssueCounts().toValueList();
|
||||
code = code.replaceAll("data: \\[.*\\] ", "data: " + AgirStatoolUtils.toJSonNumbers(values));
|
||||
code = code.replaceAll("data: \\[.*\\] ", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values));
|
||||
|
||||
result = code.toString();
|
||||
}
|
||||
|
@ -170,21 +168,23 @@ public class CreatedClosedCountChartView
|
|||
}
|
||||
|
||||
/**
|
||||
* Builds the previous year.
|
||||
* Builds the previous 2 year.
|
||||
*
|
||||
* @param title
|
||||
* the title
|
||||
* @param project
|
||||
* the project
|
||||
* @param yearCount
|
||||
* the year count
|
||||
* @return the string
|
||||
* @throws AgirStatoolException
|
||||
* the agir statool exception
|
||||
*/
|
||||
public static String buildPreviousYear(final String title, final Project project) throws AgirStatoolException
|
||||
public static String buildPreviousYear(final String title, final Project project, final int yearCount) throws AgirStatoolException
|
||||
{
|
||||
String result;
|
||||
|
||||
result = buildYear(title, project, LocalDate.now().getYear() - 1);
|
||||
result = buildYear(title, project, LocalDate.now().getYear() - Math.abs(yearCount));
|
||||
|
||||
//
|
||||
return result;
|
||||
|
|
|
@ -69,9 +69,6 @@ public class CreatedClosedDiffChartView
|
|||
|
||||
code = code.replaceAll("myChart", "myChart_" + DigestUtils.md5Hex(title + "line2Chart"));
|
||||
|
||||
StringList labels = AgirStatoolUtils.buildWeekLabels(start, end);
|
||||
code = code.replaceAll("labels: \\[.*\\]", "labels: " + AgirStatoolUtils.toJSonStrings(labels));
|
||||
|
||||
DateCountList createdDates = project.issueStats().getWeekCreatedIssueCounts();
|
||||
DateCountList closedDates = project.issueStats().getWeekConcludedIssueCounts();
|
||||
DateCountList dates = new DateCountList(createdDates.size());
|
||||
|
@ -82,8 +79,9 @@ public class CreatedClosedDiffChartView
|
|||
dates.add(new DateCount(createdDate.getDate(), createdDate.getCount() - closedDate.getCount()));
|
||||
}
|
||||
|
||||
StringList labels = AgirStatoolUtils.buildWeekLabels(start, end);
|
||||
StringList values = AgirStatoolUtils.normalizedWeekCountList(dates, start, end).toValueList();
|
||||
code = code.replaceAll("data: \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(values));
|
||||
code = code.replaceAll("data: \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values));
|
||||
|
||||
result = code.toString();
|
||||
}
|
||||
|
@ -161,15 +159,17 @@ public class CreatedClosedDiffChartView
|
|||
* the title
|
||||
* @param project
|
||||
* the project
|
||||
* @param yearCount
|
||||
* the year count
|
||||
* @return the string
|
||||
* @throws AgirStatoolException
|
||||
* the agir statool exception
|
||||
*/
|
||||
public static String buildPreviousYear(final String title, final Project project) throws AgirStatoolException
|
||||
public static String buildPreviousYear(final String title, final Project project, final int yearCount) throws AgirStatoolException
|
||||
{
|
||||
String result;
|
||||
|
||||
result = buildYear(title, project, LocalDate.now().getYear() - 1);
|
||||
result = buildYear(title, project, LocalDate.now().getYear() - Math.abs(yearCount));
|
||||
|
||||
//
|
||||
return result;
|
||||
|
|
|
@ -68,16 +68,18 @@ public class IssueAgeChartView
|
|||
code = code.replaceAll("myChart", "myChart_" + DigestUtils.md5Hex(title + "ageStatsChart"));
|
||||
|
||||
StringList labels = AgirStatoolUtils.buildWeekLabels(start, end);
|
||||
code = code.replaceAll("labels: \\[.*\\]", "labels: " + AgirStatoolUtils.toJSonStrings(labels));
|
||||
|
||||
StringList values = AgirStatoolUtils.buildWeekMinAges(project, start, end);
|
||||
code = code.replaceAll("data: \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(values));
|
||||
code = code.replaceAll("data: \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values));
|
||||
|
||||
values = AgirStatoolUtils.buildWeekMeanAges(project, start, end);
|
||||
code = code.replaceAll("data : \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(values));
|
||||
code = code.replaceAll("data : \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(labels, values));
|
||||
|
||||
values = AgirStatoolUtils.buildWeekMaxAges(project, start, end);
|
||||
code = code.replaceAll("data : \\[.*\\]", "data: " + AgirStatoolUtils.toJSonNumbers(values));
|
||||
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();
|
||||
}
|
||||
|
@ -155,15 +157,17 @@ public class IssueAgeChartView
|
|||
* the title
|
||||
* @param project
|
||||
* the project
|
||||
* @param yearCount
|
||||
* the year count
|
||||
* @return the string
|
||||
* @throws AgirStatoolException
|
||||
* the agir statool exception
|
||||
*/
|
||||
public static String buildPreviousYear(final String title, final Project project) throws AgirStatoolException
|
||||
public static String buildPreviousYear(final String title, final Project project, final int yearCount) throws AgirStatoolException
|
||||
{
|
||||
String result;
|
||||
|
||||
result = buildYear(title, project, LocalDate.now().getYear() - 1);
|
||||
result = buildYear(title, project, LocalDate.now().getYear() - Math.abs(yearCount));
|
||||
|
||||
//
|
||||
return result;
|
||||
|
|
|
@ -38,34 +38,6 @@ public class IssueStatusChartView
|
|||
{
|
||||
private static Logger logger = LoggerFactory.getLogger(IssueStatusChartView.class);
|
||||
|
||||
/**
|
||||
* Builds the grouped.
|
||||
*
|
||||
* @param title
|
||||
* the title
|
||||
* @param project
|
||||
* the project
|
||||
* @return the string
|
||||
* @throws AgirStatoolException
|
||||
* the agir statool exception
|
||||
*/
|
||||
public static String buildGrouped(final String title, final Project project) throws AgirStatoolException
|
||||
{
|
||||
String result;
|
||||
|
||||
StringList labels = new StringList("Maybe", "Active", "Resolved");
|
||||
StringList values = new StringList();
|
||||
values.append(project.issueStats().getMaybeCount());
|
||||
values.append(project.issueStats().getActiveCount());
|
||||
values.append(project.issueStats().getResolvedCount());
|
||||
|
||||
String targetTitle = title + " – " + project.getName();
|
||||
result = build(targetTitle, targetTitle, labels, values);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the.
|
||||
*
|
||||
|
@ -80,7 +52,7 @@ public class IssueStatusChartView
|
|||
public static String build(final String title, final Project project) throws AgirStatoolException
|
||||
{
|
||||
String result;
|
||||
|
||||
|
||||
StringList labels = new StringList("Maybe", "New", "Confirmed", "Ongoing", "Waiting", "Resolved");
|
||||
StringList values = new StringList();
|
||||
values.append(project.issueStats().getMaybeCount());
|
||||
|
@ -89,10 +61,9 @@ public class IssueStatusChartView
|
|||
values.append(project.issueStats().getOngoingCount());
|
||||
values.append(project.issueStats().getWaitingCount());
|
||||
values.append(project.issueStats().getResolvedCount());
|
||||
|
||||
String targetTitle = title + " – " + project.getName();
|
||||
result = build(targetTitle, targetTitle, labels, values);
|
||||
|
||||
|
||||
result = build(title, title, labels, values);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
|
@ -136,4 +107,31 @@ public class IssueStatusChartView
|
|||
//
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the grouped.
|
||||
*
|
||||
* @param title
|
||||
* the title
|
||||
* @param project
|
||||
* the project
|
||||
* @return the string
|
||||
* @throws AgirStatoolException
|
||||
* the agir statool exception
|
||||
*/
|
||||
public static String buildGrouped(final String title, final Project project) throws AgirStatoolException
|
||||
{
|
||||
String result;
|
||||
|
||||
StringList labels = new StringList("Maybe", "Active", "Resolved");
|
||||
StringList values = new StringList();
|
||||
values.append(project.issueStats().getMaybeCount());
|
||||
values.append(project.issueStats().getActiveCount());
|
||||
values.append(project.issueStats().getResolvedCount());
|
||||
|
||||
result = build(title, title, labels, values);
|
||||
|
||||
//
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
package org.april.agirstatool.core.pages;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.april.agirstatool.core.AgirStatoolException;
|
||||
import org.april.agirstatool.core.Project;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -58,10 +62,22 @@ public class ProjectPage
|
|||
|
||||
TagDataManager data = new TagDataManager();
|
||||
|
||||
data.setContent("agirLink", project.getName());
|
||||
data.setAttribute("agirLink", "href", "https://agir.april.org/projects/" + project.getIdentifier() + "/issues");
|
||||
data.setContent("projectName", "Project " + project.getName());
|
||||
data.setAttribute("projectName", "href", project.getPath());
|
||||
if (StringUtils.equals(project.getIdentifier(), "all"))
|
||||
{
|
||||
data.setAttribute("agirLink", "href", "https://agir.april.org/issues");
|
||||
}
|
||||
else
|
||||
{
|
||||
data.setAttribute("agirLink", "href", "https://agir.april.org/projects/" + project.getIdentifier() + "/issues");
|
||||
}
|
||||
data.setContent("versionsup", BuildInformation.instance().version());
|
||||
|
||||
data.setContent("lastUpdateDate", LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH':'mm", Locale.FRANCE)));
|
||||
|
||||
data.setContent("createClosePrevious3YearButton", LocalDate.now().getYear() - 3);
|
||||
data.setContent("createClosePrevious2YearButton", LocalDate.now().getYear() - 2);
|
||||
data.setContent("createClosePreviousYearButton", LocalDate.now().getYear() - 1);
|
||||
data.setContent("createdClosed3MonthsChart", CreatedClosedCountChartView.buildLastMonths("Created/closed 3 months Count", project, 3));
|
||||
data.setContent("created-Closed3MonthsChart", CreatedClosedDiffChartView.buildLastMonths("Created-closed 3 months Count", project, 3));
|
||||
|
@ -72,9 +88,15 @@ public class ProjectPage
|
|||
data.setContent("createdClosed12MonthsChart", CreatedClosedCountChartView.buildLastMonths("Created/closed 12 months Count", project, 12));
|
||||
data.setContent("created-Closed12MonthsChart", CreatedClosedDiffChartView.buildLastMonths("Created-closed 12 months Count", project, 12));
|
||||
data.setContent("age12MonthsChart", IssueAgeChartView.buildLastMonths("Issue Age 12 months", project, 12));
|
||||
data.setContent("createdClosedPreviousYearChart", CreatedClosedCountChartView.buildPreviousYear("Created/closed last year Count", project));
|
||||
data.setContent("created-ClosedPreviousYearChart", CreatedClosedDiffChartView.buildPreviousYear("Created-closed last year Count", project));
|
||||
data.setContent("agePreviousYearChart", IssueAgeChartView.buildPreviousYear("Issue Age Previous Year Chart", project));
|
||||
data.setContent("createdClosedPrevious3YearChart", CreatedClosedCountChartView.buildPreviousYear("Created/closed year-3 Count", project, -3));
|
||||
data.setContent("created-ClosedPrevious3YearChart", CreatedClosedDiffChartView.buildPreviousYear("Created-closed year-3 Count", project, -3));
|
||||
data.setContent("agePrevious3YearChart", IssueAgeChartView.buildPreviousYear("Issue Age Year-3 Chart", project, -3));
|
||||
data.setContent("createdClosedPrevious2YearChart", CreatedClosedCountChartView.buildPreviousYear("Created/closed year-2 Count", project, -2));
|
||||
data.setContent("created-ClosedPrevious2YearChart", CreatedClosedDiffChartView.buildPreviousYear("Created-closed year-2 Count", project, -2));
|
||||
data.setContent("agePrevious2YearChart", IssueAgeChartView.buildPreviousYear("Issue Age Year-2 Chart", project, -2));
|
||||
data.setContent("createdClosedPreviousYearChart", CreatedClosedCountChartView.buildPreviousYear("Created/closed last year Count", project, -1));
|
||||
data.setContent("created-ClosedPreviousYearChart", CreatedClosedDiffChartView.buildPreviousYear("Created-closed last year Count", project, -1));
|
||||
data.setContent("agePreviousYearChart", IssueAgeChartView.buildPreviousYear("Issue Age Previous Year Chart", project, -1));
|
||||
data.setContent("createdClosedFullChart", CreatedClosedCountChartView.buildFull("Created/closed Count", project));
|
||||
data.setContent("created-ClosedFullChart", CreatedClosedDiffChartView.buildFull("Created-closed Count", project));
|
||||
data.setContent("ageFullChart", IssueAgeChartView.buildFull("Issue Age Full Chart", project));
|
||||
|
|
39
src/org/april/agirstatool/core/pages/about.xhtml
Normal file
39
src/org/april/agirstatool/core/pages/about.xhtml
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Agir Statool</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta content="April" name="keywords" />
|
||||
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" type="text/css" href="agirstatool.css" />
|
||||
<script src="/commons/sorttable.js" />
|
||||
<script src="Chart.bundle.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="margin: 5px 10px 10px 10px;">
|
||||
<h1><a href="index.xhtml">Agir Statool</a> – <a id="" href="about.xhtml">About</a></h1>
|
||||
|
||||
<h2>Introduction</h2>
|
||||
<p>AgirStatool is a simple statistic tool software for the April Redmine instance:</p>
|
||||
<ul>
|
||||
<li><a href="https://agir.april.org/">https://agir.april.org/</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Tips</h2>
|
||||
<p>Some tips:</p>
|
||||
<ul>
|
||||
<li>full charts: the default full chart view displays only one chart. To see another full charts, you have to click on it.</li>
|
||||
<li>refresh delay: waiting for an update? Concerned pages are rebuild every 5 minutes.</li>
|
||||
</ul>
|
||||
|
||||
<h2>License and source repository</h2>
|
||||
<p>The original author of AgirStatool is Christian P. MOMON.</p>
|
||||
<p>Agir Statool is a free software released under the GNU AGPL license.</p>
|
||||
<p>The official source repository is the April forge:</p>
|
||||
<ul>
|
||||
<li><a href="https://forge.april.org/adminsys/agirstatool">https://forge.april.org/adminsys/agirstatool</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -20,29 +20,28 @@ var myChart = new Chart(ctx,
|
|||
type: 'line',
|
||||
data:
|
||||
{
|
||||
labels: ['S01', 'S02', 'S03', 'S04', 'S05'],
|
||||
datasets:
|
||||
[
|
||||
{
|
||||
label: 'Created',
|
||||
data: [2, 9, 13, 15, 22, 23],
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
||||
borderColor: 'rgba(255, 99, 132, 1)',
|
||||
borderWidth: 1,
|
||||
fill: true,
|
||||
/* cubicInterpolationMode: 'monotone', */
|
||||
lineTension: 0,
|
||||
pointBorderWidth: 0.00000001
|
||||
pointBorderWidth: 0.00000001,
|
||||
data: [2, 9, 13, 15, 22, 23]
|
||||
},
|
||||
{
|
||||
label: 'Closedᴿ',
|
||||
data: [1, 5, 9, 13, 15, 22] ,
|
||||
backgroundColor: 'rgba(75, 192, 192, 0.2)',
|
||||
borderColor: 'rgba(75, 192, 192, 1)',
|
||||
borderWidth: 1,
|
||||
fill: true,
|
||||
lineTension: 0,
|
||||
pointBorderWidth: 0.00000001
|
||||
pointBorderWidth: 0.00000001,
|
||||
data: [1, 5, 9, 13, 15, 22]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -57,23 +56,36 @@ var myChart = new Chart(ctx,
|
|||
{
|
||||
xAxes:
|
||||
[{
|
||||
ticks:
|
||||
type: 'time',
|
||||
time:
|
||||
{
|
||||
unit: 'month',
|
||||
isoWeekday: true,
|
||||
displayFormats:
|
||||
{
|
||||
beginAtZero: false
|
||||
},
|
||||
gridLines:
|
||||
{
|
||||
offsetGridLines: false
|
||||
month: 'YYYY MMM'
|
||||
}
|
||||
},
|
||||
distribution: 'linear',
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: false,
|
||||
maxTicksLimit: 0
|
||||
},
|
||||
gridLines:
|
||||
{
|
||||
zeroLineColor: 'rgba(0, 0, 0, 0.1)',
|
||||
offsetGridLines: false
|
||||
}
|
||||
}],
|
||||
yAxes:
|
||||
[{
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: false,
|
||||
suggestedMax: 10,
|
||||
precision: 0
|
||||
}
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: false,
|
||||
suggestedMax: 10,
|
||||
precision: 0
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,19 +20,18 @@ var myChart = new Chart(ctx,
|
|||
type: 'line',
|
||||
data:
|
||||
{
|
||||
labels: ['S01', 'S02', 'S03', 'S04', 'S05'],
|
||||
datasets:
|
||||
[
|
||||
{
|
||||
label: 'Active Issues',
|
||||
data: [2, 9, 13, 15, 22, 23],
|
||||
backgroundColor: 'rgba(255, 159, 64, 0.2)',
|
||||
borderColor: 'rgba(255, 159, 64, 1)',
|
||||
borderWidth: 1,
|
||||
fill: true,
|
||||
/* cubicInterpolationMode: 'monotone', */
|
||||
lineTension: 0,
|
||||
pointBorderWidth: 0.00000001
|
||||
pointBorderWidth: 0.00000001,
|
||||
data: [2, 9, 13, 15, 22, 23]
|
||||
},
|
||||
]
|
||||
},
|
||||
|
@ -47,19 +46,34 @@ var myChart = new Chart(ctx,
|
|||
{
|
||||
xAxes:
|
||||
[{
|
||||
ticks:
|
||||
type: 'time',
|
||||
time:
|
||||
{
|
||||
unit: 'month',
|
||||
isoWeekday: true,
|
||||
displayFormats:
|
||||
{
|
||||
beginAtZero: false
|
||||
month: 'YYYY MMM'
|
||||
}
|
||||
},
|
||||
distribution: 'linear',
|
||||
ticks:
|
||||
{
|
||||
},
|
||||
gridLines:
|
||||
{
|
||||
zeroLineColor: 'rgba(0, 0, 0, 0.1)',
|
||||
offsetGridLines: false
|
||||
}
|
||||
}],
|
||||
yAxes:
|
||||
[{
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: false,
|
||||
suggestedMax: 10,
|
||||
precision: 0
|
||||
}
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: false,
|
||||
suggestedMax: 10,
|
||||
precision: 0
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<script src="Chart.bundle.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="width: 100%; height: 100%; text-align: center; margin: 0 0; border: 1px solid red;" title="Active Issues Age">
|
||||
<div style="width: 100%; height: 100%; text-align: center; margin: 0 0; border: 1px solid red;" title="Active Issue Age (in days)">
|
||||
<canvas id="myChart" width="100%" height="100%"></canvas>
|
||||
<script>
|
||||
var ctx = document.getElementById('myChart');
|
||||
|
@ -20,43 +20,53 @@ var myChart = new Chart(ctx,
|
|||
type: 'line',
|
||||
data:
|
||||
{
|
||||
labels: ['S01', 'S02', 'S03', 'S04', 'S05'],
|
||||
datasets:
|
||||
[
|
||||
{
|
||||
label: 'min',
|
||||
data: [2, 9, 13, 15, 22, 23],
|
||||
backgroundColor: 'rgba(255, 99, 132, 0.2)',
|
||||
borderColor: 'rgba(255, 99, 132, 1)',
|
||||
borderWidth: 1,
|
||||
fill: +1,
|
||||
cubicInterpolationMode: 'monotone',
|
||||
lineTension: 0,
|
||||
pointBorderWidth: 0.00000001
|
||||
pointBorderWidth: 0.00000001,
|
||||
data: [2, 9, 13, 15, 22, 23],
|
||||
},
|
||||
{
|
||||
label: 'mean',
|
||||
data : [1, 5, 9, 13, 15, 22],
|
||||
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
|
||||
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',
|
||||
data : [1, 5, 9, 13, 15, 22],
|
||||
backgroundColor: 'rgba(153, 102, 255, 0.2)',
|
||||
borderColor: 'rgba(153, 102, 255, 1)',
|
||||
borderWidth: 1,
|
||||
fill: false,
|
||||
cubicInterpolationMode: 'monotone',
|
||||
lineTension: 0,
|
||||
pointBorderWidth: 0.00000001
|
||||
pointBorderWidth: 0.00000001,
|
||||
data : [1, 5, 9, 13, 15, 22],
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
options:
|
||||
{
|
||||
|
@ -69,10 +79,27 @@ var myChart = new Chart(ctx,
|
|||
{
|
||||
xAxes:
|
||||
[{
|
||||
ticks:
|
||||
type: 'time',
|
||||
time:
|
||||
{
|
||||
unit: 'month',
|
||||
isoWeekday: true,
|
||||
displayFormats:
|
||||
{
|
||||
beginAtZero: false
|
||||
month: 'YYYY MMM'
|
||||
}
|
||||
},
|
||||
distribution: 'linear',
|
||||
ticks:
|
||||
{
|
||||
beginAtZero: false,
|
||||
maxTicksLimit: 0
|
||||
},
|
||||
gridLines:
|
||||
{
|
||||
zeroLineColor: 'rgba(0, 0, 0, 0.1)',
|
||||
offsetGridLines: false
|
||||
}
|
||||
}],
|
||||
yAxes:
|
||||
[{
|
||||
|
|
|
@ -12,20 +12,23 @@
|
|||
</head>
|
||||
<body>
|
||||
<div style="margin: 5px 10px 10px 10px;">
|
||||
<h1><a href="index.xhtml">Agir Statool</a><sup id="versionsup" style="font-size: 9px;">v0.0.14</sup> – Project <a id="agirLink" href="#">n/a</a></h1>
|
||||
<h1><a href="index.xhtml">Agir Statool</a><sup id="versionsup" style="font-size: 9px;">v0.0.14</sup> – <a id="projectName" href="#">n/a</a> – <a id="agirLink" href="#">Link to Agir</a> – <a href="about.xhtml">About</a><span style="font-size: 9px; float: right;">Page updated on<br/><span id="lastUpdateDate" style="font-size: 9px;">xx/xx/xxxx xx:xx</span></span></h1>
|
||||
<div id="mainCharts">
|
||||
<div style="margin: 5px;">
|
||||
<a id="createClose3MonthsButton" href="#" class="button" onclick="javascript:createClosedSelect('3months');">3 months</a>
|
||||
<a id="createClose6MonthsButton" href="#" class="button" onclick="javascript:createClosedSelect('6months');">6 months</a>
|
||||
<a id="createClose12MonthsButton" href="#" class="button selected" onclick="javascript:createClosedSelect('12months');">12 months</a>
|
||||
<a id="createCloseFullButton" href="#" class="button" onclick="javascript:createClosedSelect('full');">Full</a>
|
||||
<a id="createClosePrevious3YearButton" href="#" class="button" onclick="javascript:createClosedSelect('previous3Year');">Year - 3</a>
|
||||
<a id="createClosePrevious2YearButton" href="#" class="button" onclick="javascript:createClosedSelect('previous2Year');">Year - 2</a>
|
||||
<a id="createClosePreviousYearButton" href="#" class="button" onclick="javascript:createClosedSelect('previousYear');">Previous Year</a>
|
||||
<span style="margin-left: 50px;"> </span>
|
||||
<span style="margin-left: 25px;"> </span>
|
||||
<a href="#rawgroupedswitch" class="button" title="Go down to the table below.">⇊ ⇊</a>
|
||||
<span style="margin-left: 50px;"> </span>
|
||||
<span style="margin-left: 25px;"> </span>
|
||||
<a href="index.xhtml" class="button">Root</a>
|
||||
<a href="admins.xhtml" class="button">Admins</a>
|
||||
<a href="chapril.xhtml" class="button">Chapril</a>
|
||||
<a href="gdtc.xhtml" class="button">gDTC</a>
|
||||
</div>
|
||||
<div id="3MonthsBox" style="display: none;">
|
||||
<div id="createdClosed3MonthsChart" style="display: inline-block; width: 33%; height: 400px;">CREATED/CLOSED 3 MONTHS CHART</div>
|
||||
|
@ -42,6 +45,16 @@
|
|||
<div id="created-Closed12MonthsChart" style="display: inline-block; width: 33%; height: 400px;">CREATED-CLOSED 12 MONTHS CHART</div>
|
||||
<div id="age12MonthsChart" style="display: inline-block; width: 33%; height: 400px;">AGE 12 MONTHS CHART</div>
|
||||
</div>
|
||||
<div id="previous3YearBox" style="display: none;">
|
||||
<div id="createdClosedPrevious3YearChart" style="display: inline-block; width: 33%; height: 400px;">CREATED/CLOSED PREVIOUS 3 YEARS CHART</div>
|
||||
<div id="created-ClosedPrevious3YearChart" style="display: inline-block; width: 33%; height: 400px;">CREATED-CLOSED PREVIOUS 3 YEARS CHART</div>
|
||||
<div id="agePrevious3YearChart" style="display: inline-block; width: 33%; height: 400px;">AGE PREVIOUS 3 YEARS CHART</div>
|
||||
</div>
|
||||
<div id="previous2YearBox" style="display: none;">
|
||||
<div id="createdClosedPrevious2YearChart" style="display: inline-block; width: 33%; height: 400px;">CREATED/CLOSED PREVIOUS 2 YEARS CHART</div>
|
||||
<div id="created-ClosedPrevious2YearChart" style="display: inline-block; width: 33%; height: 400px;">CREATED-CLOSED PREVIOUS 2 YEARS CHART</div>
|
||||
<div id="agePrevious2YearChart" style="display: inline-block; width: 33%; height: 400px;">AGE PREVIOUS 2 YEARS CHART</div>
|
||||
</div>
|
||||
<div id="previousYearBox" style="display: none;">
|
||||
<div id="createdClosedPreviousYearChart" style="display: inline-block; width: 33%; height: 400px;">CREATED/CLOSED PREVIOUS YEAR CHART</div>
|
||||
<div id="created-ClosedPreviousYearChart" style="display: inline-block; width: 33%; height: 400px;">CREATED-CLOSED PREVIOUS YEAR CHART</div>
|
||||
|
@ -68,7 +81,7 @@
|
|||
<div id="unassignedGroupedChart" style="width: 360px; height: 200px; display: none;"></div>
|
||||
<div id="createdClosedChartMini" style="width: 220px; height: 200px; display: inline-block;">CREATED/CLOSED CHART MINI</div>
|
||||
<div id="created-ClosedChartMini" style="width: 220px; height: 200px; display: inline-block;">CREATED-CLOSED CHART MINI</div>
|
||||
<div id="ageChartMini" style="width: 250px; height: 200px; display: inline-block;">CREATED-CLOSED MONTHS CHART MINI</div>
|
||||
<div id="ageChartMini" style="width: 220px; height: 200px; display: inline-block;">CREATED-CLOSED MONTHS CHART MINI</div>
|
||||
</div>
|
||||
<br/>
|
||||
<div id="tableView">
|
||||
|
@ -82,12 +95,16 @@
|
|||
document.getElementById ('createClose3MonthsButton').classList.remove('selected');
|
||||
document.getElementById ('createClose6MonthsButton').classList.remove('selected');
|
||||
document.getElementById ('createClose12MonthsButton').classList.remove('selected');
|
||||
document.getElementById ('createClosePrevious3YearButton').classList.remove('selected');
|
||||
document.getElementById ('createClosePrevious2YearButton').classList.remove('selected');
|
||||
document.getElementById ('createClosePreviousYearButton').classList.remove('selected');
|
||||
document.getElementById ('createCloseFullButton').classList.remove('selected');
|
||||
|
||||
document.getElementById ('3MonthsBox').style.display = 'none';
|
||||
document.getElementById ('6MonthsBox').style.display = 'none';
|
||||
document.getElementById ('12MonthsBox').style.display = 'none';
|
||||
document.getElementById ('previous3YearBox').style.display = 'none';
|
||||
document.getElementById ('previous2YearBox').style.display = 'none';
|
||||
document.getElementById ('previousYearBox').style.display = 'none';
|
||||
document.getElementById ('fullBox').style.display = 'none';
|
||||
|
||||
|
@ -106,6 +123,16 @@
|
|||
document.getElementById ('createClose12MonthsButton').classList.add('selected');
|
||||
document.getElementById ('12MonthsBox').style.display = 'block';
|
||||
}
|
||||
else if (selection == 'previous3Year')
|
||||
{
|
||||
document.getElementById ('createClosePrevious3YearButton').classList.add('selected');
|
||||
document.getElementById ('previous3YearBox').style.display = 'block';
|
||||
}
|
||||
else if (selection == 'previous2Year')
|
||||
{
|
||||
document.getElementById ('createClosePrevious2YearButton').classList.add('selected');
|
||||
document.getElementById ('previous2YearBox').style.display = 'block';
|
||||
}
|
||||
else if (selection == 'previousYear')
|
||||
{
|
||||
document.getElementById ('createClosePreviousYearButton').classList.add('selected');
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Christian Pierre MOMON, DEVINSY
|
||||
* Copyright (C) 2019-2020 Christian Pierre MOMON <christian.momon@devinsy.fr>
|
||||
*
|
||||
* This file is part of Juga, simple key value database.
|
||||
* This file is part of AgirStatool, simple key value database.
|
||||
*
|
||||
* Juga 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 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.
|
||||
*
|
||||
* Juga 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.
|
||||
* 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 Juga. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with AgirStatool. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.april.agirstatool.core;
|
||||
|
||||
|
@ -37,9 +37,9 @@ import org.junit.Test;
|
|||
*
|
||||
* @author Christian Pierre MOMON
|
||||
*/
|
||||
public class JugaTest
|
||||
public class AgirStatoolTest
|
||||
{
|
||||
private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(JugaTest.class);
|
||||
private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(AgirStatoolTest.class);
|
||||
|
||||
@Test
|
||||
public void testExport01() throws Exception
|
Loading…
Reference in New Issue
Block a user