Jump to content

Module:Medical cases chart/data

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Mxn (talk | contribs) at 09:31, 21 April 2020. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
--- 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