Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/ca/gc/tbs/controller/ProblemController.java
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/ca/gc/tbs/controller/TopTaskController.java
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
18 changes: 10 additions & 8 deletions src/main/resources/static/css/pageFeedbackDashboard_styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/* ============================================
Expand Down
252 changes: 142 additions & 110 deletions src/main/resources/static/js/pageFeedback-dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: <b>' + date + '</b><br/>' +
this.series.name + ': <b>' + formatNumberWithCommas(this.y) + '</b>' +
(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);
});
}


Expand Down
6 changes: 3 additions & 3 deletions src/main/resources/templates/pageFeedbackDashboard_en.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ <h1 id="wb-cont">GC Feedback - Dashboard</h1>
</div>
<div class="pf-filter-footer">
<div class="pf-stats">
<div class="stat"><span class="totalPagesCount">0</span> Pages with Feedback Tool</div>
<div class="stat"><span class="totalPagesCount">0</span> Pages with comments</div>
<div class="stat"><span class="totalCommentCount">0</span> Total Comments</div>
</div>
<div class="pf-actions">
Expand All @@ -187,7 +187,7 @@ <h1 id="wb-cont">GC Feedback - Dashboard</h1>
</main>
<div class="col-lg-12">
<div class="row custom-row">
<div id="chart"></div>
<div id="chart"><canvas id="chartCanvas"></canvas></div>
</div>
</div>
<div class="col-lg-12">
Expand Down Expand Up @@ -217,7 +217,7 @@ <h1 id="wb-cont">GC Feedback - Dashboard</h1>
src="https://cdn.datatables.net/v/dt/jq-3.7.0/jszip-3.10.1/dt-2.3.2/b-3.2.0/b-html5-3.2.0/cr-2.0.4/fh-4.0.1/r-3.0.3/datatables.min.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="text/javascript" src="js/spring-friendly.min.js"></script>
<script type="text/javascript" src="js/custom-dropdown.js"></script>
<script th:inline="javascript">
Expand Down
6 changes: 3 additions & 3 deletions src/main/resources/templates/pageFeedbackDashboard_fr.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ <h1 id="wb-cont">Rétroaction GC - Tableau de bord</h1>
</div>
<div class="pf-filter-footer">
<div class="pf-stats">
<div class="stat"><span class="totalPagesCount">0</span> Pages avec rétroaction</div>
<div class="stat"><span class="totalPagesCount">0</span> Pages avec commentaires</div>
<div class="stat"><span class="totalCommentCount">0</span> Commentaires totaux</div>
</div>
<div class="pf-actions">
Expand All @@ -187,7 +187,7 @@ <h1 id="wb-cont">Rétroaction GC - Tableau de bord</h1>
</main>
<div class="col-lg-12">
<div class="row custom-row">
<div id="chart"></div>
<div id="chart"><canvas id="chartCanvas"></canvas></div>
</div>
</div>
<div class="col-lg-12">
Expand Down Expand Up @@ -217,7 +217,7 @@ <h1 id="wb-cont">Rétroaction GC - Tableau de bord</h1>
src="https://cdn.datatables.net/v/dt/jq-3.7.0/jszip-3.10.1/dt-2.3.2/b-3.2.0/b-html5-3.2.0/cr-2.0.4/fh-4.0.1/r-3.0.3/datatables.min.js"></script>
<script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script type="text/javascript" src="js/spring-friendly.min.js"></script>
<script type="text/javascript" src="js/custom-dropdown.js"></script>
<script th:inline="javascript">
Expand Down
Loading
Loading