Modul:Forgalomdiagram
Megjelenés
Forgalomdiagram[mi ez?] • [dokumentáció: mutat, ] • [tesztek: létrehozás]
local getArgs = require('Modul:Arguments').getArgs
local p = {}
local property = 'P3872'
local json = {
version = 2,
width = 400, height = 200,
data = {
{
name = "table",
values = {}
}
},
scales = {
{
name = "x",
type = "ordinal",
range = "width",
domain = { data = "table", field= "x" }
},
{
name = "y",
range = "height",
nice = true,
domain = { data = "table", field = "y" }
}
},
axes = {
{ type = "x", scale = "x" },
{ type = "y", scale = "y" }
},
marks = {
{
type = "rect",
from = { data = "table" },
properties = {
enter = {
x = { scale = "x", field = "x" },
width = { scale = "x", band = true, offset = -1},
y = { scale = "y", field = "y" },
y2 = { scale = "y", value = 0 }
},
update = {
fill = { value = "steelblue" }
},
hover = {
fill = { value = "red" }
}
}
},
{
type = "text",
from = { data = "table" },
properties = {
enter = {
x = { scale = "x", field = "x" },
dx = { scale = "x", band = true, mult = 0.5 },
y = { scale = "y", field = "y" },
fill = { value = "#000" },
align = { value = "center" },
baseline = { value = "top" },
dy = { value = -13 },
text = { field = "y_form" }
}
}
}
}
}
local function getStatements(id)
local entity = mw.wikibase.getEntity(id)
if not entity then
return nil
end
if not entity.claims or not entity.claims[property] then
return nil
end
local statements = entity.claims[property]
return statements
end
local function prepareStatements(statements)
local Time
local numbers_raw = {}
local years = {}
local dates = {}
local ranks = { normal = 1, preferred = 2 }
local function processStatement(statement)
local snak = statement.mainsnak
if not snak or snak.snaktype ~= 'value' then
return
end
local rank = ranks[statement.rank]
if not rank then
return
end
local n = tonumber(snak.datavalue.value.amount)
local d = nil
if statement.qualifiers and statement.qualifiers.P585 then -- dátum
if not Time then
Time = require('Modul:Time')
end
d = Time.newFromWikidataValue(statement.qualifiers.P585[1].datavalue.value)
end
if d and d.precision >= Time.PRECISION.YEAR then
years[d.year] = true
local month = d.precision >= Time.PRECISION.MONTH and d.month or 0
local day = d.precision >= Time.PRECISION.DAY and d.day or 0
local monthday = month * 100 + day
if not numbers_raw[d.year] or numbers_raw[d.year].precision > d.precision then
-- prefer yearly/monthly data over sum of monthly/daily as the latter can have “gaps”
numbers_raw[d.year] = { number = n, precision = d.precision, monthdays = { [monthday] = rank } }
elseif numbers_raw[d.year].precision == d.precision then
if not numbers_raw[d.year].monthdays[monthday] then
numbers_raw[d.year].monthdays[monthday] = rank
numbers_raw[d.year].number = numbers_raw[d.year].number + n
elseif numbers_raw[d.year].monthdays[monthday] < rank then
numbers_raw[d.year].monthdays[monthday] = rank
numbers_raw[d.year].number = n
else
-- We already have data for this date with at least as high rank
-- as the new. Just keep the previous one; either one can be good,
-- so don’t do useless operations.
end
end
end
end
for _, statement in pairs(statements) do
processStatement(statement)
end
for y, _ in pairs(years) do
table.insert(dates, y)
end
if #dates < 1 then
return nil
end
table.sort(dates)
local numbers = {}
if #dates <= 10 then
for _, v in ipairs(dates) do
table.insert(numbers, { tostring(v), numbers_raw[v].number } )
end
else
local n = #dates - 1
for i = 0, 9 do
local j = math.floor(i * n / 9 + 0.5) + 1
local year = dates[j]
table.insert(numbers, {tostring(year), numbers_raw[year].number})
end
if numbers_raw[dates[n + 1]].number >= 1000000 then
json.marks[2].properties.enter.angle = { value = -45 }
end
end
return numbers
end
local function drawGraph(data, float)
local lang = mw.language.getContentLanguage()
for _, v in pairs(data) do
local d, n = v[1], v[2]
local n_form = tostring(n)
if n >= 10000 then
n_form = lang:formatNum(n)
end
table.insert(json.data[1].values, { x = d, y = n, y_form = n_form })
end
return tostring(mw.html.create("div")
:css("display", "inline-block") -- style hotfix
:css("max-width", "100%")
:css("overflow-x", "auto") -- too wide on mobile
:css("float", float) -- optional
:wikitext(mw.getCurrentFrame():extensionTag("graph", mw.text.jsonEncode(json)))
)
end
local function wikitable(frame, data)
local ret = '{| class="wikitable"\n'
for _, v in ipairs(data) do
ret = ret .. '|-\n|' .. v[1] .. '||' .. frame:expandTemplate { title = 'számt', args = { v[2] }} .. '\n'
end
ret = ret .. '|}'
return ret
end
function p.main(frame)
local args = {}
if type(frame) ~= 'table' then
args = { id = frame }
else
args = getArgs(frame)
end
if args.property then
property = args.property
end
local statements = getStatements(args.id)
if type(statements) ~= 'table' then
return nil
end
statements = prepareStatements(statements)
if type(statements) ~= 'table' then
return nil
end
if #statements < 3 then
return wikitable(frame, statements)
end
return frame:callParserFunction('#tag', { 'templatestyles', '', src = 'Népességdiagram alt1/style.css' }) ..
require('Modul:Népességdiagram alt1').dijagram(statements, {
property = property,
entityId = args.id or mw.wikibase.getEntityIdForCurrentPage(),
naslov = 'Utasforgalom',
yAxisTitle = 'Utasok száma'
})
end
return p