Modul:PopulationChart

Izvor: Hrvatska internetska enciklopedija
Inačica 787815 od 19. srpanj 2026. u 09:54 koju je unio WikiSysop (razgovor | doprinosi)
Prijeđi na navigaciju Prijeđi na pretraživanje
Dokumentacija modula


local p = {}

-- Napredna funkcija koja agresivno čisti sve ne-numeričke skrivene znakove
local function splitCSV(str)
    local t = {}
    if not str then return t end
    
    -- Ukloni HTML komentare ako ih ima
    str = string.gsub(str, "<!--.--->", "")
    
    -- Razlomi niz preko zareza
    for value in string.gmatch(str, "([^,]+)") do
        -- Očisti sve razmake, prijelome redaka (\n), tabulatore (\t) i skrivene znakove
        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

    -- Ako modul ne nađe podatke, ispisat će točan broj koji je uspio pročitati radi lakšeg debugiranja
    if n == 0 or #pops ~= n then
        return '<strong class="error">Greška u grafikonu: Broj učitanih godina (' .. n .. ') i broj stanovnika (' .. #pops .. ') se ne podudaraju. Provjerite jesu li svi zarezi ispravno postavljeni.</strong>'
    end

    -- Konfiguracija grafikona
    local svgWidth   = tonumber(args.svg_width)   or 800
    local svgHeight  = tonumber(args.svg_height)  or 300
    local svgPadding = tonumber(args.svg_padding) or 25 -- Malo povećan padding za bolji izgled točaka
    local lineColor  = args.line_color            or "#007bff"

    -- Pronalaženje statistike
    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 innerWidth  = svgWidth - (svgPadding * 2)
    local innerHeight = svgHeight - (svgPadding * 2)
    local divisor = maxv > 0 and maxv or 1

    -- Izrada SVG-a
    local points = {}
    local circles = {}
    for i, v in ipairs(pops) do
        local x = svgPadding
        if n > 1 then
            x = svgPadding + ((i - 1) * (innerWidth / (n - 1)))
        end
        local y = svgHeight - svgPadding - ((v / divisor) * innerHeight)
        
        table.insert(points, string.format("%.1f,%.1f", x, y))
        table.insert(circles, string.format(
            '<circle cx="%.1f" cy="%.1f" r="5" fill="%s" stroke="#ffffff" stroke-width="2"><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" style="width:100%%; height:auto;" xmlns="http://www.w3.org/2000/svg">
  <polyline fill="none" stroke="%s" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" points="%s" />
  %s
</svg>]], svgWidth, svgHeight, lineColor, table.concat(points, " "), table.concat(circles, "\n"))

    -- Izrada Bar Chart-a (Stupaca)
    local bars = {}
    for i = 1, n do
        local trend = "equal"
        if i > 1 then
            if pops[i] > pops[i-1] then
                trend = "up"
            elseif pops[i] < pops[i-1] then
                trend = "down"
            end
        end
        
        local width = math.floor((pops[i] / divisor) * 100)
        table.insert(bars, string.format([[<div class="population-bar">
  <div class="population-year">%d</div>
  <div class="population-bar-wrapper">
    <div class="population-value %s" style="width:%d%%;" title="Godina %d: %d stanovnika">
      <span>%d</span>
    </div>
  </div>
</div>]], years[i], trend, width, years[i], pops[i], pops[i]))
    end

    local stats = string.format([[<div class="population-stats">
  <strong>Najviše:</strong> %d stanovnika<br>
  <strong>Najmanje:</strong> %d stanovnika<br>
  <strong>Prosjek:</strong> %d stanovnika<br>
  <strong>Ukupno popisa:</strong> %d
</div>]], maxv, minv, math.floor(sum / n), n)

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

return p