Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 13:31, 30 January 2026 by Esportsamaze (talk | contribs)

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
-- ============================================================
-- The "Blue Theme" Color for Heatmaps (RGB: 59, 130, 246 is #3b82f6)
local HEATMAP_R, HEATMAP_G, HEATMAP_B = 59, 130, 246 

-- Standard Header Mapping (DB Field -> Display Name)
local HEADERS = {
    -- BASICS
    rank = "#",
    team = "Team",
    player = "Player",
    matches_played = "Matches", -- RENAMED FIELD
    
    -- 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 = "🥇", -- 1st
    place_2 = "🥈", -- 2nd
    place_3 = "🥉", -- 3rd
    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: Calculate Heatmap Color
-- ============================================================
local function getHeatmapStyle(value, maxVal)
    if not tonumber(value) or not tonumber(maxVal) or maxVal == 0 then return "" end
    local v = tonumber(value)
    
    -- Calculate opacity (0.05 to 0.5 to keep text readable)
    local ratio = v / maxVal
    local alpha = 0.05 + (ratio * 0.45) 
    
    -- Return CSS
    return string.format("background-color: rgba(%d, %d, %d, %.2f);", HEATMAP_R, HEATMAP_G, HEATMAP_B, alpha)
end

-- ============================================================
-- MAIN GENERATOR
-- ============================================================
function p.main(frame)
    local args = frame:getParent().args
    local type = args.type or "player" -- 'player' or 'team'
    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
        -- Default defaults
        if type == "player" then 
            colKeys = {"rank", "player", "team", "matches_played", "finishes", "damage", "headshots", "assists"}
        else 
            colKeys = {"rank", "team", "matches_played", "total_pts", "wwcd", "top_5"}
        end
    else
        colKeys = text.split(colsInput, ",")
    end
    
    -- 2. Fetch Data
    local table_name = (type == "player") and "Player_Stats" or "Team_Stats"
    local fields = table.concat(colKeys, ",")
    local where = string.format("tournament='%s' AND map='%s'", tournament:gsub("'", "\\'"), map)
    
    -- We select ALL fields to perform math, even if not displayed
    local results = cargo.query(table_name, fields .. ", 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
    
    -- 3. Pre-Process: Find Max Values for Heatmap
    local maxValues = {}
    for _, row in ipairs(results) do
        for _, key in ipairs(colKeys) do
            -- Clean and check number
            local val = tonumber(row[key]) or 0
            if val > (maxValues[key] or 0) then
                maxValues[key] = val
            end
        end
    end
    
    -- 4. Build Table
    local root = html.create('div'):addClass('stats-table-wrapper')
    local tbl = root:tag('table'):addClass('wikitable flat-table sortable stats-table')
    
    -- Headers
    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
    
    -- 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 rawVal = row[cleanKey]
            local cell = tr:tag('td')
            
            -- Special Formatting
            if cleanKey == "rank" then
                cell:wikitext(i) -- Auto-rank based on sort
                cell:css("font-weight", "bold")
            elseif cleanKey == "team" then
                cell:wikitext('[[' .. (rawVal or "") .. ']]')
                cell:css("text-align", "left")
            elseif cleanKey == "player" then
                cell:wikitext('[[' .. (rawVal or "") .. ']]')
                cell:css("text-align", "left")
                cell:css("font-weight", "bold")
            else
                -- Numeric Data
                cell:wikitext(rawVal)
                cell:css("text-align", "center")
                
                -- Heatmap Application
                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