Modul:PopulationChart: razlika između inačica

Izvor: Hrvatska internetska enciklopedija
Prijeđi na navigaciju Prijeđi na pretraživanje
mNema sažetka uređivanja
mNema sažetka uređivanja
 
Nije prikazano 5 međuinačica
Redak 1: Redak 1:
local p = {}
local p = {}


-- Čišćenje skrivenih znakova i prelamanje po zarezu
local function splitCSV(str)
local function splitCSV(str)
     local t = {}
     local t = {}
     for value in string.gmatch(str or "", "([^,]+)") do
    if not str then return t end
         value = mw.text.trim(value)
    str = string.gsub(str, "<!--.--->", "")
         table.insert(t, tonumber(value))
     for value in string.gmatch(str, "([^,]+)") do
         value = string.gsub(value, "[%s%c]", "")
        local num = tonumber(value)
         if num then
            table.insert(t, num)
        end
     end
     end
     return t
     return t
Redak 11: Redak 17:


function p.render(frame)
function p.render(frame)
     local args = frame:getParent() and frame:getParent().args or frame.args
     local args = frame:getParent() and frame:getParent().args or frame.args
 
     local years = splitCSV(args.years)
     local years = splitCSV(args.years)
     local pops  = splitCSV(args.pops)
     local pops  = splitCSV(args.pops)
    local n = #years


    local n = #years
     if n == 0 or #pops ~= n then
     if n == 0 or #pops ~= n then
         return "<strong>Greška: broj godina i broj stanovnika se ne podudara.</strong>"
         return '<strong class="error">Greška u grafikonu: Broj godina i stanovnika se ne podudara.</strong>'
     end
     end


    -- Konfiguracija (možeš mijenjati iz predloška)
     local barColor = args.line_color or "#3366cc"
     local svgWidth  = tonumber(args.svg_width)  or 800
    local svgHeight  = tonumber(args.svg_height)  or 300
    local svgPadding = tonumber(args.svg_padding) or 20
    local lineColor  = args.line_color           or "#007bff"


     -- Statistika
     -- Statistika
Redak 31: Redak 32:
     local minv = pops[1]
     local minv = pops[1]
     local sum  = 0
     local sum  = 0
 
     for _, v in ipairs(pops) do
     for _,v in ipairs(pops) do
         if v > maxv then maxv = v end
         if v > maxv then maxv = v end
         if v < minv then minv = v end
         if v < minv then minv = v end
         sum = sum + v
         sum = sum + v
     end
     end
    local divisor = maxv > 0 and maxv or 1


     local innerHeight = svgHeight - svgPadding * 2
     local lang = mw.language.getContentLanguage()
 
    -- SVG polyline + tooltipovi
    local points = {}
    local circles = {}
 
    for i,v in ipairs(pops) do
        local x = (i-1) * (svgWidth / math.max(1,(n-1)))
        local y = svgHeight - svgPadding - (v / maxv * innerHeight)
 
        table.insert(points, string.format("%.1f,%.1f", x, y))
 
        table.insert(circles, string.format(
            '<circle cx="%.1f" cy="%.1f" r="4" fill="%s"><title>Godina %d: %d stanovnika</title></circle>',
            x, y, lineColor, years[i], v
        ))
    end
 
    local svg = string.format([[
<svg class="population-linechart" viewBox="0 0 %d %d" preserveAspectRatio="none">
  <polyline fill="none" stroke="%s" stroke-width="3" points="%s" />
  %s
</svg>
]], svgWidth, svgHeight, lineColor, table.concat(points, " "), table.concat(circles, "\n"))


     -- Bar chart s animacijom
     -- Početak tablice
     local bars = {}
     local html = {}
    table.insert(html, '<table class="wikitable" style="width:100%; max-width:500px; font-size:90%; margin:10px 0;">')
    table.insert(html, '<tr><th style="width:20%; text-align:center;">Godina</th><th style="width:30%; text-align:right;">Stanovnika</th><th style="width:50%;">Trend</th></tr>')


     for i=1,n do
    -- Redovi (izbjegnut bilo kakav format, čisto spajanje)
         local trend = "equal"
     for i = 1, n do
         local percentage = math.floor((pops[i] / divisor) * 100)
        local pctString = tostring(percentage) .. "%"
       
        local trendIndicator = ""
         if i > 1 then
         if i > 1 then
             if pops[i] > pops[i-1] then
             if pops[i] > pops[i-1] then
                 trend = "up"
                 trendIndicator = ' <span style="color:#28a745;">▲</span>'
             elseif pops[i] < pops[i-1] then
             elseif pops[i] < pops[i-1] then
                 trend = "down"
                 trendIndicator = ' <span style="color:#dc3545;">▼</span>'
            else
                trendIndicator = ' <span style="color:#6c757d;">■</span>'
             end
             end
         end
         end


         local width = math.floor((pops[i] / maxv) * 100)
         local formattedPop = lang:formatNum(pops[i])
        local currentYear = tostring(years[i])


         table.insert(bars, string.format([[
         local row = '<tr>' ..
<div class="population-bar">
            '<td style="text-align:center; font-weight:bold; background:#f8f9fa;">' .. currentYear .. '</td>' ..
  <div class="population-year">%d</div>
            '<td style="text-align:right; white-space:nowrap; padding-right:8px;">' .. formattedPop .. trendIndicator .. '</td>' ..
  <div class="population-value %s" style="width:%d%%;" data-tooltip="Godina %d: %d stanovnika">
            '<td style="vertical-align:middle; padding:4px 8px;">' ..
    <span>%d</span>
                '<div style="background:#e9ecef; border-radius:2px; width:100%; height:12px;">' ..
  </div>
                    '<div style="background:' .. barColor .. '; width:' .. pctString .. '; height:100%; border-radius:2px;"></div>' ..
</div>
                '</div>' ..
]], years[i], trend, width, years[i], pops[i], pops[i]))
            '</td>' ..
        '</tr>'
       
        table.insert(html, row)
     end
     end


     local stats = string.format([[
    -- Dno tablice
<div class="population-stats">
     local formattedAvg = lang:formatNum(math.floor(sum / n))
Najviše: %d stanovnika<br>
    local formattedMin = lang:formatNum(minv)
Najmanje: %d stanovnika<br>
    local formattedMax = lang:formatNum(maxv)
Prosjek: %d stanovnika<br>
   
Ukupno godina: %d
    local footer = '<tr style="background:#f8f9fa; font-weight:bold; border-top:2px solid #a2a9b1;">' ..
</div>
        '<td colspan="3" style="font-size:85%; padding:6px; color:#54595d;">' ..
]], maxv, minv, math.floor(sum/n), n)
            'Ukupno popisa: ' .. tostring(n) .. ' | Prosjek: ' .. formattedAvg .. ' | Raspon: ' .. formattedMin .. ' - ' .. formattedMax ..
        '</td>' ..
    '</tr>'
   
    table.insert(html, footer)
    table.insert(html, '</table>')


     return '<div class="population-wrapper">' .. table.concat(bars, "\n") .. svg .. stats .. '</div>'
     return table.concat(html, "\n")
end
end


return p
return p

Posljednja izmjena od 19. srpanj 2026. u 10:34

Dokumentacija modula


local p = {}

-- Čišćenje skrivenih znakova i prelamanje po zarezu
local function splitCSV(str)
    local t = {}
    if not str then return t end
    str = string.gsub(str, "<!--.--->", "")
    for value in string.gmatch(str, "([^,]+)") do
        value = string.gsub(value, "[%s%c]", "")
        local num = tonumber(value)
        if num then
            table.insert(t, num)
        end
    end
    return t
end

function p.render(frame)
    local args = frame:getParent() and frame:getParent().args or frame.args
    local years = splitCSV(args.years)
    local pops  = splitCSV(args.pops)
    local n = #years

    if n == 0 or #pops ~= n then
        return '<strong class="error">Greška u grafikonu: Broj godina i stanovnika se ne podudara.</strong>'
    end

    local barColor = args.line_color or "#3366cc"

    -- Statistika
    local maxv = pops[1]
    local minv = pops[1]
    local sum  = 0
    for _, v in ipairs(pops) do
        if v > maxv then maxv = v end
        if v < minv then minv = v end
        sum = sum + v
    end
    local divisor = maxv > 0 and maxv or 1

    local lang = mw.language.getContentLanguage()

    -- Početak tablice
    local html = {}
    table.insert(html, '<table class="wikitable" style="width:100%; max-width:500px; font-size:90%; margin:10px 0;">')
    table.insert(html, '<tr><th style="width:20%; text-align:center;">Godina</th><th style="width:30%; text-align:right;">Stanovnika</th><th style="width:50%;">Trend</th></tr>')

    -- Redovi (izbjegnut bilo kakav format, čisto spajanje)
    for i = 1, n do
        local percentage = math.floor((pops[i] / divisor) * 100)
        local pctString = tostring(percentage) .. "%"
        
        local trendIndicator = ""
        if i > 1 then
            if pops[i] > pops[i-1] then
                trendIndicator = ' <span style="color:#28a745;">▲</span>'
            elseif pops[i] < pops[i-1] then
                trendIndicator = ' <span style="color:#dc3545;">▼</span>'
            else
                trendIndicator = ' <span style="color:#6c757d;">■</span>'
            end
        end

        local formattedPop = lang:formatNum(pops[i])
        local currentYear = tostring(years[i])

        local row = '<tr>' ..
            '<td style="text-align:center; font-weight:bold; background:#f8f9fa;">' .. currentYear .. '</td>' ..
            '<td style="text-align:right; white-space:nowrap; padding-right:8px;">' .. formattedPop .. trendIndicator .. '</td>' ..
            '<td style="vertical-align:middle; padding:4px 8px;">' ..
                '<div style="background:#e9ecef; border-radius:2px; width:100%; height:12px;">' ..
                    '<div style="background:' .. barColor .. '; width:' .. pctString .. '; height:100%; border-radius:2px;"></div>' ..
                '</div>' ..
            '</td>' ..
        '</tr>'
        
        table.insert(html, row)
    end

    -- Dno tablice
    local formattedAvg = lang:formatNum(math.floor(sum / n))
    local formattedMin = lang:formatNum(minv)
    local formattedMax = lang:formatNum(maxv)
    
    local footer = '<tr style="background:#f8f9fa; font-weight:bold; border-top:2px solid #a2a9b1;">' ..
        '<td colspan="3" style="font-size:85%; padding:6px; color:#54595d;">' ..
            'Ukupno popisa: ' .. tostring(n) .. ' | Prosjek: ' .. formattedAvg .. ' | Raspon: ' .. formattedMin .. ' - ' .. formattedMax ..
        '</td>' ..
    '</tr>'
    
    table.insert(html, footer)
    table.insert(html, '</table>')

    return table.concat(html, "\n")
end

return p