Module:Medical cases chart/data
Appearance
--- Example usage:
--- =p.externalData(mw.getCurrentFrame():newChild{args={["page name"]="COVID-19 Cases in Santa Clara County, California.tab",recoveries="hospitalized",cases="totalConfirmedCases"}})
local p = {}
local lang = mw.getContentLanguage()
function round(x)
return (math.modf(x + (x < 0 and -0.5 or 0.5)))
end
function formatChange(previous, current)
if not previous or previous == 0 then
return
end
if previous == current then
return "="
end
local change = current / previous * 100 - 100
local sign = change < 0 and "−" or "+"
return mw.ustring.format("%s%s%%", sign, lang:formatNum(round(math.abs(change))))
end
function p.externalData(frame)
local data = mw.ext.data.get(frame.args["page name"])
local dateIndex
local deathsIndex
local recoveriesIndex
local casesIndex
local class4Index
local class5Index
for i, field in ipairs(data.schema.fields) do
if field.name == "date" or field.name == frame.args.date then
dateIndex = i
elseif field.name == "deaths" or field.name == frame.args.deaths then
deathsIndex = i
elseif field.name == "recoveries" or field.name == frame.args.recoveries then
recoveriesIndex = i
elseif field.name == "cases" or field.name == frame.args.cases then
casesIndex = i
elseif field.name == "class4" or field.name == frame.args.class4 then
class4Index = i
elseif field.name == "class5" or field.name == frame.args.class5 then
class5Index = i
end
end
assert(dateIndex, "Date field not found.")
assert(deathsIndex or not frame.args.deaths, "Deaths field not found.")
assert(recoveriesIndex or not frame.args.recoveries, "Recoveries field not found.")
assert(casesIndex or not frame.args.cases, "Cases field not found.")
assert(class4Index or not frame.args.class4, "Class 4 field not found.")
assert(class5Index or not frame.args.class5, "Class 5 field not found.")
local records = {}
for i, record in ipairs(data.data) do
table.insert(records, {
date = record[dateIndex],
deaths = deathsIndex and record[deathsIndex],
recoveries = recoveriesIndex and record[recoveriesIndex],
cases = casesIndex and record[casesIndex],
class4 = class4Index and record[class4Index],
class5 = class5Index and record[class5Index],
})
end
local rows = {}
local prevRecord = {}
for i, record in ipairs(records) do
local row = {
record.date,
tostring(record.deaths or ""),
tostring(record.recoveries or ""),
tostring(record.cases or ""),
tostring(record.class4 or ""),
tostring(record.class5 or ""),
record.cases and lang:formatNum(record.cases) or "",
record.cases and formatChange(prevRecord.cases, record.cases) or "",
record.deaths and lang:formatNum(record.deaths) or "",
record.deaths and formatChange(prevRecord.deaths, record.deaths) or "",
}
if casesIndex and not prevRecord.cases and record.cases > 0 then
table.insert(row, "firstright1=y")
end
if deathsIndex and prevRecord.deaths == 0 and record.deaths > 0 then
table.insert(row, "firstright2=y")
end
table.insert(rows, table.concat(row, ";"))
prevRecord = record
end
return table.concat(rows, "\n")
end
return p