Мы используем файлы cookie.
Продолжая использовать сайт, вы даете свое согласие на работу с этими файлами.
Продолжая использовать сайт, вы даете свое согласие на работу с этими файлами.
Medical cases chart
Подписчиков: 0, рейтинг: 0
Tài liệu mô đun[tạo]
Bạn có thể muốn tạo một trang tài liệu cho mô đun Scribunto này.
Biên tập viên sửa đổi có thể thử nghiệm trong các trang chỗ thử (sửa | khác) và trường hợp kiểm thử (tạo) của mô đun này.
Các trang con của mô đun này.
Biên tập viên sửa đổi có thể thử nghiệm trong các trang chỗ thử (sửa | khác) và trường hợp kiểm thử (tạo) của mô đun này.
Các trang con của mô đun này.
local yesno = require('Module:Yesno')
local barBox = require('Module:Bar box')
local lang = mw.getLanguage("en")
local i18n = require('Module:Medical cases chart/i18n')["vi"]
local monthAbbrs = {}
for i = 1, 12 do
monthAbbrs[i] = lang:formatDate('M', '2020-' .. ('%02d'):format(i))
end
local function is(v)
return (v or '') ~= ''
end
local p = {}
function p._toggleButton(active, customtoggles, id, label)
local on = active and '' or ' mw-collapsed'
local off = active and ' mw-collapsed' or ''
local outString =
'<span class="mw-collapsible' .. on .. customtoggles .. '" id="mw-customcollapsible-' .. id .. '" ' ..
'style="border:2px solid lightblue">' .. p._monthStr(label) .. '</span>' ..
'<span class="mw-collapsible' .. off .. customtoggles .. '" id="mw-customcollapsible-' .. id .. '">' .. p._monthStr(label) .. '</span>'
return outString
end
function p._monthStr (str)
if str == "Jan" then return "Thg 1"
elseif str == "Feb" then return "Thg 2"
elseif str == "Mar" then return "Thg 3"
elseif str == "Apr" then return "Thg 4"
elseif str == "May" then return "Thg 5"
elseif str == "Jun" then return "Thg 6"
elseif str == "Jul" then return "Thg 7"
elseif str == "Aug" then return "Thg 8"
elseif str == "Sep" then return "Thg 9"
elseif str == "Oct" then return "Thg 10"
elseif str == "Nov" then return "Thg 11"
elseif str == "Dec" then return "Thg 12"
end
return str
end
function p._yearToggleButton(year)
return p._toggleButton(year.l, ' mw-customtoggle-' .. year.year, year.year, year.year)
end
function p._monthToggleButton(year, month)
local lmon, label = lang:lc(month.mon), month.mon
local id = (year or '') .. lmon
local customtoggles = ' mw-customtoggle-' .. id
if month.s then
label = label .. ' ' .. month.s -- "Mmm ##"
if month.s ~= month.e then -- "Mmm ##–##"
label = label .. '–' .. month.e
end
else
customtoggles = customtoggles .. (month.l and customtoggles .. month.l or '')
end
for i, combination in ipairs(month.combinations) do
customtoggles = customtoggles .. ' mw-customtoggle-' .. combination -- up to 2 combinations per month so no need to table.concat()
end
return p._toggleButton(false, customtoggles, id, label)
end
function p._lastXToggleButton(years, duration, combinationsL)
local months, id = years[#years].months, 'l' .. duration
local i, customtoggles = #months, {' mw-customtoggle-' .. id}
if #years > 1 then
local year = years[#years].year
while months[i].l do
customtoggles[#customtoggles+1] = ' mw-customtoggle-' .. year .. lang:lc(months[i].mon) .. '-' .. id
if i == 1 then
if year == years[#years].year then
year = years[#years-1].year
months = years[#years-1].months
i = #months
else -- either first month is also lastX month or lastX spans more than 2 years, which is not intended yet
break
end
else
i = i - 1
end
end
else
while i > 0 and months[i].l do
customtoggles[#customtoggles+1] = ' mw-customtoggle-' .. lang:lc(months[i].mon) .. '-' .. id
i = i - 1
end
end
for i, combinationL in ipairs(combinationsL) do
customtoggles[#customtoggles+1] = ' mw-customtoggle-' .. combinationL -- up to 3 combinationsL in 90 days
end
return p._toggleButton(true, table.concat(customtoggles), id, duration .. ' ngày gần nhất')
end
function p._buildTogglesBar(dateList, duration, nooverlap)
local years = {{year=dateList[1].year, months={{mon=dateList[1].mon, combinations={}}}}}
local months, combinationsL = years[1].months, {}
local function addMonth(month)
if month.mon ~= months[#months].mon then -- new month
if month.year ~= years[#years].year then -- new year
years[#years+1] = {year=month.year, months={}}
months = years[#years].months -- switch months list
end
months[#months+1] = {mon=month.mon, combinations={}}
end
end
for i = 2, #dateList do -- deduplicate years and months
if #dateList[i] == 0 then -- specific date
addMonth(dateList[i])
months[#months].l = months[#months].l or dateList[i].l -- so that both ...-mon and ...-mon-lX classes are created
elseif #dateList[i] == 1 then -- interval within month
addMonth(dateList[i][1])
months[#months].l = months[#months].l or dateList[i].l
else -- multimonth interval
for j, month in ipairs(dateList[i]) do
addMonth(month)
months[#months].combinations[#months[#months].combinations+1] = dateList[i].id
end
combinationsL[#combinationsL+1] = dateList[i].id:find('-l%d+$') and dateList[i].id
end
end
if nooverlap then
local lastDate = dateList[#dateList]
months[#months].e = tonumber(os.date('%d', lastDate.nDate or lastDate.nEndDate or lastDate.nAltEndDate)) -- end of final month
local i = #dateList
repeat
i = i - 1
until i == 0 or (dateList[i].mon or dateList[i][1].mon) ~= months[#months].mon
if i == 0 then -- start of first and final month
months[#months].s = tonumber(os.date('%d', dateList[1].nDate))
else
months[#months].s = 1
end
end
years[#years].l = true -- to activate toggle and respective months bar
local monthToggles, divs = {}, nil
if #years > 1 then
local yearToggles, monthsDivs = {}, {}
for i, year in ipairs(years) do
yearToggles[#yearToggles+1] = p._yearToggleButton(year)
monthToggles = {}
months = year.months
for j, month in ipairs(months) do
monthToggles[#monthToggles+1] = p._monthToggleButton(year.year, month)
end
monthsDivs[#monthsDivs+1] =
'<div class="mw-collapsible' .. (year.l and '' or ' mw-collapsed') ..
'" id="mw-customcollapsible-' .. year.year .. '">' .. table.concat(monthToggles) .. '</div>'
end
divs = '<div>' .. table.concat(yearToggles) .. '</div>' .. table.concat(monthsDivs)
else
for i, month in ipairs(months) do
monthToggles[#monthToggles+1] = p._monthToggleButton(nil, month)
end
divs = '<div>' .. table.concat(monthToggles) .. '</div>'
end
divs = divs .. '<div>' .. p._lastXToggleButton(years, duration, combinationsL) .. '</div>'
return '<div class="nomobile" style="text-align:center">' .. divs .. '</div>'
end
local numwidth = {n=0, t=2.45, m=3.5, d=3.5, w=4.55, x=5.6}
local bkgClasses = {
'mcc-d', --tử vong
'mcc-r', --hồi phục
'mcc-c', --số ca hoặc altlbl1
'mcc-a2', --altlbl2
'mcc-a3' --altlbl3
}
function p._customBarStacked(args)
local barargs = {}
barargs[1] = args[1]
-- (next update)
-- local function _numwidth(i)
-- return args.numwidth:sub(i,i)
-- end
local function _numwidth(nw)
if nw == 'n' then
return 0
elseif nw == 't' then
return 2.45
elseif nw == 'm' or nw == 'd' then
return 3.5
elseif nw == 'w' then
return 4.55
elseif nw == 'x' then
return 5.6
end
return 3.5
end
if args[7] or args[8] then -- is it acceptable to have one and not the other?
barargs[2] =
'<span class=mcc-r' .. _numwidth(1) .. '>' .. (args[7] or '') .. '</span>' ..
'<span class=mcc-l' .. _numwidth(2) .. '>' .. (args[8] or '') .. '</span>'
end
if #args.numwidth == 4 then
barargs.note2 = (args[9] or args[10]) and (args.numwidth:sub(3,3) ~= 'n' and '<span class=mcc-r' .. _numwidth(3) .. '>' .. (args[9] or '') .. '</span>' or '') ..
'<span class=mcc-l' .. _numwidth(4) .. '>' .. (args[10] or '') .. '</span>' or ''
local pad = args.numwidth:sub(3, 3) == 'n' and '0' or '0.3em'
end
width1 = 3.5
width2 = 3.5
if is(args.numwidth) then
width1 = _numwidth(mw.ustring.sub(args.numwidth,1,1))
width2 = _numwidth(mw.ustring.sub(args.numwidth,2,2))
width3 = _numwidth(mw.ustring.sub(args.numwidth,3,3))
width4 = _numwidth(mw.ustring.sub(args.numwidth,4,4))
end
barargs[2] =
'<span class="cbs-ibr" style="padding:0 0.3em 0 0; width:' .. width1 .. 'em">' .. (args[7] or '') .. '</span>' ..
'<span class="cbs-ibl" style="width:' .. width2 .. 'em">' .. (args[8] or '') .. '</span>'
if mw.ustring.len(args.numwidth) == 4 then
local padding = '0.3em'
if mw.ustring.sub(args.numwidth,3,3) == 'n' then
padding = '0'
end
barargs.note2 =
'<span class="cbs-ibr" style="padding:0 ' .. padding .. ' 0 0; width:' .. width3 .. 'em">' .. (args[9] or '') .. '</span>' ..
'<span class="cbs-ibl" style="width:' .. width4 .. 'em">' .. (args[10] or '') .. '</span>'
end
for i=1,5 do
barargs[2*i + 1] = p._barColors[i]
barargs[2*i + 2] = (tonumber(args[i+1]) or 0)/(tonumber(args.divisor) or 1)
barargs['title' .. i] = args[i+1]
end
barargs.align = 'cdcc'
barargs.collapsed = args.collapsed
barargs.id = args.id
barargs.rowstyle = is(tonumber(args.rowheight)) and ('line-height:'..args.rowheight..';') or nil
return barBox._stacked(barargs)
end
function p._row(args)
local barargs = {}
barargs[1] = (args[1] or '⋮') .. (args.note0 or '')
barargs[2] = args[2] or 0
barargs[3] = args[3] or 0
if args['alttot1'] then
barargs[4] = args['alttot1']
elseif args[4] then
barargs[4] = (args[4] or 0) - (barargs[2] or 0) - (barargs[3] or 0)
else
barargs[4] = 0
end
barargs[5] = args[5] or 0
if args['alttot2'] then
barargs[6] = args['alttot2']
elseif args[6] then
barargs[6] = (args[6] or 0) - (barargs[2] or 0) - (barargs[3] or 0)
else
barargs[6] = 0
end
barargs[7] = args[7]
local function changeArg(firstright, valuecol, changecol)
local change = ''
if yesno(args['firstright' .. firstright]) == true then
change = '(' .. i18n.na .. ')'
elseif yesno(args['firstright' .. firstright]) == false or not is(args['firstright' .. firstright]) then
if not is(args[1]) and is(args[valuecol]) then
change = '(' .. i18n['='] .. ')'
else
change = is(args[changecol]) and '(' .. args[changecol] .. ')' or ''
end
end
return change
end
barargs[8] = changeArg(1,7,8)
barargs[9] = args[9] or ''
barargs[10] = changeArg(2,9,10)
barargs.divisor = args.divisor
barargs.numwidth = args.numwidth
barargs.rowheight = args.rowheight
local dates
if args.collapsible then
local duration = args.duration
if args.daysToEnd >= duration then
barargs.collapsed = true
else
barargs.collapsed = false
end
if args.nooverlap and args.daysToEnd < duration then
barargs.id = 'l' .. duration
elseif args.nDate then
dates = {year=tonumber(os.date('%Y', args.nDate)), mon=lang:formatDate('M', os.date('%Y-%m', args.nDate)),
l=args.daysToEnd < duration and '-l' .. duration, nDate=args.nDate}
barargs.id = (args.multiyear and dates.year or '') .. lang:lc(dates.mon) .. (dates.l or '')
else
local id, y, m, ey, em = {},
tonumber(os.date('%Y', args.nStartDate or args.nAltStartDate)),
tonumber(os.date('%m', args.nStartDate or args.nAltStartDate)),
tonumber(os.date('%Y', args.nEndDate or args.nAltEndDate )),
tonumber(os.date('%m', args.nEndDate or args.nAltEndDate ))
dates = {nStartDate=args.nStartDate, nAltStartDate=args.nAltStartDate, nEndDate=args.nEndDate, nAltEndDate=args.nAltEndDate}
repeat
id[#id+1] = (args.multiyear and y or '') .. lang:lc(monthAbbrs[m])
dates[#dates+1] = {year=y, mon=monthAbbrs[m]}
y = y + math.floor(m / 12)
m = m % 12 + 1
until y == ey and m > em or y > ey
dates.l = args.daysToEnd < duration and '-l' .. duration
id = table.concat(id, '-') .. (dates.l or '')
barargs.id = id
dates.id = id
end
else
barargs.collapsed = false
end
return p._customBarStacked(barargs), dates
end
function p._buildBars(args)
local frame = mw.getCurrentFrame()
local lang = mw.getContentLanguage()
local updatePeriod = 86400 -- temporary implementation only supports daily updates
local function getUnix(timestamp)
return lang:formatDate('U', timestamp)
end
local rows, prevRow, maxparam = {}, {}, 1
for line in mw.text.gsplit(args.data, '\n') do
local i, barargs = 1, {}
for parameter in mw.text.gsplit(line, ';') do
parameter = mw.text.trim(parameter)
if string.find(parameter, '^%a') then
parameter = mw.text.split(parameter, '=')
if parameter[1] == 'alttot1' or parameter[1] == 'alttot2' then
parameter[2] = tonumber(frame:callParserFunction('#expr', parameter[2]))
if is(parameter[2]) then
maxparam = math.max(maxparam, parameter[2])
end
end
barargs[parameter[1]] = parameter[2]
else
-- parameter = mw.text.trim(parameter)
if is(parameter) then
if i >= 2 and i <= 6 then
parameter = tonumber(frame:callParserFunction('#expr', frame:callParserFunction('formatnum',parameter,'R')))
maxparam = math.max(maxparam, parameter or 1)
end
barargs[i] = parameter
if i == 7 or i == 9 then
parameter = tonumber(mw.ustring.match(frame:callParserFunction('formatnum',parameter,'R'), '^%d*'))
maxparam = math.max(maxparam, parameter or 1)
end
end
i = i + 1
end
end
local bValid, nDateDiff
-- get relevant date info based on previous row
if barargs[1] then
bValid, barargs.nDate = pcall(getUnix, barargs[1])
assert(bValid, 'invalid date "' .. barargs[1] .. '"')
if prevRow.nDate or prevRow.nEndDate then
nDateDiff = barargs.nDate - (prevRow.nDate or prevRow.nEndDate)
if nDateDiff > updatePeriod then
if nDateDiff == 2 * updatePeriod then
prevRow = {nDate=barargs.nDate-updatePeriod}
prevRow[1] = os.date('%Y-%m-%d', prevRow.nDate)
else
prevRow = {nStartDate=(prevRow.nDate or prevRow.nEndDate)+updatePeriod, nEndDate=barargs.nDate-updatePeriod}
end
rows[#rows+1] = prevRow
end
else
prevRow.nEndDate = barargs.nDate - updatePeriod
if prevRow.nStartDate == prevRow.nEndDate then
prevRow.nDate = prevRow.nEndDate
prevRow[1] = os.date('%Y-%m-%d', prevRow.nDate)
elseif prevRow.nAltStartDate and prevRow.nAltStartDate >= prevRow.nEndDate then
error('Một dòng trong khoảng thời gian liên tiếp dài 1 ngày thiếu một ngày')
end
end
else
if barargs.enddate then
bValid, barargs.nEndDate = pcall(getUnix, barargs.enddate)
assert(bValid, 'giá trị enddate không hợp lệ "' .. barargs.enddate .. '"')
end
if prevRow.nDate or prevRow.nEndDate then
barargs.nStartDate = (prevRow.nDate or prevRow.nEndDate) + updatePeriod
if barargs.nStartDate == barargs.nEndDate then
barargs.nDate = barargs.nEndDate
barargs[1] = os.date('%Y-%m-%d', barargs.nDate)
end
else
prevRow.nAltEndDate = (prevRow.nStartDate or prevRow.nAltStartDate) + updatePeriod
barargs.nAltStartDate = prevRow.nAltEndDate + updatePeriod
if barargs.nEndDate and barargs.nAltStartDate >= barargs.nEndDate then
error('Một dòng trong khoảng thời gian liên tiếp dài 1 ngày thiếu một ngày')
end
end
end
local function fillCols(col, change)
local data = args['right' .. col .. 'data']
local changetype = args['changetype' .. col]
local value, num, prevnum
if data == 'alttot1' then
num = barargs.alttot1 or barargs[4]
prevnum = prevRow.alttot1 or prevRow[4]
elseif data == 'alttot2' then
num = barargs.alttot2 or barargs[6]
prevnum = prevRow.alttot2 or prevRow[6]
elseif data then
num = barargs[data+1]
prevnum = prevRow[data+1]
end
if is(data) and num then -- nothing in column, source found, and data exists
value = changetype == 'o' and '' or lang:formatNum(num) -- set value to num if changetype isn't 'o'
if not change and yesno(barargs['firstright' .. col] ~= true) then
if prevnum and prevnum ~= 0 then -- data on previous row
if num - prevnum ~= 0 then --data has changed since previous row
change = num-prevnum
if changetype == 'a' then -- change type is "absolute"
if change > 0 then
change = '+' .. lang:formatNum(change)
end
else -- change type is "percent", "only percent" or undefined
local percent = 100 * change / prevnum -- calculate percent
local rounding = math.abs(percent) >= 10 and "%.0f" or math.abs(percent) >= 1 and "%.1f" or "%.2f"
-- percent = tonumber(rounding:format(percent)) -- round to two sigfigs
percent = tonumber(mw.ustring.format(rounding, percent)) -- round to two sigfigs
if percent > 0 then
change = '+' .. lang:formatNum(percent) .. '%'
elseif percent < 0 then
change = lang:formatNum(percent) .. '%'
else
change = '='
end
end
else -- data has not changed since previous row
change = '='
end
else -- no data on previous row
barargs['firstright' .. col] = true -- set to (n.a.)
end
end
end
return value, change
end
if not barargs[7] then
barargs[7], barargs[8] = fillCols(1, barargs[8])
end
if not barargs[9] then
barargs[9], barargs[10] = fillCols(2, barargs[10])
end
barargs.prevDate = prevRow[1]
rows[#rows+1] = barargs
prevRow = barargs
end
local lastRow = rows[#rows]
local total = {lastRow[2] or 0, lastRow[3] or 0, [4]=lastRow[5] or 0}
total[3] = lastRow.alttot1 or lastRow[4] and lastRow[4] - total[1] - total[2] or 0
total[5] = lastRow.alttot2 or lastRow[6] and lastRow[6] - total[1] - total[2] or 0
local divisor = (total[1] + total[2] + total[3] + total[4] + total[5]) / (args.barwidth - 5)
local firstDate, lastDate = rows[1].nDate, lastRow.nDate or lastRow.nEndDate
local multiyear = os.date('%Y', firstDate) ~= os.date('%Y', lastDate - (args.nooverlap and args.duration * 86400 or 0))
if args.collapsible ~= false then
args.collapsible = (lastDate - firstDate) / 86400 >= args.duration
end
local bars, dateList = {}, {}
for i, row in ipairs(rows) do -- build rows
row.divisor = tonumber(args.divisor) and tonumber(args.divisor) or maxparam / (0.92 * args.barwidth)--divisor
row.numwidth = args.numwidth
row.collapsible = args.collapsible
row.duration = args.duration
row.nooverlap = args.nooverlap
row.daysToEnd = (lastDate - (row.nDate or row.nEndDate or row.nAltEndDate)) / 86400
row.multiyear = multiyear
bars[#bars+1], dateList[#dateList+1] = p._row(row)
end
return table.concat(bars, '\n'), dateList
end
-- func -> obj
p._barColors = {
'#A50026', --tử vong
'SkyBlue', --hồi phục
'Tomato', --số ca hoặc altlbl1
'Gold', --altlbl2
'OrangeRed' --altlbl3
}
function p._legend0(args)
return '<span style="font-size:90%; margin:0px">' ..
'<span style="background-color:' .. (args[1] or 'none') ..
'; border:' .. (args.border or 'none') ..
'; color:' .. (args[1] or 'none') .. '">' ..
' ' .. '</span>' ..
' ' .. (args[2] or '') .. '</span>'
end
function p._chart(args)
for key, value in pairs(args) do
if ({float=1, barwidth=1, numwidth=1, changetype=1})[key:gsub('%d', '')] then
args[key] = value:lower()
end
end
local barargs = {}
barargs.css = 'Mô đun:Medical cases chart/styles.css'
barargs.float = args.float or 'right'
args.barwidth = args.barwidth or 'medium'
local barwidth
if args.barwidth == 'thin' then
barwidth = 120
elseif args.barwidth == 'medium' then
barwidth = 280
elseif args.barwidth == 'wide' then
barwidth = 400
elseif args.barwidth == 'auto' then
barwidth = 'auto'
else
error('barwidth không tồn tại')
end
local function _numwidth(i)
local nw = args.numwidth:sub(i,i)
return assert(numwidth[nw], 'unrecognized numwidth[' .. i .. ']')
end
local numwidth = 120
local right1 = numwidth - 8 -- -8 because of padding
if args.numwidth then
numwidth = _numwidth(1) + 10 + _numwidth(2)
if mw.ustring.len(args.numwidth) == 4 then
numwidth = numwidth + _numwidth(3) + _numwidth(4)
if mw.ustring.sub(args.numwidth,3,3) == 'n' then
numwidth = numwidth + 6
else
numwidth = numwidth + 10
end
end
right1 = _numwidth(1) + 2 + _numwidth(2)
if not args.right2 and mw.ustring.len(args.numwidth) == 4 then
right1 = right1 + _numwidth(3) + _numwidth(4)
if mw.ustring.sub(args.numwidth,3,3) == 'n' then
numwidth = numwidth + 6
else
numwidth = numwidth + 10
end
end
end
args.numwidth = args.numwidth or 'mm'
if args.numwidth:sub(1,1) == 'n' or args.numwidth:sub(2,2) == 'n' or args.numwidth:sub(4,4) == 'n' then
error('"n" chỉ được cho phép trong numwidth[3]')
end
local buffer = 0.3 --until automatic numwidth determination
local right1width, right2width = _numwidth(1) + 0.3 + _numwidth(2) + buffer, 0
if #args.numwidth == 4 then
right2width = _numwidth(3) + _numwidth(4) + buffer
if args.numwidth:sub(3, 3) ~= 'n' then
right2width = right2width + 0.3
end
if args.right2 then
right2width = math.ceil(right2width / 0.88 * 100) / 100 -- from td scale to th
else
right1width = right1width + 0.8 + right2width
right2width = 0
end
end
right1width = math.ceil(right1width / 0.88 * 100) / 100
local barwidth = 280
if tonumber(barwidth) then
local relwidth = math.ceil(((7.08 + right1width + right2width) * 0.88 + 0.8 * (args.right2 and 5 or 4)) * 88) / 100
barargs.width = 'calc(' .. relwidth .. 'em + ' .. barwidth .. 'px)' --why do the bar borders go inward (no +2)?
barargs.barwidth = barwidth .. 'px'
else
barargs.width = 'auto'
barargs.barwidth = 'auto'
end
barargs.lineheight = args.rowheight
local title = {}
local function spaces(n)
local nbsp = ' '
return '<span class="nowrap">' .. nbsp:rep(n) .. '</span>'
end
local location = args.location
location = mw.ustring.upper(mw.ustring.sub(location,1,1)) .. mw.ustring.sub(location,2)
local navbartitle = args.outbreak .. '/' ..
(args.location3 and args.location3 .. '/' or '') ..
(args.location2 and args.location2 .. '/' or '') ..
'Biểu đồ số ca nhiễm tại ' .. location
local navbar = require('Module:Navbar')._navbar
title[1] = (args.pretitle and args.pretitle .. ' ' or '') ..
args.disease .. ' ' .. i18n.casesIn .. ' ' .. args.location ..
(args.location2 and ', ' .. args.location2 or '') ..
(args.location3 and ', ' .. args.location3 or '') ..
(args.posttitle and ' ' .. args.posttitle or '') .. spaces(2) ..'(' ..
navbar({navbartitle, titleArg=':' .. mw.getCurrentFrame():getParent():getTitle(), mini=1, nodiv=1}) ..
')<br />'
title[2] = p._legend0({p._barColors[1], i18n.noOfDeaths})
args.recoveries = args.recoveries == nil and true or args.recoveries
title[3] = args.recoveries and spaces(3) .. p._legend0({p._barColors[2], args.reclbl or i18n.recoveries}) or ''
title[4] = args.altlbl1 ~= 'hide' and spaces(3) .. p._legend0({p._barColors[3], args.altlbl1 or i18n.activeCases}) or ''
title[5] = args.altlbl2 and spaces(3) .. p._legend0({p._barColors[4], args.altlbl2}) or ''
title[6] = args.altlbl3 and spaces(3) .. p._legend0({p._barColors[5], args.altlbl3}) or ''
local togglesbar, buildargs = nil, {}
args.right1 = args.right1 or i18n.noOfCases
args.duration = args.duration or 15
args.nooverlap = args.nooverlap or false
buildargs.barwidth = tonumber(barwidth) or 280
buildargs.numwidth = args.numwidth:gsub('d', 'm')
if args.datapage then
local externalData = require('Module:Medical cases chart/data')._externalData
buildargs.data = externalData(args)
else
buildargs.data = args.data
end
buildargs.right1data = args.right1data or args.right1 == i18n.noOfCases and 3
buildargs.right2data = args.right2data or (args.right2 == i18n.noOfDeaths or args.right2 == i18n.noOfDeaths2) and 1
buildargs.changetype1 = (args.changetype1 or args.changetype or ''):sub(1, 1) -- 1st letter
buildargs.changetype2 = (args.changetype2 or args.changetype or ''):sub(1, 1) -- 1st letter
buildargs.collapsible = args.collapsible
buildargs.duration = args.duration
buildargs.nooverlap = args.nooverlap
local dateList
barargs.bars, dateList = p._buildBars(buildargs)
if buildargs.collapsible then
togglesbar = p._buildTogglesBar(dateList, args.duration, args.nooverlap)
end
title[7] = togglesbar and '<br />' .. togglesbar or ''
barargs.title = table.concat(title)
barargs.left1 = '<div style="width:7.08em">' .. i18n.date .. '</div>'
barargs.right1 = '<div class=center style="width:' .. right1width .. 'em">' .. args.right1 .. '</div>'
if args.right2 then
barargs.right2 = '<div class=center style="width:' .. right2width ..'em">' .. args.right2 .. '</div>'
end
barargs.caption = args.caption or args.footer
local box = barBox._box(barargs)
return tostring(box)
end
local getArgs = require('Module:Arguments').getArgs
function p.barColors(frame)
local args = getArgs(frame)
return p._barColors[tonumber(args[1])]
end
function p.chart(frame)
local args = getArgs(frame, {
valueFunc = function (key, value)
if value and value ~= '' then
key = key:gsub('%d', '')
if ({rowheight=1, duration=1, rightdata=1})[key] then -- if key in {...}
return tonumber(value) or value
end
if ({recoveries=1, collapsible=1, nooverlap=1})[key] then
return yesno(value)
end
return value
end
return nil
end
})
return p._chart(args)
end
-- deprecation warning
function p.monthToggleButton(frame)
return "Bản mẫu này không còn được dùng nữa, bạn có thể xóa nó"
end
return p