Modul:Graf počtu obyvatel
Vzhled
require 'Modul:No globals'
local p = {}
local lang = mw.language.getContentLanguage()
local getArgs = require('Modul:Arguments').getArgs
local TableTools = require('Modul:TableTools')
local Wikidata = require('Modul:Wikidata')
local Formatters = require('Modul:Wikidata/Formatters')
local function getIndexedData(id, property)
local statements = Wikidata.getStatements{
id = id,
property = property,
rank = 'valid',
withqualifier = 'P585'
}
local numbers_raw = {}
for _, statement in ipairs(statements) do
local n = Formatters.getRawValue(statement.mainsnak, {})
for _, qualifier in ipairs(statement.qualifiers.P585) do
local d = Formatters.getRawValue(qualifier, {})
if d and d.year then
numbers_raw[d.year] = n
end
end
end
return numbers_raw
end
local function getKeys(rows)
local keys = {}
for _, v in pairs(rows) do
for key in pairs(v) do
keys[key] = true
end
end
return keys
end
local function formatNumOrNothing(num)
num = tonumber(num)
if num then
return lang:formatNum(num)
else
return ''
end
end
local function createTable(data,sep)
local popTables={}
local divided={}
local i,j=0,sep
for _,v in pairs(data) do
if j == sep then
i=i+1
divided[i]={}
j=0
end
j=j+1
divided[i][j] = v
end
for _, t in pairs(divided) do
local keys = getKeys(t)
local popTable = mw.html.create( 'table' )
local thead = popTable
:css( 'display', 'inline-block' )
:css( 'vertical-align', 'top' )
:addClass( 'wikitable' )
:tag( 'tr' )
thead:tag( 'th' ):wikitext( 'Rok' )
if keys.population then
thead:tag( 'th' ):wikitext( 'Obyvatelé' )
end
if keys.houses then
thead:tag( 'th' ):wikitext( 'Domy' )
end
for _, v in pairs(t) do
local tr = popTable:tag( 'tr' )
:tag( 'th' )
:wikitext( v.year )
:done()
if keys.population then
tr:tag( 'td' )
:css( 'text-align', 'right' )
:wikitext( formatNumOrNothing(v.population) )
end
if keys.houses then
tr:tag( 'td' )
:css( 'text-align', 'right' )
:wikitext( formatNumOrNothing(v.houses) )
end
end
table.insert(popTables,tostring(popTable))
end
return table.concat(popTables)
end
local function drawGraph(indexed_data, opts)
local data = {}
local x_fields = {}
local y_fields = {}
for key, values in pairs(indexed_data) do
table.insert(data, { name = key, values = values })
table.insert(x_fields, { data = key, field = 'x' })
table.insert(y_fields, { data = key, field = 'y' })
end
local json = {
version = 2,
width = opts.width, height = opts.height,
data = data,
scales = {
{
name = "x",
type = "linear",
domain = { fields = x_fields },
range = "width",
zero = false,
nice = true
},
{
name = "y",
range = "height",
nice = true,
domain = { fields = y_fields }
}
},
axes = {
{ type = "x", scale = "x", tickcount = 20, format = "d", grid = true },
{ type = "y", scale = "y", format = "2d", grid = true }
},
marks = {
{
type = "line",
from = { data = "population" },
properties = {
enter = {
x = { scale = "x", field = "x" },
y = { scale = "y", field = "y" },
strokeWidth = { value = 5 },
stroke = { value = "steelblue" }
}
}
},
{
type = "line",
from = { data = "houses" },
properties = {
enter = {
x = { scale = "x", field = "x" },
y = { scale = "y", field = "y" },
strokeWidth = { value = 5 },
stroke = { value = "orange" }
}
}
}
}
}
if opts.labels == "ano" then
table.insert(json["marks"],
{
type = "text",
from = { data = "table" },
properties = {
enter = {
x = { scale = "x", field = "x" },
y = { scale = "y", field = "y" },
fill = { value = "#000" },
align = { value = "left" },
baseline = { value = "top" },
dy = { value = -13 },
text = { field = "y" }
}
}
}
)
end
return tostring(mw.html.create("div")
:css("display","inline-block")
:css("vertical-align","top")
:wikitext(mw.getCurrentFrame():extensionTag("graph", mw.text.jsonEncode(json))))
end
function p.main(frame)
local args
if type(frame) ~= 'table' then
args = { id = frame }
else
args = getArgs(frame)
end
local opts = {
width = tonumber(args["width"]) or 430,
height = tonumber(args["height"]) or 200,
labels = args["labels"],
}
local property = args["property"] or 'P1082'
local from = tonumber(args["from"])
local to = tonumber(args["to"])
local skip = tonumber(args["skip"]) or 1
local zalamovat = tonumber(args["zalamovat"])
local keys = {}
keys.population = property
if args.domy == 'ano' then
keys.houses = 'P4080'
end
local indexed_data = {}
local dates = {}
for key, property in pairs(keys) do
indexed_data[key] = getIndexedData(args.id, property)
for d in pairs(indexed_data[key]) do
dates[d] = true
end
end
dates = TableTools.keysToList(dates, true)
if #dates < 1 then
return ''
end
local data = {}
local tabular = {}
local last
for _, d in ipairs(dates) do
if (not(from) or (d >= from))
and (not(to) or (d <= to))
and (not(last) or ((d-last)>=skip)) then
local t = { year = d }
for key in pairs(keys) do
local val = indexed_data[key][d]
if val then
if not data[key] then
data[key] = {}
end
table.insert(data[key], { x = d, y = val })
t[key] = val
end
end
table.insert(tabular, t)
last = d
end
end
local output = {}
output[1] = args["nadpis"] or '<div style="font-weight:bold">Vývoj počtu obyvatel</div><div><small>Data pocházejí z datové položky Wikidat</small></div>'
local graphPos, tabPos
if args["tabulka"] == "nad" then
tabPos = 2
output[3] = "<br/>"
graphPos = 4
elseif (args["tabulka"] == "pod") then
graphPos = 2
output[3] = "<br/>"
tabPos = 4
elseif (args["tabulka"] == "před") then
tabPos = 2
graphPos = 3
elseif (args["tabulka"] == "za") then
graphPos = 2
tabPos = 3
else
graphPos = 2
end
output[graphPos] = drawGraph(data, opts)
if tabPos then output[tabPos] = createTable(tabular, zalamovat) end
return table.concat(output)
end
return p