<% // Mobile sparkline helper — parametrised, used only in this partial function renderSparkline(values, opts) { opts = opts || {}; var w = opts.w || 70; var h = opts.h || 26; if (!values || values.length < 2) return ''; var min = Math.min.apply(null, values); var max = Math.max.apply(null, values); var range = max - min || 1; var xStep = w / (values.length - 1); var pts = values.map(function(v, i) { return { x: (i * xStep).toFixed(1), y: (((max - v) / range) * (h - 4) + 2).toFixed(1) }; }); var linePath = pts.map(function(p, i) { return (i === 0 ? 'M' : 'L') + ' ' + p.x + ' ' + p.y; }).join(' '); var last = pts[pts.length - 1]; var areaPath = linePath + ' L ' + last.x + ' ' + h + ' L 0 ' + h + ' Z'; return ''; } %> <% if (ratings.length === 0) { %>

No players tracked yet.

<% } else { %>
TRACKED PLAYERS · <%= ratings.length %>
<% ratings.forEach(function(player, index) { var sparkSvg = renderSparkline(player.monthlyHistory || [], { w: 70, h: 26 }); var isFirst = index === 0; var rank = index + 1; var ratingIsNull = (player.rating == null); var ratingCls = ratingIsNull ? 'flat' : (player.ratingChange > 0 ? 'up' : player.ratingChange < 0 ? 'down' : 'flat'); var ratingGlyph = (ratingIsNull || player.ratingChange === 0) ? '–' : (player.ratingChange > 0 ? '▲' : '▼'); var ratingNum = ratingIsNull ? '—' : (player.ratingChange > 0 ? '+' + player.ratingChange : String(player.ratingChange)); var predIsNull = (player.predictedRating == null); var predCls = predIsNull ? 'flat' : (player.deltaPredicted > 0 ? 'up' : player.deltaPredicted < 0 ? 'down' : 'flat'); var predGlyph = (predIsNull || player.deltaPredicted === 0) ? '–' : (player.deltaPredicted > 0 ? '▲' : '▼'); var predNum = predIsNull ? '—' : (player.deltaPredicted > 0 ? '+' + player.deltaPredicted : String(player.deltaPredicted)); %> <% }); %>
<% } %>