Open main menu
Home
Random
Donate
Recent changes
Special pages
Community portal
Preferences
About Stockhub
Disclaimers
Search
User menu
Talk
Contributions
Create account
Log in
Editing
Module:Historical populations
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
-- -- This template implements {{Historical populations}} -- local p = {} local lang = mw.getContentLanguage() local Date -- lazy initialization local function ifexist(page) if not page then return false end if mw.title.new(page).exists then return true end return false end local function isempty( s ) return not s or s:match( '^%s*(.-)%s*$' ) == '' end local function splitnumandref( s ) s = s:match( '^%s*(.-)%s*$' ) local t1 = mw.text.unstrip(s) local t2 = s:match( '^([%d][%d,]*)' ) if( t1 == t2 ) then local t3 = s:match( '^[%d][%d,]*(.-)$' ) return t1, t3 else return s, '' end end local function formatnumR(num) return tonumber(lang:parseFormattedNumber(num)) end local function formatnum(num) return lang:parseFormattedNumber(num) and lang:formatNum(lang:parseFormattedNumber(num)) or num end -- this function creates an array with the {year, population, percent change} local function getpoprow(year, popstr, pyear, ppopstr, linktype, percentages, current_year) local pop, popref = splitnumandref( popstr or '') local ppop, ppopref = splitnumandref( ppopstr or '') local percent = '' local yearnum = formatnumR(mw.ustring.gsub(year or '', '^%s*([%d][%d][%.%d]+).*$', '%1') or '') local pyearnum = formatnumR(mw.ustring.gsub(pyear or '', '^%s*([%d][%d][%.%d]+).*$', '%1') or '') local popnum = formatnumR(pop) local ppopnum = formatnumR(ppop) if( linktype == 'US' or linktype == 'USA' ) then if( (yearnum or 0) >= 1790 and yearnum <= current_year and math.fmod(math.floor(yearnum), 10) == 0) then if( yearnum < current_year ) then year = '[[' .. tostring(yearnum) .. ' United States census|' .. year .. ']]' elseif( ifexist(tostring(yearnum) .. ' United States census') ) then year = '[[' .. tostring(yearnum) .. ' United States census|' .. year .. ']]' end end end if(percentages ~= 'off') then local pstr = 'β ' if(popnum ~= nil and ppopnum ~= nil and (ppopnum > 0)) then if(percentages == 'pagr') then pstr = mw.ustring.format('%.2f', 100*math.abs(math.pow(popnum/ppopnum,1/(yearnum-pyearnum)) - 1)) elseif(percentages == 'monthly') then if Date == nil then Date = require('Module:Date')._Date end local date1 = Date(year) local date2 = Date(pyear) local diff = date1 - date2 local months = (diff.age_days/(365.25/12)) pstr = mw.ustring.format('%.2f', 100*math.abs(math.pow(popnum/ppopnum,1/months) - 1)) else pstr = mw.ustring.format('%.1f', 100*math.abs(popnum/ppopnum - 1)) end if( popnum < ppopnum ) then pstr = 'β' .. pstr .. '%' else pstr = '+' .. pstr .. '%' end elseif(popnum ~= nil and ppopnum ~= nil and (ppopnum == popnum)) then pstr = mw.ustring.format('%.2f', 0) .. '%' end percent = pstr end -- strip the fractional part of the year, if there is one year = mw.ustring.gsub(year or '', '^%s*([%d][%d][%d]+)%.[%d]*', '%1') return {year, formatnum(pop) .. popref, percent } end -- this function creates an array with table header labels local function getheadrow(percentages, popname, yearname, percentname) -- year cell if(yearname == '') then yearname = 'Year' end -- population cell if(popname == '') then popname = '<abbr title="Population">Pop.</abbr>' end -- percentages cell if( percentages ~= 'off' and percentname == '') then if( percentages == 'pagr' ) then percentname = '<abbr title="Per annum growth rate">Β±% p.a.</abbr>' elseif( percentages == 'monthly' ) then percentname = '<abbr title="Per month growth rate">Β±% p.m.</abbr>' else percentname = '<abbr title="Percent change">Β±%</abbr>' end end return {yearname, popname, percentname} end -- this function builds the json for the population graph local function graphjson(data, gwidth, gheight, gtype) local yearcount = #data local graphargs = { ['width'] = gwidth, ['height'] = gheight, ['type'] = gtype or 'line', ['yAxisTitle'] = 'Population', ['yAxisMin'] = 0, ['xAxisTitle'] = 'Year', ['xAxisAngle'] = '-45', ['yGrid'] = 'y', ['yAxisFormat'] = ',d', ['x'] = '', ['y'] = '' } local firstpoint = true for offset = 1,yearcount do local x,y = data[offset][1], data[offset][2] -- delink if necessary if x:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]') then x = x:match('^%s*%[%[[^%[%]]*%|([^%[%]]*)%]%]') end y = formatnumR(y) if x and y then graphargs['x'] = graphargs['x'] .. (firstpoint and '' or ', ') .. x graphargs['y'] = graphargs['y'] .. (firstpoint and '' or ', ') .. y firstpoint = false end end local Graph = require('Module:Graph') return Graph.chart({args = graphargs}) end local function rendergraph(frame, data, gwidth, gheight, gthumb, gtype) local graph = frame:extensionTag{ name = 'templatestyles', args = { src = 'Graph:Chart/styles.css'} } .. frame:extensionTag{name = 'graph', content = graphjson(data, gwidth, gheight, gtype)} if(gthumb ~= '') then local graphdiv = mw.html.create('div') :addClass('thumb') :addClass(gthumb == 'right' and 'tright' or 'tleft') :css('clear', 'none') graphdiv :tag('div') :addClass('thumbinner') :wikitext(graph) return tostring(graphdiv) end return '<div class="center">' .. graph .. '</div>' end -- this function renders the population table in a vertical format local function rendervertical(data, head, title, footnote, alignfn, class, style, width, shading, percol, cols, graphpos, graph) -- define a couple helper functions local function addrowcell(trow, tag, text, align, shading, style) cell = trow:tag(tag) cell :css('text-align', align) :css('padding', '1px') :wikitext(text) :css('border-bottom', shading ~= 'off' and '1px solid #bbbbbb' or nil) :cssText(style) end local function addheadcell(trow, text, align, width, pad) cell = trow:tag('th') cell :css('border-bottom', '1px solid black') :css('padding', pad and ('1px ' .. pad) or '1px') :css('text-align', align) :css('width', width) :wikitext(text) end local colspan = 3 local yearcount = #data local argcount = 2*yearcount if( isempty(width) ) then width = '15em' end -- override the value of cols if percol has been specified if( percol > 0 ) then cols = math.floor( (yearcount - 1) / percol ) + 1 end -- compute the number of rows per col local rowspercol = math.floor( (yearcount - 1) / cols ) + 1 -- specify the colspan for the title and footer lines if( cols > 1 ) then colspan = cols else if (head[3] == '') then colspan = 2 else colspan = 3 end end -- compute outer table width local twidth = width if( (cols > 1) and width:match('^%s*[%d]+[%w]+%s*$') ) then local widthnum = mw.ustring.gsub( width, '^%s*([%d]+)([%w]+)%s*$', '%1' ) local widthunit = mw.ustring.gsub( width, '^%s*([%d]+)([%w]+)%s*$', '%2' ) twidth = tostring(widthnum*cols) .. widthunit end -- create the outer table local root = mw.html.create('table') root :addClass(class) :css('width', twidth) :css('border-top-width', '0') :cssText(style['table']) -- add title local caption = root:tag('caption') caption :css('border-top', '1px #aaa solid') :css('border-left', '1px #aaa solid') :css('border-right', '1px #aaa solid') :css('background-color', 'lavender') :css('padding', '0.25em') :css('font-weight', 'bold') :wikitext(title) -- add the graph line (if top graph) if((graphpos == 'top' or graphpos == 't') and graph ~= '') then row = root:tag('tr') cell = row:tag('td') cell :attr('colspan', colspan) :css('border-bottom', '1px solid black') :wikitext(graph) graph = '' end -- loop over columns and rows within columns local offset = 1 local t = root for c = 1,cols do -- add inner tables if we are rendering more than one column if( cols > 1) then if (c == 1) then row = root:tag('tr') row:attr('valign', 'top') cell = row:tag('td') cell:css('padding', '0 0.5em') else cell = row:tag('td') cell :css('padding', '0 0.5em') :css('border-left', 'solid 1px #aaa') end t = cell:tag('table') t :css('border-spacing', '0') :css('width', width) end -- start column headers local hrow = t:tag('tr') hrow:css('font-size', '95%') -- year header addheadcell(hrow, head[1], nil, head[3] ~= '' and '3em' or 'auto', nil, nil) -- population header addheadcell(hrow, head[2], 'right', nil, '2px') -- percentages header if( head[3] ~= '' ) then addheadcell(hrow, head[3], 'right', nil, nil) end -- end column headers -- start population rows for r = 1,rowspercol do -- generate the row if we have not exceeded the rowcount -- shade every fifth row, unless shading = off local s = 'off' if( math.fmod((c - 1)*rowspercol + r, 5) == 0 and r ~= rowspercol) then s = shading end if(offset <= yearcount) then -- start population row local prow = t:tag('tr') -- year cell addrowcell(prow, 'th', data[offset][1], 'center', s, style['year']) -- population cell addrowcell(prow, 'td', data[offset][2], 'right', s, style['pop']) -- percentage cell if( not isempty(head[3]) ) then addrowcell(prow, 'td', data[offset][3], 'right', s, style['pct']) end -- end population row offset = offset + 1 end end end -- add the graph line (if bottom graph) if((graphpos == 'bottom' or graphpos == 'b') and graph ~= '') then row = root:tag('tr') cell = row:tag('td') cell :attr('colspan', colspan) :css('border-top', '1px solid black') :wikitext(graph) graph = '' end -- add the footnote line if( footnote ~= '') then row = root:tag('tr') cell = row:tag('td') cell :attr('colspan', colspan) :css('border-top', '1px solid black') :css('font-size', '85%') :css('text-align', alignfn) :wikitext(footnote) end return graph .. tostring(root) end -- this function renders the population table in a horizontal format local function renderhorizontal(data, head, title, footnote, alignfn, class, style, width, shading, perrow, rows, graphpos, graph) local row local cell local yearcount = #data local argcount = 2*yearcount -- override the value of rows if perrow has been specified if( perrow > 0 ) then rows = math.floor( (yearcount - 1) / perrow ) + 1 end -- compute the number of cols per row local colsperrow = math.floor( (yearcount - 1) / rows ) + 1 -- create the outer table local root = mw.html.create('table') root :addClass(class) :css('font-size', '90%') :cssText(style['table']) -- create title row row = root:tag('tr') cell = row:tag('th') cell :css('padding', '0.25em') :attr('colspan', colsperrow + 1) :wikitext(title) -- add the graph line (if top graph) if((graphpos == 'top' or graphpos == 't') and graph ~= '') then row = root:tag('tr') cell = row:tag('td') cell :attr('colspan', colsperrow + 1) :css('border-bottom', '1px solid black') :wikitext(graph) graph = '' end -- loop over rows and columns within rows local offset = 1 for r = 1,rows do local rowoffset = offset -- render the years row = root:tag('tr') cell = row:tag('th') cell:wikitext(head[1]) :css('border-top', r > 1 and '2px solid #000' or nil) for c = 1,colsperrow do cell = row:tag('td') if(offset <= yearcount) then cell:wikitext(data[offset][1]) :css('text-align', 'center') :css('border-top', r > 1 and '2px solid #000' or nil) :cssText(style['year']) else cell:css('border-width', r > 1 and '2px 0 0 0' or 0) :css('border-top', r > 1 and '2px solid #000' or nil) end offset = offset + 1 end -- render the pop offset = rowoffset row = root:tag('tr') cell = row:tag('th') cell:wikitext(head[2]) for c = 1,colsperrow do cell = row:tag('td') if(offset <= yearcount) then cell:wikitext(data[offset][2]) :css('text-align', 'right') :css('padding-right', '2px') :cssText(style['pop']) else cell:css('border-width', 0) end offset = offset + 1 end -- render the percentages if(head[3] ~= '') then offset = rowoffset row = root:tag('tr') cell = row:tag('th') cell:wikitext(head[3]) for c = 1,colsperrow do cell = row:tag('td') if(offset <= yearcount) then cell:wikitext(data[offset][3]) :css('text-align', 'right') :css('padding-right', '2px') :cssText(style['pct']) else cell:css('border-width', 0) end offset = offset + 1 end end end -- add the graph line (if bottom graph) if((graphpos == 'bottom' or graphpos == 'b') and graph ~= '') then row = root:tag('tr') cell = row:tag('td') cell :attr('colspan', colsperrow + 1) :css('border-top', '1px solid black') :wikitext(graph) graph = '' end -- add the footnote line if( footnote ~= '') then row = root:tag('tr') cell = row:tag('td') cell :css('border-top', '2px solid black') :css('font-size', '85%') :css('text-align', alignfn) :attr('colspan', colsperrow + 1) :wikitext(footnote) end return graph .. tostring(root) end -- this is the main function function p.poptable(frame) local data = {} local style = {} local args = frame.args[1] and frame.args or frame:getParent().args local title = args['title'] or '' local align = args['align'] or '' local clear = args['clear'] or '' local direction = args['direction'] or '' local percentages = args['percentages'] or '' local state = args['state'] or '' local linktype = args['type'] or '' local shading = args['shading'] or 'on' local width = args['width'] or '' local subbox = args['subbox'] or '' local popname = args['pop_name'] or '' local yearname = args['year_name'] or '' local percentname = args['percent_name'] or '' local footnote = args['footnote'] or '' local alignfn = args['align-fn'] or '' local source = args['source'] or '' local graphpos = args['graph-pos'] or '' local graphwidth = args['graph-width'] or '' local graphheight = args['graph-height'] or '' local graphtype = args['graph-type'] or 'line' local percol = tonumber(args['percol']) or 0 local cols = tonumber(args['cols']) or 1 local perrow = tonumber(args['perrow']) or 0 local rows = tonumber(args['rows']) or 1 style['year'] = args['year_style'] style['pop'] = args['pop_style'] style['pct'] = args['pct_style'] -- setup classes and styling for outer table local class = direction == 'horizontal' and 'wikitable' or 'toccolours' if( state == 'collapsed' ) then class = class .. ' collapsible collapsed' end if( isempty(title) ) then title = 'Historical population' end if( isempty(align) ) then align = direction ~= 'horizontal' and 'right' or 'center' end if( isempty(alignfn) ) then alignfn = 'left' end if( isempty(clear) ) then clear = align == 'center' and '' or align end local margin = '0.5em 0 1em 0.5em' if( align == 'left' ) then margin = '0.5em 1em 0.5em 0' elseif( align == 'none' ) then margin = '0.5em 1em 0.5em 0' elseif( align == 'center' ) then margin = '0.5em auto' align = '' end if( isempty(subbox) ) then style['table'] = 'border-spacing: 0;' .. (align ~= '' and 'float:' .. align .. ';' or '') .. (clear ~= '' and 'clear:' .. clear .. ';' or '') .. 'margin:' .. margin .. ';' else style['table'] = 'margin:0;' .. 'border-collapse:collapse;' .. 'border:none;' end style['table'] = style['table'] .. (args['table_style'] or '') -- setup the footer text if( source ~= '' ) then source = 'Source: ' .. source if( footnote ~= '' ) then footnote = footnote .. '<br/>' end end footnote = footnote .. source -- setup the data header cols/rows local head = getheadrow(percentages, popname, yearname, percentname) -- count the total number of population rows local argcount = 0 local rowcount = 0 for k, v in pairs( args ) do if ( (type( k ) == 'number') and (not isempty(args[k])) ) then if( k >= 1 and math.floor(k) == k and k > argcount) then argcount = k end if( math.fmod(k - 1, 2) == 0 ) then rowcount = rowcount + 1 end end end -- here is where we build all the data for the table -- loop over columns and rows within columns local pyear = '' local ppop = '' local offset = 1 local current_year = tonumber(os.date("%Y", os.time())) for r = 1,rowcount do -- skip blank rows while(isempty(args[offset]) and offset <= argcount) do offset = offset + 2 end -- generate the row if we have not exceeded the rowcount if(offset <= argcount) then table.insert(data, getpoprow(args[offset], args[offset + 1] or '', pyear, ppop, linktype, percentages, current_year) ) pyear = args[offset] ppop = args[offset+1] or '' offset = offset + 2 end end local graph = '' graphpos = graphpos:lower() -- now that we have the data for the table, render it in the requested format if (direction == 'horizontal') then if graphpos ~= '' then local gwidth = tonumber(graphwidth) or 200 local gheight= tonumber(graphheight) or 170 local gthumb = (graphpos == 'r' or graphpos == 'right' and 'right') or (graphpos == 'l' or graphpos == 'left' and 'left') or '' graph = rendergraph(frame, data, gwidth, gheight, gthumb, graphtype) end return renderhorizontal(data, head, title, footnote, alignfn, class, style, width, shading, perrow, rows, graphpos, graph) else if graphpos ~= '' then local gwidth = tonumber(graphwidth) or (170 * cols) local gheight= tonumber(graphheight) or 170 local gthumb = (graphpos == 'r' or graphpos == 'right' and 'right') or (graphpos == 'l' or graphpos == 'left' and 'left') or '' graph = rendergraph(frame, data, gwidth, gheight, gthumb, graphtype) end return rendervertical(data, head, title, footnote, alignfn, class, style, width, shading, percol, cols, graphpos, graph) end end return p
Summary:
Please note that all contributions to Stockhub may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Stockhub:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Templates used on this page:
Template:Tl
(
edit
)
Module:Historical populations/doc
(
edit
)