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:11, 21 April 2020 (An experiment). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)
--- 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 rows = {}
	local prevCases
	local prevDeaths
	for i, record in ipairs(data.data) do
		local row = {
			tostring(record[dateIndex]),
			deathsIndex and tostring(record[deathsIndex]) or "",
			recoveriesIndex and tostring(record[recoveriesIndex]) or "",
			casesIndex and tostring(record[casesIndex]) or "",
			class4Index and tostring(record[class4Index]) or "",
			class5Index and tostring(record[class5Index]) or "",
			casesIndex and lang:formatNum(record[casesIndex]) or "",
			casesIndex and formatChange(prevCases, record[casesIndex]) or "",
			deathsIndex and lang:formatNum(record[deathsIndex]) or "",
			deathsIndex and formatChange(prevDeaths, record[deathsIndex]) or "",
		}
		if casesIndex and not prevCases and record[casesIndex] > 0 then
			table.insert(row, "firstright1=y")
		end
		if deathsIndex and prevDeaths == 0 and record[deathsIndex] > 0 then
			table.insert(row, "firstright2=y")
		end
		
		table.insert(rows, table.concat(row, ";"))
		
		if casesIndex then
			prevCases = record[casesIndex]
		end
		if deathsIndex then
			prevDeaths = record[deathsIndex]
		end
	end
	return table.concat(rows, "\n")
end

return p