diff --git a/src/main/java/ca/gc/tbs/controller/DashboardController.java b/src/main/java/ca/gc/tbs/controller/DashboardController.java
index 6e369fb..153627a 100644
--- a/src/main/java/ca/gc/tbs/controller/DashboardController.java
+++ b/src/main/java/ca/gc/tbs/controller/DashboardController.java
@@ -134,6 +134,7 @@ public DashboardController(
institutionMappings.put("PS", Arrays.asList("PS", "SP", "PUBLIC SAFETY CANADA", "SÉCURITÉ PUBLIQUE CANADA", "PS/SP"));
institutionMappings.put("PSC", Arrays.asList("PSC", "CFP", "PUBLIC SERVICE COMMISSION OF CANADA", "COMMISSION DE LA FONCTION PUBLIQUE DU CANADA", "PSC/CFP"));
institutionMappings.put("PSPC", Arrays.asList("PSPC", "SPAC", "PUBLIC SERVICES AND PROCUREMENT CANADA", "SERVICES PUBLICS ET APPROVISIONNEMENT CANADA", "GOUVERNEMENT DU CANADA, SERVICES PUBLICS ET APPROVISIONNEMENT CANADA", "GOVERNMENT OF CANADA, PUBLIC SERVICES AND PROCUREMENT CANADA", "PSPC/SPAC"));
+ institutionMappings.put("PSPC-OL", Arrays.asList("PSPC-OL", "SPAC-NL", "GOVERNMENT OF CANADA, PUBLIC SERVICES AND PROCUREMENT CANADA, TRANSLATION BUREAU", "GOUVERNEMENT DU CANADA, SERVICES PUBLICS ET APPROVISIONNEMENT CANADA, BUREAU DE LA TRADUCTION", "PSPC-OL/SPAC-NL"));
institutionMappings.put("RCMP", Arrays.asList("RCMP", "GRC", "ROYAL CANADIAN MOUNTED POLICE", "GENDARMERIE ROYALE DU CANADA", "RCMP/GRC"));
institutionMappings.put("SC", Arrays.asList("SC", "SC", "SERVICE CANADA", "SERVICE CANADA", "SC/SC"));
institutionMappings.put("SSC", Arrays.asList("SSC", "PSC", "SHARED SERVICES CANADA", "SERVICES PARTAGÉS CANADA", "SSC/PSC"));
diff --git a/src/main/java/ca/gc/tbs/controller/ProblemController.java b/src/main/java/ca/gc/tbs/controller/ProblemController.java
index b11e162..2588704 100644
--- a/src/main/java/ca/gc/tbs/controller/ProblemController.java
+++ b/src/main/java/ca/gc/tbs/controller/ProblemController.java
@@ -417,6 +417,14 @@ public ProblemController(
"GOUVERNEMENT DU CANADA, SERVICES PUBLICS ET APPROVISIONNEMENT CANADA",
"GOVERNMENT OF CANADA, PUBLIC SERVICES AND PROCUREMENT CANADA",
"PSPC / SPAC"));
+ institutionMappings.put(
+ "PSPC-OL",
+ Arrays.asList(
+ "PSPC-OL",
+ "SPAC-NL",
+ "GOVERNMENT OF CANADA, PUBLIC SERVICES AND PROCUREMENT CANADA, TRANSLATION BUREAU",
+ "GOUVERNEMENT DU CANADA, SERVICES PUBLICS ET APPROVISIONNEMENT CANADA, BUREAU DE LA TRADUCTION",
+ "PSPC-OL / SPAC-NL"));
institutionMappings.put(
"RCMP",
Arrays.asList(
diff --git a/src/main/java/ca/gc/tbs/controller/TopTaskController.java b/src/main/java/ca/gc/tbs/controller/TopTaskController.java
index aed9f5f..0cef171 100644
--- a/src/main/java/ca/gc/tbs/controller/TopTaskController.java
+++ b/src/main/java/ca/gc/tbs/controller/TopTaskController.java
@@ -422,6 +422,14 @@ public TopTaskController(
"GOUVERNEMENT DU CANADA, SERVICES PUBLICS ET APPROVISIONNEMENT CANADA",
"GOVERNMENT OF CANADA, PUBLIC SERVICES AND PROCUREMENT CANADA",
"PSPC / SPAC"));
+ institutionMappings.put(
+ "PSPC-OL",
+ Arrays.asList(
+ "PSPC-OL",
+ "SPAC-NL",
+ "GOVERNMENT OF CANADA, PUBLIC SERVICES AND PROCUREMENT CANADA, TRANSLATION BUREAU",
+ "GOUVERNEMENT DU CANADA, SERVICES PUBLICS ET APPROVISIONNEMENT CANADA, BUREAU DE LA TRADUCTION",
+ "PSPC-OL / SPAC-NL"));
institutionMappings.put(
"RCMP",
Arrays.asList(
diff --git a/src/main/resources/static/css/pageFeedbackDashboard_styles.css b/src/main/resources/static/css/pageFeedbackDashboard_styles.css
index e468fef..6983c15 100644
--- a/src/main/resources/static/css/pageFeedbackDashboard_styles.css
+++ b/src/main/resources/static/css/pageFeedbackDashboard_styles.css
@@ -325,18 +325,20 @@ h1#wb-cont {
}
#chart {
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- align-items: center;
- padding: 20px;
- border: 1px solid #000;
+ padding: 24px;
+ background: #fcfcfb;
+ border: 1px solid rgba(11, 11, 11, 0.1);
+ border-radius: 8px;
+ box-shadow: 0 1px 3px rgba(11, 11, 11, 0.06);
margin: 1em auto;
max-width: 85%;
+ position: relative;
+ height: 420px;
}
-.highcharts-credits {
- display: none;
+#chartCanvas {
+ width: 100% !important;
+ height: 100% !important;
}
/* ============================================
diff --git a/src/main/resources/static/js/pageFeedback-dashboard.js b/src/main/resources/static/js/pageFeedback-dashboard.js
index 28aad7b..8bd1fcb 100644
--- a/src/main/resources/static/js/pageFeedback-dashboard.js
+++ b/src/main/resources/static/js/pageFeedback-dashboard.js
@@ -370,132 +370,164 @@ $(document).ready(function () {
}
return rollingAverages;
}
+let chartInstance = null;
+
function fetchDataAndCreateChart() {
-//error keyword filter
const errorKeywordChecked = $("#errorComments").prop("checked");
let url = "/chartData";
let params = [];
- if (errorKeywordChecked) params.push("error_keyword=true");
+ if (errorKeywordChecked) params.push("error_keyword=true");
- // Date range
- const dateRangePickerValue = $("#dateRangePicker").val();
- if (dateRangePickerValue) {
- const dateRange = $("#dateRangePicker").data("daterangepicker");
- params.push("startDate=" + encodeURIComponent(dateRange.startDate.format("YYYY-MM-DD")));
- params.push("endDate=" + encodeURIComponent(dateRange.endDate.format("YYYY-MM-DD")));
- }
+ const dateRangePickerValue = $("#dateRangePicker").val();
+ if (dateRangePickerValue) {
+ const dateRange = $("#dateRangePicker").data("daterangepicker");
+ params.push("startDate=" + encodeURIComponent(dateRange.startDate.format("YYYY-MM-DD")));
+ params.push("endDate=" + encodeURIComponent(dateRange.endDate.format("YYYY-MM-DD")));
+ }
- // Other filters (need to turn this into a module that takes an ID as a parameter)
- if ($("#language").val()) params.push("language=" + encodeURIComponent($("#language").val()));
- if ($("#department").val()) params.push("department=" + encodeURIComponent($("#department").val()));
- if ($("#comments").val()) params.push("comments=" + encodeURIComponent($("#comments").val()));
- if ($("#section").val()) params.push("section=" + encodeURIComponent($("#section").val()));
- if ($("#theme").val()) params.push("theme=" + encodeURIComponent($("#theme").val()));
- if ($("#url").val()) params.push("url=" + encodeURIComponent($("#url").val()));
+ if ($("#language").val()) params.push("language=" + encodeURIComponent($("#language").val()));
+ if ($("#department").val()) params.push("department=" + encodeURIComponent($("#department").val()));
+ if ($("#comments").val()) params.push("comments=" + encodeURIComponent($("#comments").val()));
+ if ($("#section").val()) params.push("section=" + encodeURIComponent($("#section").val()));
+ if ($("#theme").val()) params.push("theme=" + encodeURIComponent($("#theme").val()));
+ if ($("#url").val()) params.push("url=" + encodeURIComponent($("#url").val()));
- if (params.length > 0) url += "?" + params.join("&");
+ if (params.length > 0) url += "?" + params.join("&");
- // Fetch the data from your endpoint
fetch(url)
- .then((response) => response.json())
- .then((data) => {
- // Extract categories (dates) and comments data
- const categories = data.map((item) => item.date);
- const commentsData = data.map((item) => item.comments);
-
- // Calculate rolling average (e.g., over 7 days)
- const windowSize = 7; // Adjust this value as needed
- const rollingAverages = calculateRollingAverage(commentsData, windowSize);
-
- const paddedRollingAverages = new Array(windowSize - 1).fill(null).concat(rollingAverages);
-
- // Now create the chart with the data
- Highcharts.chart("chart", {
- chart: {
- type: "column",
- },
- title: {
- text: isFrench ? "Commentaires par jour" : "Comments by day",
- align: "left",
- style: {
- fontSize: "20px", // Adjust title font size here
- },
- },
- xAxis: {
- categories: categories, // Set the categories from the data
- crosshair: true,
- accessibility: {
- description: "Dates",
- },
- labels: {
- style: {
- fontSize: "14px", // Adjust X axis labels font size here
- },
- },
+ .then((response) => response.json())
+ .then((data) => {
+ const categories = data.map((item) => item.date);
+ const commentsData = data.map((item) => item.comments);
+
+ const windowSize = 7;
+ const rollingAverages = calculateRollingAverage(commentsData, windowSize);
+ const paddedRollingAverages = new Array(windowSize - 1).fill(null).concat(rollingAverages);
+
+ if (chartInstance) {
+ chartInstance.destroy();
+ }
+
+ const ctx = document.getElementById("chartCanvas").getContext("2d");
+ chartInstance = new Chart(ctx, {
+ data: {
+ labels: categories,
+ datasets: [
+ {
+ type: "bar",
+ label: isFrench ? "Commentaires" : "Comments",
+ data: commentsData,
+ backgroundColor: "#2a78d6", // categorical slot 1 (blue)
+ hoverBackgroundColor: "#2a78d6",
+ borderWidth: 0,
+ borderRadius: 4,
+ borderSkipped: "bottom",
+ maxBarThickness: 28,
+ categoryPercentage: 0.9,
+ barPercentage: 0.9,
+ order: 2,
+ },
+ {
+ type: "line",
+ label: isFrench ? "Moyenne mobile (7 jours)" : "Rolling Average (7 days)",
+ data: paddedRollingAverages,
+ borderColor: "#eb6834", // categorical slot 8 (orange)
+ backgroundColor: "#eb6834",
+ borderWidth: 5,
+ pointRadius: 0,
+ pointHoverRadius: 4,
+ pointHoverBorderWidth: 0,
+ spanGaps: true,
+ tension: 0.35,
+ order: 1,
+ },
+ ],
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ layout: { padding: { top: 4, right: 8 } },
+ interaction: {
+ mode: "index",
+ intersect: false,
+ },
+ plugins: {
+ title: {
+ display: true,
+ text: isFrench ? "Commentaires par jour" : "Comments by day",
+ align: "start",
+ font: { size: 18, weight: "600" },
+ color: "#0b0b0b", // primary ink
+ padding: { bottom: 18 },
+ },
+ legend: {
+ position: "bottom",
+ labels: {
+ font: { size: 13 },
+ color: "#52514e", // secondary ink
+ usePointStyle: true,
+ pointStyle: "circle",
+ boxWidth: 8,
+ boxHeight: 8,
+ padding: 18,
},
- yAxis: {
- min: 0,
- title: {
- text: isFrench ? "Nombre de commentaires" : "Number of Comments",
- style: {
- fontSize: "16px", // Adjust Y axis title font size here
- fontWeight: "bold",
- },
- },
- labels: {
- style: {
- fontSize: "16px", // Adjust Y axis labels font size here
- },
- formatter: function() {
- return formatNumberWithCommas(this.value);
- }
- },
+ },
+ tooltip: {
+ backgroundColor: "#ffffff",
+ titleColor: "#0b0b0b",
+ bodyColor: "#52514e",
+ borderColor: "rgba(11,11,11,0.10)",
+ borderWidth: 1,
+ padding: 12,
+ cornerRadius: 6,
+ usePointStyle: true,
+ boxPadding: 6,
+ callbacks: {
+ label: function (context) {
+ const val = context.parsed.y;
+ if (val === null) return null;
+ const suffix = isFrench ? " commentaires" : " comments";
+ return context.dataset.label + ": " + formatNumberWithCommas(val) + suffix;
+ },
},
- legend: {
- style: {
- fontSize: "16px", // Adjust legend font size here
- },
- itemStyle: {
- fontSize: "14px", // Adjust legend item font size here
- },
+ },
+ },
+ scales: {
+ x: {
+ ticks: {
+ font: { size: 12 },
+ color: "#898781", // muted axis ink
+ maxRotation: 45,
+ autoSkipPadding: 12,
},
- tooltip: {
- valueSuffix: isFrench ? " commentaires" : " comments",
- style: {
- fontSize: "16px", // Adjust font size for text in the tooltip on hover
- },
- formatter: function() {
- const date = categories[this.point.index];
- return 'Date: ' + date + '
' +
- this.series.name + ': ' + formatNumberWithCommas(this.y) + '' +
- (isFrench ? " commentaires" : " comments");
- }
+ grid: { display: false },
+ border: { color: "#c3c2b7" }, // baseline
+ },
+ y: {
+ min: 0,
+ title: {
+ display: true,
+ text: isFrench ? "Nombre de commentaires" : "Number of Comments",
+ font: { size: 13, weight: "600" },
+ color: "#52514e",
},
- plotOptions: {
- column: {
- pointPadding: 0, // Minimizes the space between points within the same category
- groupPadding: 0.1, // Adjust space between categories
- borderWidth: 0,
- },
+ ticks: {
+ font: { size: 12 },
+ color: "#898781",
+ padding: 8,
+ callback: function (value) { return formatNumberWithCommas(value); },
},
- series: [
- {
- name: isFrench ? "Commentaires" : "Comments",
- data: commentsData, // Set the data from the data
- },
- {
- name: isFrench ? "Moyenne mobile (7 jours)" : "Rolling Average (7 days)",
- data: paddedRollingAverages, // Use the rolling average data
- type: "line", // Display as a line chart
- color: "#5D3FD3", // Optional: Set a different color for the rolling average
- },
- ],
- });
- })
- .catch((error) => {
- console.error("Error fetching data: ", error);
+ grid: { color: "#e1e0d9", drawTicks: false }, // hairline gridlines
+ border: { display: false },
+ },
+ },
+ },
});
+ })
+ .catch((error) => {
+ console.error("Error fetching data: ", error);
+ });
}
diff --git a/src/main/resources/templates/pageFeedbackDashboard_en.html b/src/main/resources/templates/pageFeedbackDashboard_en.html
index b4b7adf..1926fad 100644
--- a/src/main/resources/templates/pageFeedbackDashboard_en.html
+++ b/src/main/resources/templates/pageFeedbackDashboard_en.html
@@ -168,7 +168,7 @@