From 0bc73f661e5eb005334f4e863099a7807ba23f8a Mon Sep 17 00:00:00 2001 From: "Christian P. MOMON" Date: Sat, 20 Feb 2021 21:25:10 +0100 Subject: [PATCH] Added category distribution charts. Improved software charts. --- .../statoolinfos/core/StatoolInfosUtils.java | 25 +++ .../htmlize/FederationStatsPage.java | 13 +- .../statoolinfos/htmlize/Htmlizer.java | 181 +++++++++++++++++- .../statoolinfos/htmlize/charts/BarChart.java | 7 +- .../htmlize/charts/ChartColor.java | 20 ++ .../htmlize/charts/ChartColors.java | 15 ++ .../statoolinfos/htmlize/charts/PieChart.java | 5 +- .../htmlize/federationStats.xhtml | 20 +- .../htmlize/organizationStats.xhtml | 10 +- 9 files changed, 277 insertions(+), 19 deletions(-) diff --git a/src/fr/devinsy/statoolinfos/core/StatoolInfosUtils.java b/src/fr/devinsy/statoolinfos/core/StatoolInfosUtils.java index b6e8e29..4be1b00 100644 --- a/src/fr/devinsy/statoolinfos/core/StatoolInfosUtils.java +++ b/src/fr/devinsy/statoolinfos/core/StatoolInfosUtils.java @@ -52,6 +52,7 @@ import org.slf4j.LoggerFactory; import fr.devinsy.strings.StringList; import fr.devinsy.strings.StringsUtils; +import fr.devinsy.xidyn.utils.XidynUtils; /** * The Class StatoolInfosUtils. @@ -80,6 +81,30 @@ public class StatoolInfosUtils return result; } + /** + * Escape JSONXML. + * + * @param data + * the data + * @return the string + */ + public static String escapeJSONXML(final String data) + { + String result; + + if (data == null) + { + result = null; + } + else + { + result = XidynUtils.escapeXmlBlank(data.replace('\'', ' ')); + } + + // + return result; + } + /** * File local date time. * diff --git a/src/fr/devinsy/statoolinfos/htmlize/FederationStatsPage.java b/src/fr/devinsy/statoolinfos/htmlize/FederationStatsPage.java index 03f1b9d..787d910 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/FederationStatsPage.java +++ b/src/fr/devinsy/statoolinfos/htmlize/FederationStatsPage.java @@ -67,10 +67,6 @@ public class FederationStatsPage TagDataManager data = new TagDataManager(); - data.setContent("serviceCountMonthChart", Htmlizer.htmlizeServiceCountMonthChart(federation)); - data.setContent("serviceCountYearChart", Htmlizer.htmlizeServiceCountYearChart(federation)); - data.setContent("serviceDateStatusChart", Htmlizer.htmlizeServiceDateStatusChart(federation.getAllServices())); - data.setContent("turnoutChart", Htmlizer.htmlizeOrganizationTurnoutChart(federation.getOrganizations())); data.setContent("organizationCountryChart", Htmlizer.htmlizeOrganizationCountryChart(federation.getOrganizations())); data.setContent("organizationCountChart", Htmlizer.htmlizeOrganizationCountChart(federation)); @@ -113,6 +109,15 @@ public class FederationStatsPage data.setContent("registrationClientTypeChart", DoughnutChartView.build(pie)); } + data.setContent("serviceCountMonthChart", Htmlizer.htmlizeServiceCountMonthChart(federation)); + data.setContent("serviceCountYearChart", Htmlizer.htmlizeServiceCountYearChart(federation)); + data.setContent("serviceDateStatusChart", Htmlizer.htmlizeServiceDateStatusChart(federation.getAllServices())); + + data.setContent("softwareDistributionChart", Htmlizer.htmlizeSoftwareDistributionChart()); + data.setContent("softwareDistributionPieChart", Htmlizer.htmlizeSoftwareDistributionPieChart(federation.getAllServices())); + data.setContent("categoryDistributionChart", Htmlizer.htmlizeCategoryDistributionChart()); + data.setContent("categoryDistributionPieChart", Htmlizer.htmlizeCatergoryDistributionPieChart(federation.getAllServices())); + // String content = PresenterUtils.dynamize("/fr/devinsy/statoolinfos/htmlize/federationStats.xhtml", data).toString(); diff --git a/src/fr/devinsy/statoolinfos/htmlize/Htmlizer.java b/src/fr/devinsy/statoolinfos/htmlize/Htmlizer.java index 189ec2f..3dba3e5 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/Htmlizer.java +++ b/src/fr/devinsy/statoolinfos/htmlize/Htmlizer.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import fr.devinsy.statoolinfos.HtmlizerContext; +import fr.devinsy.statoolinfos.core.Categories; import fr.devinsy.statoolinfos.core.Category; import fr.devinsy.statoolinfos.core.Configuration; import fr.devinsy.statoolinfos.core.Federation; @@ -49,12 +50,16 @@ import fr.devinsy.statoolinfos.htmlize.charts.PieChartView; import fr.devinsy.statoolinfos.properties.PathProperty; import fr.devinsy.statoolinfos.properties.PathPropertyList; import fr.devinsy.statoolinfos.stats.StatAgent; +import fr.devinsy.statoolinfos.stats.categories.CategoryStat; +import fr.devinsy.statoolinfos.stats.categories.CategoryStats; import fr.devinsy.statoolinfos.stats.country.CountryStats; import fr.devinsy.statoolinfos.stats.organizations.OrganizationTurnoutStats; import fr.devinsy.statoolinfos.stats.services.HostProviderTypeStats; import fr.devinsy.statoolinfos.stats.services.HostServerTypeStats; import fr.devinsy.statoolinfos.stats.services.RegistrationStats; import fr.devinsy.statoolinfos.stats.services.ServiceInstallTypeStats; +import fr.devinsy.statoolinfos.stats.softwares.SoftwareStat; +import fr.devinsy.statoolinfos.stats.softwares.SoftwareStats; import fr.devinsy.statoolinfos.util.URLUtils; import fr.devinsy.strings.StringList; @@ -201,6 +206,92 @@ public class Htmlizer SocialNetworksPage.buildAll(); } + /** + * Htmlize category distribution chart. + * + * @return the string + * @throws StatoolInfosException + * the statool infos exception + */ + public static String htmlizeCategoryDistributionChart() throws StatoolInfosException + { + String result; + + BarChart chart; + + chart = new BarChart("Distribution des catégories les plus proposées"); + chart.addDataset("Catégories"); + + Federation federation = HtmlizerContext.instance().getFederation(); + Categories categories = HtmlizerContext.instance().getCategories(); + + CategoryStats stats = StatAgent.statAllCategories(federation, categories); + stats.sortByServiceCount().reverse(); + + for (CategoryStat stat : stats) + { + if (stat.getServiceCount() > 0) + { + chart.add(stat.getCategory().getName(), stat.getServiceCount(), ChartColor.PURPLE); + } + } + + result = BarChartView.build(chart); + + // + return result; + } + + /** + * Htmlize catergory distribution pie chart. + * + * @param services + * the services + * @return the string + * @throws StatoolInfosException + * the statool infos exception + */ + public static String htmlizeCatergoryDistributionPieChart(final Services services) throws StatoolInfosException + { + String result; + + Federation federation = HtmlizerContext.instance().getFederation(); + Categories categories = HtmlizerContext.instance().getCategories(); + + CategoryStats stats = StatAgent.statAllCategories(federation, categories); + stats.sortByServiceCount().reverse(); + + ChartColors colors = ChartColor.valueList(); + colors.remove(ChartColor.BLUE); + + PieChart pie = new PieChart("Distribution des catégories"); + int index = 0; + while ((index < stats.size() && (index < 10))) + { + ChartColor color = colors.get(index); + CategoryStat stat = stats.get(index); + pie.add(StringUtils.abbreviate(stat.getCategory().getName(), 30), stat.getServiceCount(), color); + + index += 1; + } + + int others = 0; + while (index < stats.size()) + { + CategoryStat stat = stats.get(index); + others += stat.getServiceCount(); + + index += 1; + } + pie.add("Autres", others, ChartColor.BLUE); + pie.setLegendPosition(Position.RIGHT); + + result = DoughnutChartView.build(pie); + + // + return result; + } + /** * Htmlize host provider type chart. * @@ -514,7 +605,7 @@ public class Htmlizer BarChart chart; - chart = new BarChart("Nombre de services (mois)"); + chart = new BarChart("Nombre de services déclarés (mois)"); chart.addDataset("Services"); YearMonth now = YearMonth.now(); @@ -691,7 +782,7 @@ public class Htmlizer BarChart chart; - chart = new BarChart("Nombre de services"); + chart = new BarChart("Nombre de services déclarés"); chart.addDataset("Services"); int now = LocalDate.now().getYear(); @@ -808,6 +899,92 @@ public class Htmlizer return result; } + /** + * Htmlize software distribution chart. + * + * @param services + * the services + * @return the string + * @throws StatoolInfosException + * the statool infos exception + */ + public static String htmlizeSoftwareDistributionChart() throws StatoolInfosException + { + String result; + + BarChart chart = new BarChart("Distribution des logiciels proposés par au moins deux services"); + chart.addDataset("Logiciel"); + + Federation federation = HtmlizerContext.instance().getFederation(); + Categories categories = HtmlizerContext.instance().getCategories(); + + SoftwareStats stats = StatAgent.statAllSoftwares(federation, categories); + stats.sortByServiceCount().reverse(); + + for (SoftwareStat stat : stats) + { + if (stat.getServiceCount() > 1) + { + chart.add(stat.getName(), stat.getServiceCount(), ChartColor.PURPLE); + } + } + + result = BarChartView.build(chart); + + // + return result; + } + + /** + * Htmlize software used chart. + * + * @param services + * the services + * @return the string + * @throws StatoolInfosException + * the statool infos exception + */ + public static String htmlizeSoftwareDistributionPieChart(final Services services) throws StatoolInfosException + { + String result; + + Federation federation = HtmlizerContext.instance().getFederation(); + Categories categories = HtmlizerContext.instance().getCategories(); + + SoftwareStats stats = StatAgent.statAllSoftwares(federation, categories); + stats.sortByServiceCount().reverse(); + + ChartColors colors = ChartColor.valueList(); + colors.remove(ChartColor.BLUE); + + PieChart pie = new PieChart("Distribution des logiciels"); + int index = 0; + while ((index < stats.size() && (index < 10))) + { + ChartColor color = colors.get(index); + SoftwareStat stat = stats.get(index); + pie.add(stat.getName(), stat.getServiceCount(), color); + + index += 1; + } + + int others = 0; + while (index < stats.size()) + { + SoftwareStat stat = stats.get(index); + others += stat.getServiceCount(); + + index += 1; + } + pie.add("Autres", others, ChartColor.BLUE); + pie.setLegendPosition(Position.RIGHT); + + result = DoughnutChartView.build(pie); + + // + return result; + } + /** * To bar chart. * diff --git a/src/fr/devinsy/statoolinfos/htmlize/charts/BarChart.java b/src/fr/devinsy/statoolinfos/htmlize/charts/BarChart.java index d81aacd..1c80062 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/charts/BarChart.java +++ b/src/fr/devinsy/statoolinfos/htmlize/charts/BarChart.java @@ -21,6 +21,7 @@ package fr.devinsy.statoolinfos.htmlize.charts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import fr.devinsy.statoolinfos.core.StatoolInfosUtils; import fr.devinsy.strings.StringList; /** @@ -78,8 +79,10 @@ public class BarChart */ public void add(final String label, final double value, final ChartColor color) { - this.labels.add(label); - this.datasets.get(0).add(new BarChartData(label, value, color)); + String escapedLabel = StatoolInfosUtils.escapeJSONXML(label); + + this.labels.add(escapedLabel); + this.datasets.get(0).add(new BarChartData(escapedLabel, value, color)); } /** diff --git a/src/fr/devinsy/statoolinfos/htmlize/charts/ChartColor.java b/src/fr/devinsy/statoolinfos/htmlize/charts/ChartColor.java index 307a1af..add4f9e 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/charts/ChartColor.java +++ b/src/fr/devinsy/statoolinfos/htmlize/charts/ChartColor.java @@ -81,4 +81,24 @@ public enum ChartColor // return result; } + + /** + * To list. + * + * @return the chart colors + */ + public static ChartColors valueList() + { + ChartColors result; + + result = new ChartColors(); + ChartColor[] values = values(); + for (int index = 0; index < values.length; index++) + { + result.add(values[index]); + } + + // + return result; + } } diff --git a/src/fr/devinsy/statoolinfos/htmlize/charts/ChartColors.java b/src/fr/devinsy/statoolinfos/htmlize/charts/ChartColors.java index 8532529..a64ba7a 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/charts/ChartColors.java +++ b/src/fr/devinsy/statoolinfos/htmlize/charts/ChartColors.java @@ -37,6 +37,21 @@ public class ChartColors extends ArrayList super(); } + /** + * From. + * + * @param colors + * the colors + * @return the chart colors + */ + public void addAll(final ChartColor[] colors) + { + for (int index = 0; index < colors.length; index++) + { + add(colors[index]); + } + } + /** * Gets the ChartColor of the index with safe overflow. * diff --git a/src/fr/devinsy/statoolinfos/htmlize/charts/PieChart.java b/src/fr/devinsy/statoolinfos/htmlize/charts/PieChart.java index 20dd947..6bb9b42 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/charts/PieChart.java +++ b/src/fr/devinsy/statoolinfos/htmlize/charts/PieChart.java @@ -21,6 +21,7 @@ package fr.devinsy.statoolinfos.htmlize.charts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import fr.devinsy.statoolinfos.core.StatoolInfosUtils; import fr.devinsy.strings.StringList; /** @@ -78,7 +79,9 @@ public class PieChart */ public void add(final String label, final double value, final ChartColor color) { - this.datas.add(new PieChartData(label, value, color)); + String targetLabel = StatoolInfosUtils.escapeJSONXML(label); + + this.datas.add(new PieChartData(targetLabel, value, color)); } /** diff --git a/src/fr/devinsy/statoolinfos/htmlize/federationStats.xhtml b/src/fr/devinsy/statoolinfos/htmlize/federationStats.xhtml index d5c836a..b1bc8dd 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/federationStats.xhtml +++ b/src/fr/devinsy/statoolinfos/htmlize/federationStats.xhtml @@ -15,11 +15,6 @@

Statistiques

-
-
-
-
-
@@ -45,6 +40,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/fr/devinsy/statoolinfos/htmlize/organizationStats.xhtml b/src/fr/devinsy/statoolinfos/htmlize/organizationStats.xhtml index 92484a8..15739e2 100644 --- a/src/fr/devinsy/statoolinfos/htmlize/organizationStats.xhtml +++ b/src/fr/devinsy/statoolinfos/htmlize/organizationStats.xhtml @@ -15,11 +15,6 @@

Statistiques

-
-
-
-
-
@@ -42,6 +37,11 @@
+
+
+
+
+