Module:ElectionStats: Difference between revisions

From Elections Wiki
Jump to navigation Jump to search
Created page with "local json = mw.text.jsonDecode local p = {} function p.generateCards(frame) local dataPage = 'Data:Election Data.json' local success, data = p.loadJson(dataPage) if not success then return "could not load JSON data from " .. dataPage .. "!" end local currentTime = os.time() local counts = { Local = 0, General = 0, Statewide = 0, Referendum = 0 } local total = 0 for _, elections in pairs(data) do for _, election in ipai..."
 
grid
Line 27: Line 27:
     end
     end


     local result = {}
     local cards = {}
     for electionType, count in pairs(counts) do
     for electionType, count in pairs(counts) do
         if count > 0 then
         if count > 0 then
             table.insert(result, p.generateCard(electionType, count))
             table.insert(cards, p.generateCard(electionType, count))
         end
         end
     end
     end
   
    table.insert(result, p.generateCard("Total", total))


     return table.concat(result, "\n")
     table.insert(cards, p.generateCard("Total", total))
 
    local electionGrid = '<div class="election-grid">\n' .. table.concat(cards, "\n") .. '\n</div>'
    return electionGrid
end
end


Line 68: Line 69:
     return string.format(
     return string.format(
         [[
         [[
<div style="width: 200px; height: 250px; background-color: #1C408C; color: white; text-align: center; border: 1px solid #1C408C; padding: 10px; font-family: Arial, sans-serif; display: flex; flex-direction: column; justify-content: center; align-items: center;">
<div class="election-card">
   <div style="font-size: 2em; font-weight: bold; line-height: 1.5;">%d</div>
   <div class="card-number">%d</div>
   <div style="border-top: 2px solid white; width: 80%%; margin: 10px 0;"></div>
   <div class="card-divider"></div>
   <div style="font-size: 1em; text-transform: uppercase; line-height: 1.5;">%s Elections</div>
   <div class="card-text">%s Elections</div>
</div>
</div>
         ]],
         ]],

Revision as of 00:12, 26 January 2025

Documentation for this module may be created at Module:ElectionStats/doc

local json = mw.text.jsonDecode
local p = {}

function p.generateCards(frame)
    local dataPage = 'Data:Election Data.json'
    local success, data = p.loadJson(dataPage)
    if not success then
        return "could not load JSON data from " .. dataPage .. "!"
    end

    local currentTime = os.time()

    local counts = { Local = 0, General = 0, Statewide = 0, Referendum = 0 }
    local total = 0

    for _, elections in pairs(data) do
        for _, election in ipairs(elections) do
            local electionType = election.election_type
            local electionDate = p.parseDate(election.date)
            if electionDate and electionDate <= currentTime then
                if counts[electionType] then
                    counts[electionType] = counts[electionType] + 1
                    total = total + 1
                end
            end
        end
    end

    local cards = {}
    for electionType, count in pairs(counts) do
        if count > 0 then
            table.insert(cards, p.generateCard(electionType, count))
        end
    end

    table.insert(cards, p.generateCard("Total", total))

    local electionGrid = '<div class="election-grid">\n' .. table.concat(cards, "\n") .. '\n</div>'
    return electionGrid
end

function p.loadJson(page)
    local title = mw.title.new(page)
    if not title or not title.exists then
        return false, nil
    end
    local content = title:getContent()
    return true, json(content)
end

function p.parseDate(dateString)
    local pattern = "(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)"
    local year, month, day, hour, min, sec = dateString:match(pattern)
    if year and month and day and hour and min and sec then
        return os.time({
            year = tonumber(year),
            month = tonumber(month),
            day = tonumber(day),
            hour = tonumber(hour),
            min = tonumber(min),
            sec = tonumber(sec)
        })
    else
        return nil
    end
end

function p.generateCard(electionType, count)
    return string.format(
        [[
<div class="election-card">
  <div class="card-number">%d</div>
  <div class="card-divider"></div>
  <div class="card-text">%s Elections</div>
</div>
        ]],
        count,
        electionType
    )
end

return p