refactor: move std-dev info to accordion, remove tooltip (#19)
- Add "Round spread" row (±stdDev, range lo–hi) to desktop accordion (player-history.ejs) and mobile card expanded section (ratings-cards.ejs) - Remove .std-dev-tooltip div and .std-dev-inline span from table partial - Remove stdDevTooltipText, updateStdDevInline, initRatingsTooltips helpers and all call sites from players.js - Remove .std-dev-tooltip and .std-dev-inline CSS rules; drop cursor:help from .rating-value
This commit is contained in:
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
.rating-value {
|
.rating-value {
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
cursor: help;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pdga-number {
|
.pdga-number {
|
||||||
@@ -47,12 +46,6 @@
|
|||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
.std-dev-inline {
|
|
||||||
color: var(--text-muted);
|
|
||||||
font-size: 12px;
|
|
||||||
font-variant-numeric: tabular-nums;
|
|
||||||
}
|
|
||||||
|
|
||||||
.difference {
|
.difference {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
@@ -101,24 +94,6 @@
|
|||||||
box-shadow: var(--shadow-lg);
|
box-shadow: var(--shadow-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Tooltips ─────────────────────────────────── */
|
|
||||||
|
|
||||||
.std-dev-tooltip {
|
|
||||||
position: fixed;
|
|
||||||
background: var(--navy-900);
|
|
||||||
color: var(--text-inverse);
|
|
||||||
padding: 6px 10px;
|
|
||||||
border-radius: var(--radius-sm);
|
|
||||||
font-size: 12px;
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 10000;
|
|
||||||
display: none;
|
|
||||||
white-space: pre;
|
|
||||||
box-shadow: var(--shadow-lg);
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Debug Icon ───────────────────────────────── */
|
/* ── Debug Icon ───────────────────────────────── */
|
||||||
|
|
||||||
.debug-icon:hover {
|
.debug-icon:hover {
|
||||||
|
|||||||
@@ -26,27 +26,6 @@ function applyDeltaPill(pillEl, value) {
|
|||||||
pillEl.appendChild(numSpan);
|
pillEl.appendChild(numSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Std-dev helpers ───────────────────────────────
|
|
||||||
function stdDevTooltipText(rating, stdDev) {
|
|
||||||
return `Spridning: ±${stdDev} poäng\nIntervall: ${rating - stdDev}–${rating + stdDev}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateStdDevInline(predStack, stdDev) {
|
|
||||||
if (!predStack) return;
|
|
||||||
let stdDevInline = predStack.querySelector('.std-dev-inline');
|
|
||||||
if (stdDev) {
|
|
||||||
if (!stdDevInline) {
|
|
||||||
stdDevInline = document.createElement('span');
|
|
||||||
stdDevInline.className = 'std-dev-inline mono';
|
|
||||||
predStack.appendChild(stdDevInline);
|
|
||||||
}
|
|
||||||
stdDevInline.textContent = '±' + stdDev;
|
|
||||||
stdDevInline.style.display = '';
|
|
||||||
} else if (stdDevInline) {
|
|
||||||
stdDevInline.style.display = 'none';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function initChartsIn(rootEl) {
|
function initChartsIn(rootEl) {
|
||||||
rootEl.querySelectorAll('.player-chart').forEach(function(container) {
|
rootEl.querySelectorAll('.player-chart').forEach(function(container) {
|
||||||
if (container.dataset.charted === 'true') return;
|
if (container.dataset.charted === 'true') return;
|
||||||
@@ -78,7 +57,6 @@ function setupAfterTableSwap() {
|
|||||||
document.body.addEventListener('htmx:afterSwap', function(event) {
|
document.body.addEventListener('htmx:afterSwap', function(event) {
|
||||||
const target = event.detail.target;
|
const target = event.detail.target;
|
||||||
if (target.id === 'ratings-table') {
|
if (target.id === 'ratings-table') {
|
||||||
initRatingsTooltips();
|
|
||||||
initChartsIn(target);
|
initChartsIn(target);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -88,19 +66,6 @@ function setupAfterTableSwap() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function initRatingsTooltips() {
|
|
||||||
document.querySelectorAll('.rating-value').forEach(span => {
|
|
||||||
const pdgaNumber = span.dataset.pdga;
|
|
||||||
const rating = parseInt(span.dataset.rating);
|
|
||||||
const stdDev = parseInt(span.dataset.stddev);
|
|
||||||
const tooltip = document.getElementById(`tooltip-rating-${pdgaNumber}`);
|
|
||||||
|
|
||||||
if (rating && stdDev && tooltip) {
|
|
||||||
setupTooltip(span, tooltip, () => stdDevTooltipText(rating, stdDev));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function togglePlayerHistory(pdgaNumber) {
|
function togglePlayerHistory(pdgaNumber) {
|
||||||
const historyRow = document.getElementById('history-' + pdgaNumber);
|
const historyRow = document.getElementById('history-' + pdgaNumber);
|
||||||
const contentDiv = document.getElementById('history-content-' + pdgaNumber);
|
const contentDiv = document.getElementById('history-content-' + pdgaNumber);
|
||||||
@@ -200,14 +165,6 @@ async function refreshPlayer(pdgaNumber) {
|
|||||||
if (ratingValue) {
|
if (ratingValue) {
|
||||||
ratingValue.textContent = data.player.rating || 'N/A';
|
ratingValue.textContent = data.player.rating || 'N/A';
|
||||||
ratingValue.dataset.rating = data.player.rating || '';
|
ratingValue.dataset.rating = data.player.rating || '';
|
||||||
|
|
||||||
const stdDev = parseInt(ratingValue.dataset.stddev);
|
|
||||||
const rating = parseInt(data.player.rating);
|
|
||||||
const tooltip = document.getElementById(`tooltip-rating-${pdgaNumber}`);
|
|
||||||
|
|
||||||
if (rating && stdDev && tooltip) {
|
|
||||||
replaceWithTooltip(ratingValue, tooltip, () => stdDevTooltipText(rating, stdDev));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const deltaMonthPill = ratingCell ? ratingCell.querySelector('.delta-pill') : null;
|
const deltaMonthPill = ratingCell ? ratingCell.querySelector('.delta-pill') : null;
|
||||||
@@ -239,8 +196,6 @@ async function refreshRoundHistory(pdgaNumber) {
|
|||||||
if (predictedValue) {
|
if (predictedValue) {
|
||||||
predictedValue.textContent = data.predictedRating || 'N/A';
|
predictedValue.textContent = data.predictedRating || 'N/A';
|
||||||
predictedValue.dataset.stddev = data.stdDev || '';
|
predictedValue.dataset.stddev = data.stdDev || '';
|
||||||
|
|
||||||
updateStdDevInline(predictedValue.closest('.pred-stack'), data.stdDev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,14 +204,6 @@ async function refreshRoundHistory(pdgaNumber) {
|
|||||||
const ratingValue = ratingCell ? ratingCell.querySelector('.rating-value') : null;
|
const ratingValue = ratingCell ? ratingCell.querySelector('.rating-value') : null;
|
||||||
if (ratingValue && data.stdDev) {
|
if (ratingValue && data.stdDev) {
|
||||||
ratingValue.dataset.stddev = data.stdDev;
|
ratingValue.dataset.stddev = data.stdDev;
|
||||||
|
|
||||||
const rating = parseInt(ratingValue.dataset.rating);
|
|
||||||
const stdDev = parseInt(data.stdDev);
|
|
||||||
const ratingTooltip = document.getElementById(`tooltip-rating-${pdgaNumber}`);
|
|
||||||
|
|
||||||
if (rating && stdDev && ratingTooltip) {
|
|
||||||
replaceWithTooltip(ratingValue, ratingTooltip, () => stdDevTooltipText(rating, stdDev));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -772,7 +719,6 @@ async function refreshHistoryThenCalculate(pdgaNumber) {
|
|||||||
if (predictedValue) {
|
if (predictedValue) {
|
||||||
predictedValue.textContent = data.predictedRating || 'N/A';
|
predictedValue.textContent = data.predictedRating || 'N/A';
|
||||||
predictedValue.dataset.stddev = data.stdDev || '';
|
predictedValue.dataset.stddev = data.stdDev || '';
|
||||||
updateStdDevInline(predictedValue.closest('.pred-stack'), data.stdDev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,12 @@ const chartPdgaNumber = hasPlayer ? player.pdgaNumber : pdgaNumber;
|
|||||||
<dt>Gap to predicted</dt>
|
<dt>Gap to predicted</dt>
|
||||||
<dd><%- include('delta-pill', { value: player.deltaPredicted, extraClass: 'delta-predicted-pill' }) %></dd>
|
<dd><%- include('delta-pill', { value: player.deltaPredicted, extraClass: 'delta-predicted-pill' }) %></dd>
|
||||||
</div>
|
</div>
|
||||||
|
<% if (player.stdDev != null && player.rating) { %>
|
||||||
|
<div>
|
||||||
|
<dt>Round spread</dt>
|
||||||
|
<dd>±<%= player.stdDev %> (range <%= player.rating - player.stdDev %>–<%= player.rating + player.stdDev %>)</dd>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
</dl>
|
</dl>
|
||||||
<button class="link-btn" onclick="showDebugInfo(<%= player.pdgaNumber %>)" style="margin-top: 4px;">View calculation details →</button>
|
<button class="link-btn" onclick="showDebugInfo(<%= player.pdgaNumber %>)" style="margin-top: 4px;">View calculation details →</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -114,6 +114,12 @@ function renderSparkline(values, opts) {
|
|||||||
<dt>Gap to predicted</dt>
|
<dt>Gap to predicted</dt>
|
||||||
<dd><span class="delta-pill <%= predCls %> delta-predicted-pill"><span class="delta-glyph"><%= predGlyph %></span><span class="delta-num"><%= predNum %></span></span></dd>
|
<dd><span class="delta-pill <%= predCls %> delta-predicted-pill"><span class="delta-glyph"><%= predGlyph %></span><span class="delta-num"><%= predNum %></span></span></dd>
|
||||||
</div>
|
</div>
|
||||||
|
<% if (player.stdDev != null && player.rating) { %>
|
||||||
|
<div>
|
||||||
|
<dt>Round spread</dt>
|
||||||
|
<dd>±<%= player.stdDev %> (range <%= player.rating - player.stdDev %>–<%= player.rating + player.stdDev %>)</dd>
|
||||||
|
</div>
|
||||||
|
<% } %>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -67,14 +67,12 @@ function renderSparkline(values, opts) {
|
|||||||
<% } else { %>
|
<% } else { %>
|
||||||
<span class="rating-pending">Click to load</span>
|
<span class="rating-pending">Click to load</span>
|
||||||
<% } %>
|
<% } %>
|
||||||
<div class="std-dev-tooltip" id="tooltip-rating-<%= player.pdgaNumber %>"></div>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="col-predicted" id="predicted-<%= player.pdgaNumber %>">
|
<td class="col-predicted" id="predicted-<%= player.pdgaNumber %>">
|
||||||
<% if (player.predictedRating) { %>
|
<% if (player.predictedRating) { %>
|
||||||
<div class="pred-stack">
|
<div class="pred-stack">
|
||||||
<span class="predicted-value pred-num mono" data-stddev="<%= player.stdDev || '' %>" data-pdga="<%= player.pdgaNumber %>"><%= player.predictedRating %></span>
|
<span class="predicted-value pred-num mono" data-stddev="<%= player.stdDev || '' %>" data-pdga="<%= player.pdgaNumber %>"><%= player.predictedRating %></span>
|
||||||
<%- include('delta-pill', { value: player.deltaPredicted, extraClass: 'delta-predicted-pill' }) %>
|
<%- include('delta-pill', { value: player.deltaPredicted, extraClass: 'delta-predicted-pill' }) %>
|
||||||
<% if (player.stdDev != null) { %><span class="std-dev-inline mono">±<%= player.stdDev %></span><% } %>
|
|
||||||
</div>
|
</div>
|
||||||
<% } else { %>
|
<% } else { %>
|
||||||
<span class="rating-pending">—</span>
|
<span class="rating-pending">—</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user