--
-- VREMENSKI OKVIR
--
w = {};
local args = {}
local w_table
wbc = require("Module:Vremenski_okvir/Boje");
wbd = require("Module:Vremenski_okvir/Dijagram");
math_mod = require('Module:Math');
local months = {"jan", "feb", "mar", "apr", "maj", "jun",
"jul", "aug", "sep", "okt", "nov", "dec"}
local CONSTANTS = {mean = 0, sum = 1}
-- 'months arguments'
local m_arg_table = {
mean_temperature = { par = 'pt_', label = 'Prosječna temperatura (°C)' },
max_temperature = { par = 'vt_', label = 'Najviša prosječna temperatura (°C)' },
min_temperature = { par = 'nt_', label = 'Najniža prosječna temperatura (°C)' },
precipitation = { par = 'p_', label = 'Padavine (mm)' },
rainy_days = { par = 'kd_', label = 'Broj kišnih dana' },
humidity = { par = 'vz_', label = 'Prosječna vlažnost zraka (%)' },
sunshine_hours = { par = 'ss_', label = 'Broj sunčanih sati (h/danu)' }
}
-- other arguments
local arg_table = {
title = { par = 'naslov', label = '' },
source = { par = 'izvor', label = 'Izvor' },
diagram = { par = 'dijagram', label = ''}
}
local function renderHeader()
local header = w_table:tag('tr')
:css('background-color', '#eee')
:css('text-align', 'center')
header:tag('td')
:attr('scope', 'col')
:css('width', '200px')
:css('min-width', '140px')
for i,v in ipairs(months) do
header:tag('th')
:attr('scope', 'col')
:css('width', '40px')
:wikitext(v:sub(1,1):upper() .. v:sub(2))
end
header:tag('td')
:attr('scope', 'col')
header:tag('th')
:attr('scope', 'col')
:css('width', '40px')
end
local function addRow(rowArgs)
local row = w_table:tag('tr')
:css('text-align', 'center')
local label = row:tag('td')
:attr('scope', 'col')
if rowArgs.label then
label:wikitext(rowArgs.label)
:css('text-align', 'left')
:css('font-size', '85%')
end
local m_index = 0
local total = 0
for i,v in ipairs(months) do
local temp = row:tag('td')
:attr('scope', 'col')
if rowArgs[v] then
-- Lets the user use ',' instead of '.' i.e. 27,9 (27.9 works too).
local to_dot = mw.ustring.gsub(rowArgs[v], ",", ".")
local to_no = math_mod._cleanNumber(to_dot)
if to_no ~= nil then
m_index = m_index+1
total = total + to_no
temp:wikitext( (mw.ustring.gsub( (mw.ustring.gsub( rowArgs[v], "%-", "−") ), "%.", ",") ) )
local color = rowArgs.color_func(to_no)
temp:css('background-color', color.background)
temp:css('color', color.color)
else
temp:wikitext("-")
end
else
temp:wikitext("-")
end
end
local total_sign = row:tag('th')
:attr('scope', 'col')
:css('padding', '0 5px')
local m_value = math.floor((total/m_index) * 10 + 0.5) / 10
local m_color = rowArgs.color_func(m_value)
local total_col = row:tag('td')
:attr('scope', 'col')
:css('background-color', m_color.background)
:css('color', m_color.color)
if rowArgs.total_type == CONSTANTS.mean then
total_sign:wikitext("Ø")
total_col:wikitext((mw.ustring.gsub( (mw.ustring.gsub( m_value, "%-", "−") ), "%.", ",") ))
elseif rowArgs.total_type == CONSTANTS.sum then
total_sign:wikitext("Σ")
total_col:wikitext((mw.ustring.gsub( (mw.ustring.gsub( total, "%-", "−") ), "%.", ",") ))
end
end
local function renderRow(label, name, color_func, total_type)
local temp_table = {}
for i,val in pairs(months) do
temp_table[val] = args[name .. val]
end
if tableIsEmpty(temp_table) then
return
end
temp_table['label'] = label
temp_table['color_func'] = color_func
temp_table['total_type'] = total_type
addRow(temp_table)
end
local function renderDiagram()
local temp_table = {}
local temp_p_table = {}
local temp_mit_table = {}
local temp_mat_table = {}
for i,val in pairs(months) do
temp_p_table[val] = args[m_arg_table.precipitation.par .. val]
temp_mit_table[val] = args[m_arg_table.min_temperature.par .. val]
temp_mat_table[val] = args[m_arg_table.max_temperature.par .. val]
end
if tableIsEmpty(temp_p_table) and
(tableIsEmpty(temp_mit_table) or tableIsEmpty(temp_mat_table)) then
return
end
temp_table = {
precipitation = temp_p_table,
minTemperature = temp_mit_table,
maxTemperature = temp_mat_table,
state = args[arg_table.diagram.par]
}
w_table:tag('tr')
:tag('td')
:attr('colspan', '15')
:wikitext(wbd.diagram(temp_table))
end
local function _weather_box()
-- (table) root
w_table = mw.html.create():tag('table')
:attr('cellspacing', '1')
:attr('cellpadding', '0')
:css('margin', 'auto')
:css('background', '#f9f9f9')
:css('border', '1px solid #A9A9A9')
:css('margin-bottom', '.5em')
:css('margin-top', '.5em')
:css('padding', '2px')
:css('font-size', '95%')
-- title
if args[arg_table.title.par] then
w_table:tag('tr')
:tag('th')
:attr('colspan', '15')
:css('background-color', '#eee')
:css('font-style', 'italic')
:css('text-align', 'center')
:wikitext(args[arg_table.title.par])
end
renderHeader()
renderRow(m_arg_table.mean_temperature.label, m_arg_table.mean_temperature.par,
wbc._temperature_color, CONSTANTS.mean)
renderRow(m_arg_table.max_temperature.label, m_arg_table.max_temperature.par,
wbc._temperature_color, CONSTANTS.mean)
renderRow(m_arg_table.min_temperature.label, m_arg_table.min_temperature.par,
wbc._temperature_color, CONSTANTS.mean)
renderRow(m_arg_table.precipitation.label, m_arg_table.precipitation.par,
wbc._precipitation_color, CONSTANTS.sum)
renderRow(m_arg_table.rainy_days.label, m_arg_table.rainy_days.par,
wbc._rainy_days, CONSTANTS.sum)
renderRow(m_arg_table.humidity.label, m_arg_table.humidity.par,
wbc._humidity, CONSTANTS.mean)
renderRow(m_arg_table.sunshine_hours.label, m_arg_table.sunshine_hours.par,
wbc._sunshine_hours, CONSTANTS.mean)
-- TODO: if args[arg_table.diagram.par] == 'no' -> do not render?
renderDiagram()
-- source
if args[arg_table.source.par] ~= nil then
w_table:tag('tr')
:tag('td')
:attr('colspan', '15')
:css('font-size', '85%')
:wikitext(arg_table.source.label .. ': '
.. args[arg_table.source.par])
end
return tostring(w_table)
end
local function preprocessSingleArg(argName)
-- If the argument exists and isn't blank, add it to the argument table.
-- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
if (origArgs[argName] and origArgs[argName] ~= '') then
args[argName] = origArgs[argName]
end
end
-- preProcessArgs: first argument the parameter,
-- the second a table containing string that will be appended
-- to the parameter e.g. _type = 'a_' and _table = {'1', '2'}
-- the function will process arguments 'a_1' and 'a_2'.
local function preprocessArgs(_type, _table)
if type(_type) ~= 'string' then
error("Invalid type value detected", 2)
end
if _table == nil then
if origArgs[_type] then
preprocessSingleArg(_type)
end
else
for i,v in ipairs(_table) do
local prefixArgName = _type .. v
if origArgs[prefixArgName] then
preprocessSingleArg(prefixArgName)
end
end
end
end
function tableIsEmpty(t)
if t == nil then
return true
end
for _, _ in pairs(t) do
return false
end
return true
end
function w.weather_box(frame)
-- If called via #invoke, use the args passed into the invoking template.
-- Otherwise, for testing purposes, assume args are being passed directly in.
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
else
origArgs = frame
end
for i,val in pairs(m_arg_table) do
preprocessArgs(val.par, months)
end
for i,val in pairs(arg_table) do
preprocessArgs(val.par, nil)
end
return _weather_box()
end
return w