Module:Thời biểu dân số
Documentation for this module may be created at Module:Thời biểu dân số/doc
local p = {}
local m = require("Module:Math") -- [[Module:Math]]
---Horizontal width of each bar, including spacing, when there is no risk of the
-- graph overflowing the allotted horizontal space.
local defaultBarIncrement = 35 -- px
---Returns the [[Lịch Gregory đón trước|proleptic Gregorian]] (ISO 8601)
-- representation of the year in the given argument.
function p.toyear(arg)
local year = tonumber(arg)
if year then return year end
year = string.match(arg, "(%d+) *S?CN")
if year then
year = math.floor(tonumber(year))
assert(year > 0, "Không có năm " .. year .. " CN.")
return year
end
year = string.match(arg, "(%d+) *TCN") or string.match(arg, "(%d+) *TTL")
if year then
year = math.floor(tonumber(year))
assert(year > 0, "Không có năm " .. year .. " TCN.")
return -1 * year + 1
end
end
---Returns the total span of years represented in the given data.
function p.count(frame)
local args = frame:getParent().args
local earliestYear = math.huge
local latestYear = 0
for year, value in pairs(args) do
year = p.toyear(year)
if year then
if year < earliestYear then earliestYear = year end
if year > latestYear then latestYear = year end
end
end
return latestYear - earliestYear + 1
end
function p.max(frame)
local args = frame:getParent().args
local maxYear = 0
local maxValue = 0
for year, value in pairs(args) do
year = p.toyear(year)
value = tonumber(value)
if year and value > maxValue then
maxValue = value
maxYear = year
end
end
return maxValue
end
function p.maxorder(frame)
return m._order(p.max(frame))
end
function p.fit(frame)
local max = p.max(frame)
if max == 0 then return 0 end
return (math.ceil(max / 10^(m._order(max) - 1))) * 10^(m._order(max) - 1)
end
---Returns the global minimum of the derivative of the set of numbers in the
-- given array.
function minInterval(numbers)
local dxmin = math.huge
for i = 2, #numbers do
local x = numbers[i]
local xlast = numbers[i - 1]
if x - xlast < dxmin then dxmin = x - xlast end
end
return dxmin
end
function p.barIncrement(frame)
local args = frame:getParent().args
local years = {}
local valuesByYear = {}
for year, value in pairs(args) do
year = p.toyear(year)
if year then
table.insert(years, year)
valuesByYear[year] = tonumber(value)
end
end
table.sort(years)
local width = defaultBarIncrement / minInterval(years)
local count = p.count(frame)
if math.ceil(width) * count <= 1600 - 60 then return width end
return math.floor((1600 - 60) / count)
end
function p.bars(frame)
local args = frame:getParent().args
local years = {}
local valuesByYear = {}
for year, value in pairs(args) do
year = p.toyear(year)
if year then
table.insert(years, year)
valuesByYear[year] = tonumber(value)
end
end
table.sort(years)
for year = years[1], years[#years] do
if not valuesByYear[year] then
table.insert(years, year)
end
end
table.sort(years)
local bars = {}
for i, year in ipairs(years) do
local bar = " bar:" .. year
if valuesByYear[year] then
bar = bar .. " text:" .. year
end
table.insert(bars, bar)
end
return table.concat(bars, "\n")
end
function p.plots(frame)
local args = frame:getParent().args
local plots = {}
for year, value in pairs(args) do
year = p.toyear(year)
if year then
local plot = string.format(" bar:%i from:0 till:%i", year, value)
table.insert(plots, plot)
end
end
return table.concat(plots, "\n")
end
function p.labels(frame)
local args = frame:getParent().args
local lang = mw.getContentLanguage()
local labels = {}
for year, value in pairs(args) do
year = p.toyear(year)
value = tonumber(value)
if year and value then
local label = string.format(" bar:%i at:%i text:%s",
year, value, lang:formatNum(value))
table.insert(labels, label)
end
end
return table.concat(labels, "\n")
end
return p