Module:COVID-19 data


This module and these templates show data on the COVID-19 pandemic.

Core components

mali niŋ

The body of a table can be made by using the main() function:

{{#invoke:COVID-19 data|main|columns=columns|sort=column to sort by}}

This only generates table contents (the body). Headers and titles can be customised independent of the module, to allow for styling.

Please use the following reference (preferably in the table title), to avoid duplicate references and have automatically updating access date and authors:

<ref name="Template:COVID-19 data">{{COVID-19 data/cite}}</ref>
List
Page C? D? VT? VD? VF? Other? Col? Notes
Template:COVID-19 data Main table
Template:COVID-19 pandemic data Other "hub" template
Template:COVID-19 pandemic death rates Deaths/million
Template:COVID-19 pandemic death rates by country Larger, has row numbers
Template:COVID-19 vaccination data % vaccinated
Template:COVID-19 vaccination data in Africa
Template:COVID-19 vaccination data in North America

References

mali niŋ

local p = {}

local data_title = mw.title.new(
	'Template:COVID-19 data/data'
)
local data_content = data_title:getContent()
local data = mw.text.jsonDecode(data_content)

local function format_num(number)
	if not number then
		return ''
	end
	local _, _, minus, int, _ = tostring(number):find('([-]?)(%d+)([.]?%d*)')
	int = int:reverse():gsub("(%d%d%d)", "%1,")
	int = int:reverse():gsub("^,", "")
	int = minus .. int
	return int
end

function p.main()
	local out = ''
	local data_s = {}
	local has_notelist = false
	local count_row = 0
	local count_col = 0
	-- Build new table
	local locations = {}
	if mw.getCurrentFrame().args['locations'] then
		for location in string.gmatch(
			mw.getCurrentFrame().args['locations'],
			'([^,]+)'
		) do
			locations[location] = true
		end
	else
		locations = nil
	end
	for key, value in pairs(data) do
		local index
		if mw.getCurrentFrame().args['sort'] then
			if value[mw.getCurrentFrame().args['sort']] then
				index = value[mw.getCurrentFrame().args['sort']]
			else
				index = 0
			end
		else
			if value.cases then
				index = value.cases
			elseif value.deaths then
				index = value.deaths
			elseif value.vaccine_doses then
				index = value.vaccine_doses
			elseif value.total_vaccinated then
				index = value.total_vaccinated
			elseif value.fully_vaccinated then
				index = value.fully_vaccinated
			else index = 0
			end
		end
		if (not locations) or locations[key] then
			data_s[#data_s+1] = value
			data_s[#data_s]['_index'] = index
			data_s[#data_s]['_code'] = key
		end
	end
	-- Sort the new table
	table.sort(
		data_s,
		function(x, y)
			if x._code == 'XW' then
				return true
			elseif y._code == 'XW' then
				return false
			else
				return (x._index > y._index)
			end
		end
	)
	-- Get columns
	local columns = {
		cases = false,
		deaths = false,
		total_vaccinated = false,
		vaccine_doses = false,
		fully_vaccinated = false,
		percent_vaccinated = false,
		percent_fully_vaccinated = false,
		deaths_per_million = false,
		population = false
	}
	local columns_index = {}
	if mw.getCurrentFrame().args['columns'] then
		for column in string.gmatch(
			mw.getCurrentFrame().args['columns'],
			'([^,]+)'
		) do
			columns[column] = true
			columns_index[#columns_index+1] = column
		end
	else
		columns = {
			cases = true,
			deaths = true,
			total_vaccinated = true,
			vaccine_doses = true,
			fully_vaccinated = true,
			percent_vaccinated = false,
			percent_fully_vaccinated = false,
			deaths_per_million = false,
			population = false
		}
		columns_index = {
			'cases',
			'deaths',
			'total_vaccinated',
			'vaccine_doses',
			'fully_vaccinated',
			'percent_vaccinated',
			'percent_fully_vaccinated',
			'deaths_per_million',
			'population'
		}
	end
	-- Check if should show note_vaccination
	local show_note_vaccination = false
	if columns['total_vaccinated'] or columns['vaccine_doses'] or columns['fully_vaccinated'] or columns['percent_vaccinated'] or columns['percent_fully_vaccinated'] then
		show_note_vaccination = true
	end
	-- Generate wikitext content
	for _, row in ipairs(data_s) do
		-- Test for empty rows
		local has_data = false
		for _, column in pairs(columns_index) do
			if columns[column] and row[column] then
				has_data = true
			end
		end
		if has_data then -- Only add row if it has data
			count_row = count_row + 1
			out = out .. '\n|-'
			if row._code == 'XW' then
				out = out .. 'class="sorttop static-row-header"'
			end
			-- Add the flag
			if not mw.getCurrentFrame().args['noflag'] then
				if count_row == 1 then
					count_col = count_col + 1
				end
				out = out .. '\n| style="text-align: center;" data-sort-value="' .. row.name .. '" | '
				if row._code == 'XW' then
					out = out ..
						'[[File:OOjs UI icon globe.svg|16px|alt=|link=]]'
				else
					flag_params = {row.name}
					-- So that it's not too large
					if row.name == 'New Caledonia' then
						flag_params[2] = 'merged'
					end
					out = out ..
						mw.getCurrentFrame():expandTemplate{
							title = 'Flagicon',
							args = flag_params
						}
				end
			end
			-- Add country name
			if count_row == 1 then
				count_col = count_col + 1
			end
			if mw.getCurrentFrame().args['noflag'] then
				out = out .. '\n! scope="row" data-sort-value="' .. row.name .. '" | '
			else
				out = out .. '\n! scope="row" |'
			end
			if row._code == 'XW' then
				out = out .. '[[COVID-19 pandemic|' .. row.name .. ']]'
			elseif row._code == 'GE' then
				out = out ..
					'[[COVID-19 pandemic in Georgia (country)' ..
					'|' .. row.name .. ']]'
			else
				out = out ..
					'[[COVID-19 pandemic in ' .. row.name ..
					'|' .. row.name .. ']]'
			end
			-- Add notes
			if row.note then
				has_notelist = true
				out = out ..
					mw.getCurrentFrame():expandTemplate{
						title = 'Efn',
						args = {row.note}
					}
			end
			if row.note_vaccination and show_note_vaccination then
				has_notelist = true
				out = out ..
					mw.getCurrentFrame():expandTemplate{
						title = 'Efn',
						args = {'Vaccination note: ' .. row.note_vaccination}
					}
			end
			-- Fill out columns
			for _, column in ipairs(columns_index) do
				if columns[column] then
					if count_row == 1 then
						count_col = count_col + 1
					end
					if row[column] then
						out = out .. '\n| data-sort-value=' ..
							tostring(row[column]) ..
							'|'
						if column:find('^percent') then
							out = out .. string.format('%.2f', row[column]) .. '%'
						else
							out = out .. format_num(row[column])
						end
					else
						out = out .. '\n| data-sort-value=0 | —'
					end
				end
			end
		end
	end
	if has_notelist then
		out = out .. '\n|- class="sortbottom static-row-header" style="text-align: left;"' ..
			'\n| colspan="' .. count_col .. '" style="width: 0;" |' ..
			mw.getCurrentFrame():expandTemplate{
				title = 'Notelist'
			}
	end
	return out
end

function p.vac()
	local out = ''
	local data_s = {}
	local has_country_num_doses = false
	local has_country_num_fully = false
	local count_row = 0
	local count_col = 0
	-- Build new table
	for key, value in pairs(data) do
		if value.total_vaccinated then
			data_s[#data_s+1] = value
			data_s[#data_s]['index'] = value.total_vaccinated
		elseif value.vaccine_doses then
			data_s[#data_s+1] = value
			data_s[#data_s]['index'] = value.vaccine_doses
		elseif value.fully_vaccinated then
			data_s[#data_s+1] = value
			data_s[#data_s]['index'] = value.fully_vaccinated
		end
	end
	-- Sort the new table
	table.sort(
		data_s,
		function(x, y)
			return (x.index > y.index)
		end
	)
	-- Generate wikitext content
	for _, row in pairs(data_s) do
		count_row = count_row + 1
		out = out .. '\n|-'
		-- Add the flag
		if count_row == 1 then
			count_col = count_col + 2
		end
		if row.name == 'World' then
			out = out ..
				'class="sorttop static-row-header"' ..
				'\n| style="text-align: center;" data-sort-value="' .. row.name .. '" | ' ..
				'[[File:OOjs UI icon globe.svg|16px|alt=|link=]]' ..
				'\n! scope="row" data-sort-value="' .. row.name .. '" | ' ..
				'[[Deployment of COVID-19 vaccines|World]]'
		else
			flag_params = {row.name}
			-- So that it's not too large
			if row.name == 'New Caledonia' then
				flag_params[2] = 'merged'
			end
			out = out ..
				'\n| style="text-align: center;" data-sort-value="' .. row.name .. '" | ' ..
				mw.getCurrentFrame():expandTemplate{
					title = 'Flagicon',
					args = flag_params
				} ..
				'\n! scope="row" data-sort-value="' .. row.name .. '" | ' ..
				'[[COVID-19 vaccination in ' .. row.name .. '|' .. row.name .. ']]'
		end
		-- Add note
		if row.note_vaccination then
			out = out ..
				mw.getCurrentFrame():expandTemplate{
					title = 'Efn',
					args = {row.note_vaccination}
				}
		end
		-- Add the number
		if count_row == 1 then
			count_col = count_col + 1
		end
		if row.total_vaccinated then
			out = out .. '\n| data-sort-value=' ..
				tostring(row.total_vaccinated) ..
				'|' .. format_num(row.total_vaccinated)
		elseif row.vaccine_doses then
			has_country_num_doses = true
			out = out .. '\n| data-sort-value=' ..
				tostring(row.vaccine_doses) ..
				'|' ..
				mw.getCurrentFrame():expandTemplate{
					title = 'Font color',
					args = {'darkred', format_num(row.vaccine_doses)}
				} ..
				mw.getCurrentFrame():expandTemplate{
					title = 'Efn',
					args = {name = 'country_num_doses'}
				}
		elseif row.fully_vaccinated then
			has_country_num_fully = true
			out = out .. '\n| data-sort-value=' ..
				tostring(row.fully_vaccinated) ..
				'|' ..
				mw.getCurrentFrame():expandTemplate{
					title = 'Font color',
					args = {'darkorange', format_num(row.fully_vaccinated)}
				} ..
				mw.getCurrentFrame():expandTemplate{
					title = 'Efn',
					args = {name = 'country_num_fully'}
				}
		end
		-- Add the percentage
		if count_row == 1 then
			count_col = count_col + 1
		end
		if row.percent_vaccinated then
			out = out .. '\n| data-sort-value=' ..
				tostring(row.percent_vaccinated) ..
				'|' .. string.format("%.1f", row.percent_vaccinated) .. '%'
		else
			out = out .. '\n| data-sort-value=0 | —'
		end
	end
	if has_country_num_doses or has_country_num_fully then
		notelist_refs = ''
		if has_country_num_doses then
			notelist_refs = notelist_refs ..
				mw.getCurrentFrame():expandTemplate{
					title = 'Efn',
					args = {
						name = 'country_num_doses',
						'This country\'s data are the ' ..
							mw.getCurrentFrame():expandTemplate{
								title = 'Font color',
								args = {
									'darkred',
									'number of vaccine doses administered'
								}
							} ..
							', not the first dose only.'
					}
				}
		end
		if has_country_num_fully then
			notelist_refs = notelist_refs ..
				mw.getCurrentFrame():expandTemplate{
					title = 'Efn',
					args = {
						name = 'country_num_fully',
						'This country\'s data are the ' ..
							mw.getCurrentFrame():expandTemplate{
								title = 'Font color',
								args = {
									'darkorange',
									'number of people fully vaccinated'
								}
							} ..
							', not the number of people ' ..
							'who have received at least one dose.'
					}
				}
		end
		out = out .. '\n|- class="sortbottom  static-row-header" style="text-align: left;"' ..
			'\n| colspan="' .. count_col .. '" style="width: 0;" |' ..
			mw.getCurrentFrame():expandTemplate{
				title = 'Notelist',
				args = {refs = notelist_refs}
			}
	end
	return out
end

function p.text()
	local location = mw.getCurrentFrame().args['location']
	local column = mw.getCurrentFrame().args['column']
	return data[location][column]
end

return p