Module:Statistics
From eSportsAmaze
More actions
Documentation for this module may be created at Module:Statistics/doc
local p = {}
local cargo = mw.ext.cargo
local html = mw.html
local text = mw.text
-- ============================================================
-- CONFIGURATION
-- ============================================================
-- Heatmap Color (Blue: 59, 130, 246)
local HEATMAP_R, HEATMAP_G, HEATMAP_B = 59, 130, 246
local HEADERS = {
-- BASICS
rank = "#",
team = "Team",
player = "Player",
matches_played = "Matches",
-- KILLS / OFFENSE
finishes = "Finishes",
fpm = "FPM",
knocks = "Knocks",
damage = "Damage",
headshots = "Headshots",
longest = "Longest",
assists = "Assists",
grenade_kills = "Grenade Kills",
vehicle_kills = "Vehicle Kills",
contribution = "Contrib %",
-- SURVIVAL / SUPPORT
survival = "Surv. Time",
healings = "Heals",
revives = "Revives",
damage_taken = "Dmg Recv",
-- UTILITY
grenades_used = "Nades Used",
smokes_used = "Smokes Used",
utility_used = "Util Used",
-- MOVEMENT
dist_drive = "Drive Dist",
dist_walk = "Walk Dist",
dist_total = "Total Dist",
bluezone = "Bluezone Time",
air_drops = "Air Drops",
-- TEAM SPECIFIC
total_pts = "Total Pts",
place_pts = "Place Pts",
elims = "Elims",
-- AVERAGES (Team)
avg_place = "Avg Place",
avg_place_pts = "Avg Place Pts",
avg_elims = "Avg Elims",
avg_total = "Avg Pts",
-- PLACEMENT COUNTS
wwcd = "🥇",
place_2 = "🥈",
place_3 = "🥉",
top_5 = "Top 5",
top_8 = "Top 8",
place_low = "> 8th",
-- POINT BUCKETS
g_0 = "0",
g_1_5 = "1–5",
g_6_10 = "6–10",
g_11_15 = "11–15",
g_16_20 = "16–20",
g_20_plus = "20+"
}
-- Columns that should NOT get a heatmap background
local NO_HEATMAP = { rank=true, team=true, player=true, matches_played=true }
-- ============================================================
-- HELPER: Heatmap Style
-- ============================================================
local function getHeatmapStyle(value, maxVal)
if not tonumber(value) or not tonumber(maxVal) or maxVal == 0 then return "" end
local v = tonumber(value)
local ratio = v / maxVal
local alpha = 0.05 + (ratio * 0.45)
return string.format("background-color: rgba(%d, %d, %d, %.2f);", HEATMAP_R, HEATMAP_G, HEATMAP_B, alpha)
end
-- ============================================================
-- HELPER: Get Team Logo
-- ============================================================
local function getTeamLogo(teamName)
if not teamName then return "" end
local cleanName = teamName:gsub("'", "")
local lightFile = cleanName .. '.png'
local darkFile = cleanName .. '_dark.png'
local hasLight = mw.title.new('File:' .. lightFile).exists
local hasDark = mw.title.new('File:' .. darkFile).exists
local html = ""
-- Light Mode
if hasLight then
html = html .. '[[File:' .. lightFile .. '|25px|link=' .. teamName .. '|class=logo-lightmode]]'
else
html = html .. '[[File:Shield_team.png|25px|link=' .. teamName .. '|class=logo-lightmode]]'
end
-- Dark Mode
if hasDark then
html = html .. '[[File:' .. darkFile .. '|25px|link=' .. teamName .. '|class=logo-darkmode]]'
elseif hasLight then
html = html .. '[[File:' .. lightFile .. '|25px|link=' .. teamName .. '|class=logo-darkmode]]'
else
html = html .. '[[File:Shield_team_dark.png|25px|link=' .. teamName .. '|class=logo-darkmode]]'
end
return html .. " "
end
-- ============================================================
-- MAIN GENERATOR
-- ============================================================
function p.main(frame)
local args = frame:getParent().args
local type = args.type or "player"
local tournament = args.tournament or mw.title.getCurrentTitle().subpageText
local map = args.map or "All"
-- 1. Determine Columns to Show
local colsInput = args.columns or ""
local colKeys = {}
if colsInput == "" then
if type == "player" then
colKeys = {"rank", "player", "team", "matches_played", "finishes", "damage"}
else
colKeys = {"rank", "team", "matches_played", "total_pts", "wwcd"}
end
else
colKeys = text.split(colsInput, ",")
end
-- 2. Build Query Fields (Exclude 'rank' from SQL)
local queryFields = {}
for _, k in ipairs(colKeys) do
local cleanK = k:match("^%s*(.-)%s*$")
if cleanK ~= "rank" then -- Don't ask DB for 'rank'
table.insert(queryFields, cleanK)
end
end
local table_name = (type == "player") and "Player_Stats" or "Team_Stats"
local fieldsSQL = table.concat(queryFields, ",")
local where = string.format("tournament='%s' AND map='%s'", tournament:gsub("'", "\\'"), map)
-- 3. Fetch Data
local results = cargo.query(table_name, fieldsSQL .. ", team", {
where = where,
orderBy = (type == "player" and "finishes DESC" or "total_pts DESC"),
limit = 100
})
if not results or #results == 0 then
return '<div style="padding:20px; color:#666;">No statistics available for ' .. map .. '.</div>'
end
-- 4. Find Max Values
local maxValues = {}
for _, row in ipairs(results) do
for _, key in ipairs(queryFields) do
local val = tonumber(row[key]) or 0
if val > (maxValues[key] or 0) then maxValues[key] = val end
end
end
-- 5. Build Table
local root = html.create('div'):addClass('stats-table-wrapper')
local tbl = root:tag('table'):addClass('wikitable flat-table sortable stats-table')
-- Header Row
local trHead = tbl:tag('tr')
for _, key in ipairs(colKeys) do
local label = HEADERS[key:match("^%s*(.-)%s*$")] or key:upper()
trHead:tag('th'):wikitext(label)
end
-- Data Rows
for i, row in ipairs(results) do
local tr = tbl:tag('tr')
for _, key in ipairs(colKeys) do
local cleanKey = key:match("^%s*(.-)%s*$")
local cell = tr:tag('td')
if cleanKey == "rank" then
-- Auto-generate Rank (1, 2, 3...)
cell:wikitext(i .. '.')
cell:css("font-weight", "bold")
cell:css("text-align", "center")
elseif cleanKey == "team" then
local teamName = row.team or ""
cell:wikitext(getTeamLogo(teamName) .. '[[' .. teamName .. ']]')
cell:css("text-align", "left")
cell:css("white-space", "nowrap")
elseif cleanKey == "player" then
cell:wikitext('[[' .. (row.player or "") .. ']]')
cell:css("text-align", "left")
cell:css("font-weight", "bold")
else
-- Numeric Data
local rawVal = row[cleanKey]
cell:wikitext(rawVal)
cell:css("text-align", "center")
-- Heatmap
if not NO_HEATMAP[cleanKey] then
local style = getHeatmapStyle(rawVal, maxValues[cleanKey])
if style ~= "" then
cell:attr("style", style .. " text-align:center;")
end
end
end
end
end
return tostring(root)
end
return p