diff --git a/application/controllers/Statistics.php b/application/controllers/Statistics.php
index 5e4fcc118..562afe48c 100644
--- a/application/controllers/Statistics.php
+++ b/application/controllers/Statistics.php
@@ -65,6 +65,28 @@ class Statistics extends CI_Controller {
echo json_encode($yearstats);
}
+ public function get_year_month() {
+ $this->load->model('logbook_model');
+
+ $yr = xss_clean($this->input->post('yr')) ?? 'All';
+
+ // get data
+ $totals_month = $this->logbook_model->totals_year_month($yr);
+
+ $monthstats = array();
+
+ $i = 0;
+ if ($totals_month) {
+ foreach($totals_month->result() as $qso_numbers) {
+ $monthstats[$i]['month'] = intval($qso_numbers->month);
+ $monthstats[$i++]['total'] = $qso_numbers->total;
+ }
+ }
+
+ header('Content-Type: application/json');
+ echo json_encode($monthstats);
+ }
+
public function get_mode() {
$this->load->model('logbook_model');
$yr = xss_clean($this->input->post('yr')) ?? 'All';
diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php
index a32c47ab7..032b6bee6 100644
--- a/application/models/Logbook_model.php
+++ b/application/models/Logbook_model.php
@@ -3462,6 +3462,41 @@ class Logbook_model extends CI_Model {
return $query;
}
+ function totals_year_month($year = null) {
+
+ $this->load->model('logbooks_model');
+ $logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
+
+ if (!$logbooks_locations_array) {
+ return null;
+ }
+
+ $location_list = implode(',', array_fill(0, count($logbooks_locations_array), '?'));
+ $params = $logbooks_locations_array;
+
+ if ($year === null || $year === 'All') {
+ // Aggregate across all years
+ $sql = "SELECT DATE_FORMAT(COL_TIME_ON, '%m') AS month, COUNT(COL_PRIMARY_KEY) AS total
+ FROM " . $this->config->item('table_name') . "
+ WHERE station_id IN ($location_list)
+ GROUP BY DATE_FORMAT(COL_TIME_ON, '%m')
+ ORDER BY month ASC";
+ } else {
+ // Filter by specific year
+ $sql = "SELECT DATE_FORMAT(COL_TIME_ON, '%m') AS month, COUNT(COL_PRIMARY_KEY) AS total
+ FROM " . $this->config->item('table_name') . "
+ WHERE station_id IN ($location_list)
+ AND DATE_FORMAT(COL_TIME_ON, '%Y') = ?
+ GROUP BY DATE_FORMAT(COL_TIME_ON, '%m')
+ ORDER BY month ASC";
+ $params[] = $year;
+ }
+
+ $query = $this->db->query($sql, $params);
+
+ return $query;
+ }
+
/* Return total number of qsos */
function total_qsos($StationLocationsArray = null, $api_key = null) {
if ($StationLocationsArray == null) {
diff --git a/application/views/statistics/index.php b/application/views/statistics/index.php
index 958e7b51d..3aa0a8747 100644
--- a/application/views/statistics/index.php
+++ b/application/views/statistics/index.php
@@ -12,16 +12,35 @@
diff --git a/assets/js/sections/statistics.js b/assets/js/sections/statistics.js
index 954bc9eb7..824f62735 100644
--- a/assets/js/sections/statistics.js
+++ b/assets/js/sections/statistics.js
@@ -28,6 +28,12 @@ $("a[href='#yearstab']").on('shown.bs.tab', function(e) {
$("#yr").hide();
});
+$("a[href='#monthstab']").on('shown.bs.tab', function(e) {
+ activeTab='totalQsosPerMonth()';
+ totalQsosPerMonth();
+ $("#yr").show();
+});
+
$("a[href='#bandtab']").on('shown.bs.tab', function(e) {
totalBandQsos();
activeTab='totalBandQsos()'
@@ -268,6 +274,126 @@ function totalQsosPerYear() {
});
}
+function totalQsosPerMonth() {
+ // using this to change color of legend and label according to background color
+ var color = ifDarkModeThemeReturn('white', 'grey');
+
+ $.ajax({
+ url: base_url+'index.php/statistics/get_year_month',
+ type: 'post',
+ data: { yr: $("#yr option:selected").val() },
+ success: function (data) {
+ if (data.length > 0) {
+ $(".months").html('');
+ $(".months").append('
' + lang_statistics_months + '
');
+ $("#monthContainer").append("
");
+
+ // appending table to hold the data
+ $("#monthTable").append('
' +
+ '' +
+ '| # | ' +
+ '' + lang_statistics_month +' | ' +
+ '' + lang_statistics_number_of_qso_worked + ' | ' +
+ '
' +
+ '' +
+ '
');
+
+ var labels = [];
+ var dataQso = [];
+
+ var $myTable = $('.monthtable');
+ var i = 1;
+
+ // building the rows in the table
+ var rowElements = data.map(function (row) {
+ var $row = $('
|
');
+
+ // Convert month number to string with leading zero
+ var monthKey = row.month.toString().padStart(2, '0');
+ var monthName = monthNames[monthKey] || monthKey;
+
+ var $iterator = $('
| ').html(i++);
+ var $type = $('
| ').html(monthName);
+ var $content = $('
| ').html(row.total);
+
+ $row.append($iterator, $type, $content);
+
+ return $row;
+ });
+
+ // finally inserting the rows
+ $myTable.append(rowElements);
+
+ $.each(data, function () {
+ var monthKey = this.month.toString().padStart(2, '0');
+ var monthName = monthNames[monthKey] || monthKey;
+ labels.push(monthName);
+ dataQso.push(this.total);
+ });
+
+ var ctx = document.getElementById("monthChart").getContext('2d');
+ var myChart = new Chart(ctx, {
+ type: 'bar',
+ data: {
+ labels: labels,
+ datasets: [{
+ label: decodeHtml(lang_statistics_number_of_qso_worked_each_month),
+ data: dataQso,
+ backgroundColor: 'rgba(54, 162, 235, 0.2)',
+ borderColor: 'rgba(54, 162, 235, 1)',
+ borderWidth: 2,
+ color: color
+ }]
+ },
+ options: {
+ scales: {
+ y: {
+ ticks: {
+ beginAtZero: true,
+ color: color
+ }
+ },
+ x: {
+ ticks: {
+ color: color
+ }
+ }
+ },
+ plugins: {
+ legend: {
+ labels: {
+ color: color
+ }
+ }
+
+ }
+ }
+ });
+ $('.monthtable').DataTable({
+ responsive: false,
+ ordering: false,
+ "scrollY": "320px",
+ "scrollCollapse": true,
+ "paging": false,
+ "scrollX": true,
+ "language": {
+ url: getDataTablesLanguageUrl(),
+ },
+ bFilter: false,
+ bInfo: false
+ });
+
+ // using this to change color of csv-button if dark mode is chosen
+ var background = $('body').css("background-color");
+
+ if (background != ('rgb(255, 255, 255)')) {
+ $(".buttons-csv").css("color", "white");
+ }
+ }
+ }
+ });
+}
+
function totalModeQsos() {
// using this to change color of legend and label according to background color
var color = ifDarkModeThemeReturn('white', 'grey');