Modul:Timeline: razlika između inačica
Prijeđi na navigaciju
Prijeđi na pretraživanje
Nema sažetka uređivanja |
Nema sažetka uređivanja |
||
| Redak 10: | Redak 10: | ||
end | end | ||
function | local function yearToY(year, minYear, scale, startY) | ||
return startY + (year - minYear) * scale | |||
end | |||
-- generička mapa boja za generacije | |||
local function getGenColor(args, gen) | |||
if not gen or gen == "" then return nil end | |||
-- korisnik može prepisati boju generacije npr. gencolor_nano=#aabbcc | |||
local override = args["gencolor_" .. gen] | |||
if override and override ~= "" then return override end | |||
local map = { | |||
classic = "#bfc9ff", | |||
nano = "#c9f0b5", | |||
mini = "#d7f5c3", | |||
shuffle = "#ffd27f", | |||
touch = "#e0e0e0", | |||
main = "#b3d9ff", | |||
plus = "#ffd9b3", | |||
se = "#c9f0b5", | |||
} | |||
return map[gen] | |||
end | |||
-- generički renderer | |||
local function buildTimeline(frame) | |||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local minYear = tonumber(args.minYear) or 2000 | local minYear = tonumber(args.minYear) or 2000 | ||
local maxYear = tonumber(args.maxYear) or 2030 | local maxYear = tonumber(args.maxYear) or 2030 | ||
local scale = tonumber(args.scale) or 60 | local scale = tonumber(args.scale) or 60 | ||
local | local orientation = (args.orientation or "horizontal"):lower() | ||
local | local startMain = 60 -- start X ili Y za os vremena | ||
local padding = 80 | |||
local svg = {} | local svg = {} | ||
- | if orientation == "vertical" then | ||
local height = startMain + (maxYear - minYear) * scale + padding | |||
if height < 300 then height = 300 end | |||
table.insert(svg, string.format( | |||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 %d" role="img">', | |||
height | |||
)) | |||
table.insert(svg, '<rect x="0" y="0" width="100%" height="100%" fill="white" />') | |||
-- vremenska os (vertical) | |||
table.insert(svg, '<g font-family="sans-serif" font-size="10" fill="#555">') | |||
local yEnd = yearToY(maxYear, minYear, scale, startMain) | |||
table.insert(svg, string.format( | |||
'<line x1="80" y1="%d" x2="80" y2="%d" stroke="#aaa" />', | |||
startMain, yEnd | |||
)) | |||
for y = minYear, maxYear do | |||
local yy = yearToY(y, minYear, scale, startMain) | |||
table.insert(svg, string.format('<text x="50" y="%d">%d</text>', yy + 4, y)) | |||
end | |||
table.insert(svg, '</g>') | |||
-- redovi | |||
local rowIndex = 1 | |||
while args["row" .. rowIndex .. "_label"] do | |||
local label = args["row" .. rowIndex .. "_label"] | |||
local x = tonumber(args["row" .. rowIndex .. "_x"]) or (120 + (rowIndex - 1) * 120) | |||
table.insert(svg, string.format( | |||
'<text x="%d" y="40" font-family="sans-serif" font-size="11" fill="#333">%s</text>', | |||
x, esc(label) | |||
)) | |||
local blockIndex = 1 | |||
while args[string.format("row%d_block%d_start", rowIndex, blockIndex)] do | |||
local start = tonumber(args[string.format("row%d_block%d_start", rowIndex, blockIndex)]) | |||
local stop = tonumber(args[string.format("row%d_block%d_end", rowIndex, blockIndex)]) or maxYear | |||
local text = args[string.format("row%d_block%d_label", rowIndex, blockIndex)] or "" | |||
local tip = args[string.format("row%d_block%d_tip", rowIndex, blockIndex)] | |||
local icon = args[string.format("row%d_block%d_icon", rowIndex, blockIndex)] or "" | |||
local col = args[string.format("row%d_block%d_color", rowIndex, blockIndex)] | |||
local gen = args[string.format("row%d_block%d_gen", rowIndex, blockIndex)] | |||
if not col or col == "" then | |||
col = args["row" .. rowIndex .. "_color"] | |||
end | |||
if (not col or col == "") and gen and gen ~= "" then | |||
col = getGenColor(args, gen) | |||
end | |||
if not col or col == "" then | |||
col = "#cccccc" | |||
end | |||
local y1 = yearToY(start, minYear, scale, startMain) | |||
local y2 = yearToY(stop, minYear, scale, startMain) | |||
local h = y2 - y1 | |||
if h < 6 then h = 6 end | |||
if not tip or tip == "" then | |||
tip = string.format("%s (%s–%s)", text, tostring(start), tostring(stop)) | |||
end | |||
table.insert(svg, '<g font-family="sans-serif" font-size="9" fill="#000">') | |||
table.insert(svg, string.format( | |||
'<rect x="%d" y="%d" width="90" height="%d" fill="%s"><title>%s</title></rect>', | |||
x - 10, y1, h, esc(col), esc(tip) | |||
)) | |||
local labelText = icon ~= "" and (icon .. " " .. esc(text)) or esc(text) | |||
table.insert(svg, string.format( | |||
'<text x="%d" y="%d" transform="rotate(90 %d %d)">%s</text>', | |||
x + 5, y1 + h/2, x + 5, y1 + h/2, labelText | |||
)) | |||
table.insert(svg, '</g>') | |||
blockIndex = blockIndex + 1 | |||
end | |||
rowIndex = rowIndex + 1 | |||
end | |||
-- | else | ||
-- HORIZONTALNI TIMELINE | |||
local width = startMain + (maxYear - minYear) * scale + padding | |||
if width < 400 then width = 400 end | |||
table.insert(svg, string.format( | |||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 %d 300" role="img">', | |||
width | |||
)) | |||
table.insert(svg, '<rect x="0" y="0" width="100%" height="100%" fill="white" />') | |||
-- | -- vremenska os | ||
table.insert(svg, '<g font-family="sans-serif" font-size="10" fill="#555">') | |||
local xEnd = yearToX(maxYear, minYear, scale, startMain) | |||
table.insert(svg, string.format( | table.insert(svg, string.format( | ||
'< | '<line x1="%d" y1="30" x2="%d" y2="30" stroke="#aaa" />', | ||
startMain, xEnd | |||
)) | )) | ||
for y = minYear, maxYear do | |||
local xx = yearToX(y, minYear, scale, startMain) | |||
table.insert(svg, string.format('<text x="%d" y="25">%d</text>', xx, y)) | |||
local | end | ||
table.insert(svg, '</g>') | |||
-- redovi | |||
local | local rowIndex = 1 | ||
local | while args["row" .. rowIndex .. "_label"] do | ||
local label = args["row" .. rowIndex .. "_label"] | |||
local y = tonumber(args["row" .. rowIndex .. "_y"]) or (50 + rowIndex * 40) | |||
table.insert(svg, string.format( | table.insert(svg, string.format( | ||
'< | '<text x="10" y="%d" font-family="sans-serif" font-size="11" fill="#333">%s</text>', | ||
y, esc(label) | |||
)) | )) | ||
local | local blockIndex = 1 | ||
while args[string.format("row%d_block%d_start", rowIndex, blockIndex)] do | |||
local start = tonumber(args[string.format("row%d_block%d_start", rowIndex, blockIndex)]) | |||
local stop = tonumber(args[string.format("row%d_block%d_end", rowIndex, blockIndex)]) or maxYear | |||
local text = args[string.format("row%d_block%d_label", rowIndex, blockIndex)] or "" | |||
local tip = args[string.format("row%d_block%d_tip", rowIndex, blockIndex)] | |||
local icon = args[string.format("row%d_block%d_icon", rowIndex, blockIndex)] or "" | |||
local col = args[string.format("row%d_block%d_color", rowIndex, blockIndex)] | |||
local gen = args[string.format("row%d_block%d_gen", rowIndex, blockIndex)] | |||
if not col or col == "" then | |||
'<text x="%d" y="%d">%s</text>', | col = args["row" .. rowIndex .. "_color"] | ||
end | |||
if (not col or col == "") and gen and gen ~= "" then | |||
col = getGenColor(args, gen) | |||
end | |||
if not col or col == "" then | |||
col = "#cccccc" | |||
end | |||
local x1 = yearToX(start, minYear, scale, startMain) | |||
local x2 = yearToX(stop, minYear, scale, startMain) | |||
local w = x2 - x1 | |||
if w < 6 then w = 6 end | |||
if not tip or tip == "" then | |||
tip = string.format("%s (%s–%s)", text, tostring(start), tostring(stop)) | |||
end | |||
table.insert(svg, '<g font-family="sans-serif" font-size="9" fill="#000">') | |||
table.insert(svg, string.format( | |||
'<rect x="%d" y="%d" width="%d" height="14" fill="%s"><title>%s</title></rect>', | |||
x1, y - 10, w, esc(col), esc(tip) | |||
)) | |||
local labelText = icon ~= "" and (icon .. " " .. esc(text)) or esc(text) | |||
table.insert(svg, string.format( | |||
'<text x="%d" y="%d">%s</text>', | |||
x1 + 3, y, labelText | |||
)) | |||
table.insert(svg, '</g>') | |||
blockIndex = blockIndex + 1 | |||
end | |||
rowIndex = rowIndex + 1 | |||
end | end | ||
end | end | ||
table.insert(svg, '</svg>') | table.insert(svg, '</svg>') | ||
return table.concat(svg, "\n") | return table.concat(svg, "\n") | ||
end | |||
function p.render(frame) | |||
return buildTimeline(frame) | |||
end | end | ||
return p | return p | ||
Inačica od 12. siječanj 2026. u 13:00
Script error: The function "nonexistent" does not exist.
local p = {}
local function esc(s)
if not s then return "" end
return s:gsub("&","&"):gsub("<","<"):gsub(">",">")
end
local function yearToX(year, minYear, scale, startX)
return startX + (year - minYear) * scale
end
local function yearToY(year, minYear, scale, startY)
return startY + (year - minYear) * scale
end
-- generička mapa boja za generacije
local function getGenColor(args, gen)
if not gen or gen == "" then return nil end
-- korisnik može prepisati boju generacije npr. gencolor_nano=#aabbcc
local override = args["gencolor_" .. gen]
if override and override ~= "" then return override end
local map = {
classic = "#bfc9ff",
nano = "#c9f0b5",
mini = "#d7f5c3",
shuffle = "#ffd27f",
touch = "#e0e0e0",
main = "#b3d9ff",
plus = "#ffd9b3",
se = "#c9f0b5",
}
return map[gen]
end
-- generički renderer
local function buildTimeline(frame)
local args = frame:getParent().args
local minYear = tonumber(args.minYear) or 2000
local maxYear = tonumber(args.maxYear) or 2030
local scale = tonumber(args.scale) or 60
local orientation = (args.orientation or "horizontal"):lower()
local startMain = 60 -- start X ili Y za os vremena
local padding = 80
local svg = {}
if orientation == "vertical" then
local height = startMain + (maxYear - minYear) * scale + padding
if height < 300 then height = 300 end
table.insert(svg, string.format(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 %d" role="img">',
height
))
table.insert(svg, '<rect x="0" y="0" width="100%" height="100%" fill="white" />')
-- vremenska os (vertical)
table.insert(svg, '<g font-family="sans-serif" font-size="10" fill="#555">')
local yEnd = yearToY(maxYear, minYear, scale, startMain)
table.insert(svg, string.format(
'<line x1="80" y1="%d" x2="80" y2="%d" stroke="#aaa" />',
startMain, yEnd
))
for y = minYear, maxYear do
local yy = yearToY(y, minYear, scale, startMain)
table.insert(svg, string.format('<text x="50" y="%d">%d</text>', yy + 4, y))
end
table.insert(svg, '</g>')
-- redovi
local rowIndex = 1
while args["row" .. rowIndex .. "_label"] do
local label = args["row" .. rowIndex .. "_label"]
local x = tonumber(args["row" .. rowIndex .. "_x"]) or (120 + (rowIndex - 1) * 120)
table.insert(svg, string.format(
'<text x="%d" y="40" font-family="sans-serif" font-size="11" fill="#333">%s</text>',
x, esc(label)
))
local blockIndex = 1
while args[string.format("row%d_block%d_start", rowIndex, blockIndex)] do
local start = tonumber(args[string.format("row%d_block%d_start", rowIndex, blockIndex)])
local stop = tonumber(args[string.format("row%d_block%d_end", rowIndex, blockIndex)]) or maxYear
local text = args[string.format("row%d_block%d_label", rowIndex, blockIndex)] or ""
local tip = args[string.format("row%d_block%d_tip", rowIndex, blockIndex)]
local icon = args[string.format("row%d_block%d_icon", rowIndex, blockIndex)] or ""
local col = args[string.format("row%d_block%d_color", rowIndex, blockIndex)]
local gen = args[string.format("row%d_block%d_gen", rowIndex, blockIndex)]
if not col or col == "" then
col = args["row" .. rowIndex .. "_color"]
end
if (not col or col == "") and gen and gen ~= "" then
col = getGenColor(args, gen)
end
if not col or col == "" then
col = "#cccccc"
end
local y1 = yearToY(start, minYear, scale, startMain)
local y2 = yearToY(stop, minYear, scale, startMain)
local h = y2 - y1
if h < 6 then h = 6 end
if not tip or tip == "" then
tip = string.format("%s (%s–%s)", text, tostring(start), tostring(stop))
end
table.insert(svg, '<g font-family="sans-serif" font-size="9" fill="#000">')
table.insert(svg, string.format(
'<rect x="%d" y="%d" width="90" height="%d" fill="%s"><title>%s</title></rect>',
x - 10, y1, h, esc(col), esc(tip)
))
local labelText = icon ~= "" and (icon .. " " .. esc(text)) or esc(text)
table.insert(svg, string.format(
'<text x="%d" y="%d" transform="rotate(90 %d %d)">%s</text>',
x + 5, y1 + h/2, x + 5, y1 + h/2, labelText
))
table.insert(svg, '</g>')
blockIndex = blockIndex + 1
end
rowIndex = rowIndex + 1
end
else
-- HORIZONTALNI TIMELINE
local width = startMain + (maxYear - minYear) * scale + padding
if width < 400 then width = 400 end
table.insert(svg, string.format(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 %d 300" role="img">',
width
))
table.insert(svg, '<rect x="0" y="0" width="100%" height="100%" fill="white" />')
-- vremenska os
table.insert(svg, '<g font-family="sans-serif" font-size="10" fill="#555">')
local xEnd = yearToX(maxYear, minYear, scale, startMain)
table.insert(svg, string.format(
'<line x1="%d" y1="30" x2="%d" y2="30" stroke="#aaa" />',
startMain, xEnd
))
for y = minYear, maxYear do
local xx = yearToX(y, minYear, scale, startMain)
table.insert(svg, string.format('<text x="%d" y="25">%d</text>', xx, y))
end
table.insert(svg, '</g>')
-- redovi
local rowIndex = 1
while args["row" .. rowIndex .. "_label"] do
local label = args["row" .. rowIndex .. "_label"]
local y = tonumber(args["row" .. rowIndex .. "_y"]) or (50 + rowIndex * 40)
table.insert(svg, string.format(
'<text x="10" y="%d" font-family="sans-serif" font-size="11" fill="#333">%s</text>',
y, esc(label)
))
local blockIndex = 1
while args[string.format("row%d_block%d_start", rowIndex, blockIndex)] do
local start = tonumber(args[string.format("row%d_block%d_start", rowIndex, blockIndex)])
local stop = tonumber(args[string.format("row%d_block%d_end", rowIndex, blockIndex)]) or maxYear
local text = args[string.format("row%d_block%d_label", rowIndex, blockIndex)] or ""
local tip = args[string.format("row%d_block%d_tip", rowIndex, blockIndex)]
local icon = args[string.format("row%d_block%d_icon", rowIndex, blockIndex)] or ""
local col = args[string.format("row%d_block%d_color", rowIndex, blockIndex)]
local gen = args[string.format("row%d_block%d_gen", rowIndex, blockIndex)]
if not col or col == "" then
col = args["row" .. rowIndex .. "_color"]
end
if (not col or col == "") and gen and gen ~= "" then
col = getGenColor(args, gen)
end
if not col or col == "" then
col = "#cccccc"
end
local x1 = yearToX(start, minYear, scale, startMain)
local x2 = yearToX(stop, minYear, scale, startMain)
local w = x2 - x1
if w < 6 then w = 6 end
if not tip or tip == "" then
tip = string.format("%s (%s–%s)", text, tostring(start), tostring(stop))
end
table.insert(svg, '<g font-family="sans-serif" font-size="9" fill="#000">')
table.insert(svg, string.format(
'<rect x="%d" y="%d" width="%d" height="14" fill="%s"><title>%s</title></rect>',
x1, y - 10, w, esc(col), esc(tip)
))
local labelText = icon ~= "" and (icon .. " " .. esc(text)) or esc(text)
table.insert(svg, string.format(
'<text x="%d" y="%d">%s</text>',
x1 + 3, y, labelText
))
table.insert(svg, '</g>')
blockIndex = blockIndex + 1
end
rowIndex = rowIndex + 1
end
end
table.insert(svg, '</svg>')
return table.concat(svg, "\n")
end
function p.render(frame)
return buildTimeline(frame)
end
return p