Module:Population pyramid
Appearance
| This module is rated as beta. It is considered ready for widespread use, but as it is still relatively new, it should be applied with some caution to ensure results are as expected. |
This module implements {{Population pyramid}}
Usage
[edit]{{#invoke:Population pyramid|box}}
--
-- This module implements {{Population pyramid}}
--
local p = {}
local function get_values(val, total, rescale_flag)
if ( rescale_flag ) then
total = (total > 0) and total or 1
val = 100*(tonumber(val))/total
local val_text = mw.ustring.format('%.2f', val)
return val, val_text
end
return (tonumber(val or '0') or 0), (val or 'n/d')
end
-- this is the main function
function p.box(frame)
local mArguments = require('Module:Arguments')
local args = mArguments.getArgs(frame)
-- create a sorted table of ages
local ages = {}
local max_pop, total_m, total_f = 0, 0, 0
for k, v in pairs( args ) do
local i = tonumber(tostring(k):match( '^%s*[mf]([%d]+)%s*$' ) or '-1')
local mf = tostring(k):match( '^%s*([mf])[%d]+%s*$' ) or ''
if ( i >= 0 and v ) then
table.insert(ages, i)
if ((tonumber(v) or 0) > max_pop) then
max_pop = tonumber(v)
end
if ( mf == 'm' ) then
total_m = total_m + (tonumber(v) or 0)
elseif (mf == 'f') then
total_f = total_f + (tonumber(v) or 0)
end
end
end
table.sort(ages)
-- remove duplicates
for k = 2,#ages do
if ages[k] == ages[k-1] then
table.remove(ages, k)
end
end
-- compute the bar width
local mmax = tonumber(args['mmax'] or '9') or 9
if ( (args['mmax'] or '') == 'auto' and (max_pop > 0) ) then
mmax = max_pop
end
local scale = tonumber(args['scale'] or '10') or 10
local barmaxpx = mmax*scale
local percent = ((args['percentage'] or '') == 'off') and '#' or '%'
local rescale_values = ((args['percentage'] or '') == 'auto')
-- create the inner table
local root = mw.html.create('table')
:css('width', '100%')
:css('margin', '0')
-- table header row
local row = root:tag('tr')
row:tag('th')
:css('font-weight', 'normal')
:css('text-align', 'right')
:wikitext(percent)
row:tag('th')
:css('text-align', 'left')
:css('font-weight', 'normal')
:css('width', barmaxpx .. 'px')
:wikitext('Males')
row:tag('th')
:css('font-weight', 'normal')
:css('text-align', 'center')
:wikitext('Age')
row:tag('th')
:css('font-weight', 'normal')
:css('text-align', 'right')
:css('width', barmaxpx .. 'px')
:wikitext('Females')
row:tag('th')
:css('font-weight', 'normal')
:css('text-align', 'left')
:wikitext(percent)
-- build the table starting from highest age group
local prev_age = -1
for k = #ages,1,-1 do
local age = ages[k]
local age_group = age .. '+'
if (prev_age > 0) then
age_group = age .. '–' .. (prev_age - 1)
end
local m, m_text = get_values(args['m' .. age], total_m, rescale_values)
local f, f_text = get_values(args['f' .. age], total_f, rescale_values)
row = root:tag('tr')
row:tag('td')
:css('font-size', 'x-small')
:wikitext(m_text)
row:tag('td')
:css('text-align','right')
:css('border-left', 'solid 1px silver')
:css('border-right', 'solid 1px silver')
:tag('div')
:css('background', 'lightblue')
:css('overflow', 'hidden')
:css('margin-left', 'auto')
:css('width', (m * scale) .. 'px')
:wikitext(' ')
row:tag('td')
:css('font-size', 'x-small')
:css('text-align', 'center')
:css('white-space', 'nowrap')
:wikitext(age_group)
row:tag('td')
:css('text-align','left')
:css('border-left', 'solid 1px silver')
:css('border-right', 'solid 1px silver')
:tag('div')
:css('background', 'pink')
:css('overflow', 'hidden')
:css('width', (f * scale) .. 'px')
:wikitext(' ')
row:tag('td')
:css('font-size', 'x-small')
:wikitext(f_text)
prev_age = age
end
-- wrap the table in an infobox
local year = args['year'] and ' <span style="font-weight:normal">' .. args['year'] .. '</span>' or ''
local below
if (args['source'] or args['sourceref']) then
below = '\'\'\'Source:\'\'\' '
if args['source'] then
below = below .. args['source']
end
if args['sourceref'] then
below = below .. frame:extensionTag( {name='ref', content = args['sourceref']} )
end
end
local infobox = require ('Module:Infobox').infobox
return infobox({
['abovestyle'] = 'text-align:center; font-size:100%; border-bottom:solid 1px silver;',
['above'] = '[[Population pyramid]]' .. year,
['datastyle'] = 'padding:0;',
['belowstyle'] = below and 'text-align:left; font-weight:normal; font-size:100%; border-top:solid 1px silver;',
['below'] = below,
['data1'] = tostring(root)
})
end
return p