Browse Source

ACA score plots: Cache results in Redis, improve graph readability

master
Fabian Kurz 6 months ago
parent
commit
9e5e8cadce
  1. 29
      api.php
  2. 24
      functions.php
  3. 2
      index.php
  4. 86
      scores-by-call.php
  5. 2
      scores.php

29
api.php

@ -481,6 +481,9 @@
exit();
}
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$calls = explode(',', $_GET['calls']);
$ret = Array();
@ -490,16 +493,24 @@
if (!is_call($c))
continue;
$ret[$c] = Array();
$data = $redis->get("plotACA".$c);
$date = new DateTime("$year-01-01");
for ($i = 1; $i <= 52; $i++) {
$date->modify('next tuesday');
$tue = $date->format('Y-m-d');
$q = mysqli_query($db, "SELECT count(distinct(`nr`)) from cwops_log where `mycall`='$c' and year=YEAR(CURDATE()) and date <= '$tue'");
$r = mysqli_fetch_row($q);
$aca = $r[0];
array_push($ret[$c], $aca);
if ($data) {
$ret[$c] = unserialize($data);
}
else {
$ret[$c] = Array();
$date = new DateTime("$year-01-01");
for ($i = 1; $i <= 52; $i++) {
$date->modify('next tuesday');
$tue = $date->format('Y-m-d');
$q = mysqli_query($db, "SELECT count(distinct(`nr`)) from cwops_log where `mycall`='$c' and year=YEAR(CURDATE()) and date <= '$tue'");
$r = mysqli_fetch_row($q);
$aca = $r[0];
array_push($ret[$c], $aca);
}
$redis->set('plotACA'.$c, serialize($ret[$c]), 60*60*24);
}
}

24
functions.php

@ -1175,6 +1175,13 @@ function score_table_by_call() {
<script>
function update_table(f) {
try {
plot_calls = [];
}
catch (e) {
}
filter = f;
// check for filter callsigns
@ -1201,7 +1208,7 @@ function score_table_by_call() {
var tbl = document.createElement('table');
var tr = tbl.insertRow();
tr.innerHTML = "<th>Rank</th><th onmouseup='update_table(0);'>Call</th><th onmouseup='update_table(1);'>ACA</th><th onmouseup='update_table(2);'>CMA</th><th onmouseup='update_table(3);'>DXCC</th><th onmouseup='update_table(4);'>WAS</th><th onmouseup='update_table(5);'>WAE</th><th onmouseup='update_table(6);'>WAZ</th><th onmouseup='update_table(7);'>Updated</th>";
tr.innerHTML = "<th>Rank</th><th onmouseup='update_table(0);'>Call</th><th onmouseup='update_table(1);'>ACA</th><th onmouseup='update_table(2);'>CMA</th><th onmouseup='update_table(3);'>DXCC</th><th onmouseup='update_table(4);'>WAS</th><th onmouseup='update_table(5);'>WAE</th><th onmouseup='update_table(6);'>WAZ</th><th onmouseup='update_table(7);'>Updated</th><th>Plot</th>";
var cnt = 0;
var lastscore = 0;
for (var i = 0; i < scores_sort.length; i++) {
@ -1240,8 +1247,21 @@ function score_table_by_call() {
td.appendChild(document.createTextNode(scores_sort[i][j]));
if (j == f) {
td.style.fontWeight = 'bold';
}
}
}
td = tr.insertCell();
var cb = document.createElement('input');
cb.type = 'checkbox';
cb.name = scores_sort[i][0];
cb.addEventListener('change', function () {
try {
plot_update(this.name, this.checked);
}
catch (e) {
console.log("plot_update failed");
}
});
td.appendChild(cb);
}
}
document.getElementById('scoretable').innerHTML = '';

2
index.php

@ -12,7 +12,7 @@ include('functions.php');
</head>
<body>
<h1>CWops Award Tools</h1>
<p>This server provides services for members of <a href="https://cwops.org/">CWops</a>. <a href="/help">Help and Documentation</a> - <a href="/intro">Introduction Video</a> - <a href="/scores">Score table</a></p>
<p>This server provides services for members of <a href="https://cwops.org/">CWops</a>. <a href="/help">Help and Documentation</a> - <a href="/intro">Introduction Video</a> - <a href="/scores">Score table</a> - <a href="/scores-by-call">Search and sortable scores with graphs</a></p>
<h2>ACA, CMA, WAS, WAE and WAZ tracking</h2>
<?

86
scores-by-call.php

@ -7,23 +7,73 @@
<a href="/">Back</a> - <a href="/scores">Score overview</a><br><br>
<!-- div style="float:right;border:1px solid">
<canvas id="c" width="800" height="600">
</canvas>
</div -->
<?php
session_start();
include("functions.php");
?>
<?
echo score_table_by_call();
?>
<div style="position:fixed;top:50px;left:550px">
<h2>ACA Graph</h2>
<canvas id="c" width="800" height="600"></canvas>
<p>The graph shows the ACA score of the selected station(s) on each week's Tuesday (i.e. before the CWTs).</p>
</div>
<script>
var plot_calls = ["<? if ($_SESSION['callsign']) { echo $_SESSION['callsign']; } else { echo "DJ5CW"; }?>"];
var plot_colors = {};
function rc (c) {
if (plot_colors[c]) {
// nothing :-)
}
else {
var a = 'abcdef0123456789';
var ret = '#';
for (var i = 0; i < 6; i++) {
ret += a[Math.floor(Math.random() * a.length)];
}
plot_colors[c] = ret;
}
return plot_colors[c];
}
// called when a checkbox changes
function plot_update(c, e) {
console.log("plot_update: " + c + " " + e);
console.log(plot_calls);
var j = plot_calls.indexOf(c);
if (e == false) {
if (j >= 0) {
plot_calls.splice(j, 1);
}
}
else {
if (j == -1) {
plot_calls.push(c);
}
}
console.log(plot_calls);
plot();
}
function plot() {
console.log("plot...");
var request = new XMLHttpRequest();
request.open("GET", "/api.php?action=plot&type=ACA&year=2021&calls=AA3B,KR2Q,K3WW,N5RZ,N5AW,K3WJV,NA8V,W1RM,K3JT,K7QA,K1VUT,K4WW,KG9X,N7US,VE3KI,WT9U,K3PP,WT3K,W0UO,W9ILY", true);
var pc = plot_calls.join(",");
request.open("GET", "/api.php?action=plot&type=ACA&year=2021&calls="+pc, true);
request.onreadystatechange = function() {
var done = 4, ok = 200;
if (request.readyState == done && request.status == ok) {
@ -34,22 +84,33 @@ function plot() {
var w = c.width;
var h = c.height;
ctx.clearRect(0,0, w, h);
ctx.fillStyle = '#efefef';
ctx.fillRect(0,0, w, h);
// find max value for scaling
var max = 0;
for (call in data) {
data[call].forEach(d => { d = parseInt(d); console.log(d); if (d > max) { max = d; } });
data[call].forEach(d => { d = parseInt(d); if (d > max) { max = d; } });
}
// set top value to next full 500
var max = max - max % 500 + 500;
// horizontal: keep 100 pixels at the end for callsigns
var hw = w - 50;
console.log(data);
// draw a horizontal line for each 500
ctx.strokeStyle = '#999999';
for (var i = 500; i < max; i += 500) {
ctx.fillStyle = 'black';
ctx.fillText(i, 0, h - h/max * i + 4);
ctx.beginPath();
ctx.moveTo(30, h - h/max * i);
ctx.lineTo(hw, h - h/max * i);
ctx.stroke();
}
for (call in data) {
console.log(call);
ctx.beginPath();
var xpos = 0;
var ypos = h;
@ -59,10 +120,12 @@ function plot() {
ypos = h - h/max * data[call][i];
ctx.lineTo(xpos, ypos);
}
ctx.strokeStyle = "red";
ctx.fillStyle = "red";
var col = rc(call);
ctx.strokeStyle = col;
ctx.stroke();
ctx.fillStyle = col;
ctx.fillText(call, xpos + 5, ypos + 3);
ctx.stroke();
}
}
@ -71,6 +134,7 @@ function plot() {
}
plot();
</script>

2
scores.php

@ -4,7 +4,7 @@
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<h2>Score overview</h2>
<a href="/">Back</a> - <a href="/scores-by-call">Sortable and searchable score table</a> - Final scores: <a href="/scores-2020-final">2020</a>, <a href="/scores-2019-final">2019</a><br><br>
<a href="/">Back</a> - <a href="/scores-by-call">Sortable and searchable score table with graphs</a> - Final scores: <a href="/scores-2020-final">2020</a>, <a href="/scores-2019-final">2019</a><br><br>
<?php
session_start();
include("functions.php");

Loading…
Cancel
Save