Graph tweaks

Determine the correct height of the bar from the data-value and the given height of the tbody rather than including an explicit data-height on the bar.

Better algorithm to determine where to draw horizontal lines on the graph.

Only display the top 10 geolocated search locations with the rest falling under "Other", unless there are only 11 locations in the list.
This commit is contained in:
Brian Huisman 2023-11-06 11:27:15 -05:00
parent 9e5dccf8b7
commit 0c1f359ef0
2 changed files with 66 additions and 40 deletions

View file

@ -2706,19 +2706,37 @@ ORCINUS;
</tr> </tr>
</thead> </thead>
<tbody><?php <tbody><?php
foreach ($locCount as $iso => $searches) { ?> $top10 = 0;
<tr> foreach ($locCount as $iso => $searches) {
<th scope="row"><?php if ($top10++ < 10 || $iso == array_key_last($locCount)) { ?>
if (file_exists(__DIR__.'/img/flags/'.strtolower($iso).'.png')) { ?> <tr>
<img src="img/flags/<?php echo strtolower($iso); ?>.png" alt="<?php echo strtoupper($iso); ?>" title="<?php echo $locData[$iso]; ?>" class="svg-icon-flag"><?php <th scope="row"><?php
} else { ?> if (file_exists(__DIR__.'/img/flags/'.strtolower($iso).'.png')) { ?>
<img src="img/help.svg" alt="?" title="<?php echo $locData[$iso]; ?>" class="svg-icon"><?php <img src="img/flags/<?php echo strtolower($iso); ?>.png" alt="<?php echo strtoupper($iso); ?>" title="<?php echo $locData[$iso]; ?>" class="svg-icon-flag"><?php
} ?> } else { ?>
<span class="align-middle"><?php echo $locData[$iso]; ?></span> <img src="img/help.svg" alt="?" title="<?php echo $locData[$iso]; ?>" class="svg-icon"><?php
</th> } ?>
<td class="text-end"><?php echo $searches; ?></td> <span class="align-middle"><?php echo $locData[$iso]; ?></span>
<td class="text-center"><small>(<?php echo round($searches / array_sum($locCount) * 100, 1); ?>%)</small></td> </th>
</tr><?php <td class="text-end"><?php echo $searches; ?></td>
<td class="text-center"><small>(<?php echo round($searches / array_sum($locCount) * 100, 1); ?>%)</small></td>
</tr><?php
} else {
$cap = false; $hits = 0;
foreach ($locCount as $iso2 => $searches2) {
if ($iso2 == $iso) $capture = true;
if ($capture) $hits += $searches2;
} ?>
<tr>
<th scope="row">
<img src="img/help.svg" alt="?" title="Other" class="svg-icon">
<span class="align-middle">Other</span>
</th>
<td class="text-end"><?php echo $hits; ?></td>
<td class="text-center"><small>(<?php echo round($hits / array_sum($locCount) * 100, 1); ?>%)</small></td>
</tr><?php
break;
}
} ?> } ?>
</tbody> </tbody>
</table> </table>
@ -2740,17 +2758,15 @@ ORCINUS;
<li class="list-group-item"> <li class="list-group-item">
<h4>All Searches by Day of Week</h4> <h4>All Searches by Day of Week</h4>
<table class="bar-graph d-flex align-items-end position-relative w-100 gap-1 pt-4 mb-5"> <table class="bar-graph d-flex align-items-end position-relative w-100 gap-1 pt-4 mb-5">
<tbody class="flex-fill d-flex gap-3"><?php <tbody class="flex-fill d-flex gap-3" style="height:14em;"><?php
foreach ($dayWalker as $day => $value) { ?> foreach ($dayWalker as $day => $value) { ?>
<tr class="flex-fill d-flex flex-column justify-content-end<?php <tr class="flex-fill d-flex flex-column justify-content-end<?php
if ($day == 'Sun') echo ' ps-2'; if ($day == array_key_first($dayWalker)) echo ' ps-2';
if ($day == 'Sat') echo ' pe-2'; ?>"> if ($day == array_key_last($dayWalker)) echo ' pe-2'; ?>">
<th class="position-relative p-0"> <th class="position-relative p-0">
<span class="position-absolute top-0 start-50 translate-middle-x"><?php echo $day; ?></span> <span class="position-absolute top-0 start-50 translate-middle-x"><?php echo $day; ?></span>
</th> </th>
<td class="order-first position-relative bg-secondary bg-gradient p-0" data-height="<?php <td class="order-first position-relative bg-secondary bg-gradient p-0" data-value="<?php echo $value; ?>" title="<?php echo $day; ?>">
echo round($value / (max($dayWalker) / 200));
?>" data-value="<?php echo $value; ?>" title="<?php echo $day; ?>">
<small class="position-absolute bottom-100 start-50 translate-middle-x"><?php echo $value; ?></small> <small class="position-absolute bottom-100 start-50 translate-middle-x"><?php echo $value; ?></small>
</td> </td>
</tr><?php </tr><?php
@ -2761,17 +2777,15 @@ ORCINUS;
<li class="list-group-item"> <li class="list-group-item">
<h4>All Searches by Time of Day</h4> <h4>All Searches by Time of Day</h4>
<table class="bar-graph d-flex align-items-end position-relative w-100 gap-1 pt-4 mb-5"> <table class="bar-graph d-flex align-items-end position-relative w-100 gap-1 pt-4 mb-5">
<tbody class="flex-fill d-flex gap-1"><?php <tbody class="flex-fill d-flex gap-1" style="height:14em;"><?php
foreach ($hourWalker as $hour => $value) { ?> foreach ($hourWalker as $hour => $value) { ?>
<tr class="flex-fill d-flex flex-column justify-content-end<?php <tr class="flex-fill d-flex flex-column justify-content-end<?php
if ($hour == '00:00') echo ' ps-2'; if ($hour == array_key_first($hourWalker)) echo ' ps-2';
if ($hour == '23:00') echo ' pe-2'; ?>"> if ($hour == array_key_last($hourWalker)) echo ' pe-2'; ?>">
<th class="position-relative p-0"> <th class="position-relative p-0">
<time class="position-absolute top-0 start-50 translate-middle-x"><?php echo $hour; ?></time> <time class="position-absolute top-0 start-50 translate-middle-x"><?php echo $hour; ?></time>
</th> </th>
<td class="order-first position-relative bg-secondary bg-gradient p-0" data-height="<?php <td class="order-first position-relative bg-secondary bg-gradient p-0" data-value="<?php echo $value; ?>" title="<?php echo $hour; ?>">
echo (max($hourWalker)) ? round($value / (max($hourWalker) / 200)) : 0;
?>" data-value="<?php echo $value; ?>" title="<?php echo $hour; ?>">
<small class="position-absolute bottom-100 start-50 translate-middle-x"><?php echo $value; ?></small> <small class="position-absolute bottom-100 start-50 translate-middle-x"><?php echo $value; ?></small>
</td> </td>
</tr><?php </tr><?php

View file

@ -359,22 +359,25 @@ for (let x = 0; x < os_index_with_selected.length; x++) {
/* ***** Page >> Search Statistics ********************************* */ /* ***** Page >> Search Statistics ********************************* */
let bars = document.querySelectorAll('table.bar-graph td[data-height]'); let bars = document.querySelectorAll('table.bar-graph td[data-value]');
for (let x = 0; x < bars.length; x++) { for (let x = 0; x < bars.length; x++) {
bars[x].style.height = '0px'; bars[x].style.height = '0px';
bars[x].style.transition = 'height 0.8s ease'; bars[x].style.transition = 'height 0.8s ease';
let tb = bars[x].parentNode.parentNode; bars[x].tbody = bars[x].parentNode.parentNode;
if (tb.offsetHeight <= parseInt(bars[x].getAttribute('data-height'))) { if (!bars[x].tbody.dataMaxValue) bars[x].tbody.dataMaxValue = 0;
tb.style.height = bars[x].getAttribute('data-height') + 'px'; bars[x].tbody.dataMaxValue = Math.max(
tb.dataMaxValue = bars[x].getAttribute('data-value'); parseFloat(bars[x].getAttribute('data-value')),
} bars[x].tbody.dataMaxValue
setTimeout((function(elem) { );
elem.style.height = elem.getAttribute('data-height') + 'px';
})(bars[x]), 5); setTimeout((function(elem) { return function() {
elem.style.height = (parseFloat(elem.getAttribute('data-value') / elem.tbody.dataMaxValue) * elem.tbody.offsetHeight) + 'px';
}})(bars[x]), 5);
} }
let graphs = document.querySelectorAll('table.bar-graph'); let graphs = document.querySelectorAll('table.bar-graph');
let ticks = [1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000];
for (let x = 0; x < graphs.length; x++) { for (let x = 0; x < graphs.length; x++) {
let thead = graphs[x].getElementsByTagName('thead'); let thead = graphs[x].getElementsByTagName('thead');
if (!thead.length) { if (!thead.length) {
@ -383,13 +386,23 @@ for (let x = 0; x < graphs.length; x++) {
// Adjust background lines // Adjust background lines
if (tbody.dataMaxValue) { if (tbody.dataMaxValue) {
graphs[x].unitHeight = tbody.offsetHeight / tbody.dataMaxValue; graphs[x].unitHeight = tbody.offsetHeight / tbody.dataMaxValue;
} else graphs[x].unitHeight = tbody.offsetHeight;
// 5 intervals by default? let divisions = 1;
graphs[x].interval = tbody.offsetHeight / 5; do {
graphs[x].interval = tbody.dataMaxValue / divisions;
} while (
graphs[x].interval * graphs[x].unitHeight > 20 &&
divisions < tbody.dataMaxValue &&
divisions++ < tbody.offsetHeight / 50
);
graphs[x].interval = Math.max(1, Math.round(graphs[x].interval / graphs[x].unitHeight / 5) * 5 * graphs[x].unitHeight, graphs[x].unitHeight); let divVal = Math.floor(Math.log10(tbody.dataMaxValue));
graphs[x].interval = Math.max(1, Math.round(graphs[x].interval / ticks[divVal])) * ticks[divVal] * graphs[x].unitHeight;
} else {
graphs[x].unitHeight = tbody.offsetHeight;
graphs[x].interval = tbody.offsetHeight;
}
thead = document.createElement('thead'); thead = document.createElement('thead');
let tr = document.createElement('tr'); let tr = document.createElement('tr');
@ -397,8 +410,7 @@ for (let x = 0; x < graphs.length; x++) {
for (let y = 0; y < Math.ceil(tbody.offsetHeight / graphs[x].interval); y++) { for (let y = 0; y < Math.ceil(tbody.offsetHeight / graphs[x].interval); y++) {
let td = document.createElement('td'); let td = document.createElement('td');
td.classList.add('d-flex', 'flex-column', 'justify-content-end', 'text-end'); td.classList.add('d-flex', 'flex-column', 'justify-content-end', 'text-end');
td.style.height = graphs[x].interval + 'px'; td.style.height = Math.min(tbody.offsetHeight, graphs[x].interval) + 'px';
td.style.transform = 'translatey(0.6em)';
let small = document.createElement('small'); let small = document.createElement('small');
small.appendChild(document.createTextNode(Math.round(y * graphs[x].interval / graphs[x].unitHeight))); small.appendChild(document.createTextNode(Math.round(y * graphs[x].interval / graphs[x].unitHeight)));
td.appendChild(small); td.appendChild(small);