Mô đun:Historical populations

--
-- Bản mẫu này thực hiện
--
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 0)) then
if(percentages == 'pagr') then
pstr = mw.ustring.format('%.2f', 100math.abs(math.pow(popnum/ppopnum,1/(yearnum-pyearnum)) - 1))
elseif(percentages 'monthly') then
if Date nil then Date = require('Mô đun: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', 100math.abs(math.pow(popnum/ppopnum,1/months) - 1))
else
pstr = mw.ustring.format('%.1f', 100math.abs(popnum/ppopnum - 1))
end
if( popnum Số dân'
end

-- percentages cell
if( percentages ~= 'off' and percentname ) then
if( percentages 'pagr' ) then
percentname = '±% năm'
elseif( percentages == 'monthly' ) then
percentname = '±% tháng'
else
percentname = '±%'
end
end
return {yearname, popname, percentname}
end

-- this function builds the json for the population graph
local function graphjson(data, gwidth, gheight)
local yearcount = data
local graphargs = {
['width'] = gwidth,
['height'] = gheight,
['type'] = 'line',
['yAxisTitle'] = 'Dân số',
['yAxisMin'] = 0,
['xAxisTitle'] = 'Năm',
['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('Mô đun:Graph')

return Graph.chart({args = graphargs})
end

local function rendergraph(frame, data, gwidth, gheight, gthumb)
local graph = frame:extensionTag{
name = 'templatestyles',
args = { src = 'Graph:Chart/styles.css'}
} .. frame:extensionTag{name = 'graph', content = graphjson(data, gwidth, gheight)}

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 .. graph ..
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 = 2yearcount

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(widthnumcols) .. 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 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 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 '
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)
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)
end
return rendervertical(data, head, title, footnote, alignfn, class, style, width, shading, percol, cols, graphpos, graph)
end

end

return p