Module:WikidataChart
Implements {{WikidataChart}}
local defaultFormat = {
[0] = "Y", -- precision: billion years
[1] = "Y", -- precision: hundred million years
[2] = "Y", -- precision: ten million years
[3] = "Y", -- precision: million years
[4] = "Y", -- precision: hundred thousand years
[5] = "Y", -- precision: ten thousand years
[6] = "Y", -- precision: millennium
[7] = "Y", -- precision: century
[8] = "Y", -- precision: decade
[9] = "Y", -- precision: year
[10] = "M Y", -- precision: month
[11] = "j F Y", -- precision: day
[12] = "j F Y ga", -- precision: hour
[13] = "j F Y g:ia", -- precision: minute
[14] = "j F Y g:i:sa" -- precision: second
}
local p = {}
function p.plot(frame)
local property = frame.args[1] or error("Wikidata property to chart required")
local xQualifier = frame.args[2] or error("Wikidata qualifier for x axis required")
local yIds = mw.text.split(frame.args["pageIds"] or "", ",", true)
local xStart = frame.args["xStart"]
local xEnd = frame.args["xEnd"]
local precision = tonumber(frame.args["precision"])
local xAxisFormat = defaultFormat[precision or 9]
-- Collect data
local series = { captions = {}, points = {} }
for seriesIdx, id in ipairs(yIds) do
if id == "" then id = nil end
local entity = mw.wikibase.getEntity(id)
local labels = entity.labels or {}
series.captions[seriesIdx] = (labels.en or labels.de or {}).value or id
local property = entity.claims[property]
for _, item in ipairs(property) do
if item.qualifiers and item.qualifiers[xQualifier] and item.qualifiers[xQualifier][1] then
local qualifier = item.qualifiers[xQualifier][1]
if qualifier.snaktype ~= "value" or qualifier.datatype ~= "time" then
error("'xQualifier' parameter must be a time")
end
local x = applyPrecision(mw.text.trim(qualifier.datavalue.value.time, "+"), precision)
if (not xStart or x >= xStart) and (not xEnd or string.sub(x, 1, #xEnd) <= xEnd) and qualifier.datavalue.value.precision >= (precision or 0) then
local mainsnak = item.mainsnak
if mainsnak.snaktype ~= "value" or mainsnak.datatype ~= "quantity" then
error("'property' parameter must be numeric")
end
local y = tonumber(mainsnak.datavalue.value.amount)
if not series.points[x] then series.points[x] = {} end
series.points[x][seriesIdx] = y
end
end
end
end
-- Sort x values
local xValues = {}
for k in pairs(series.points) do table.insert(xValues, k) end
table.sort(xValues)
-- default values, can be overwritten
local chartArgs =
{
type = "line",
xType = "date",
x = table.concat(xValues, ","),
yType = "number",
-- these are not supported anymore with new chart extension as of now..
-- xAxisTitle = mw.wikibase.label(xQualifier),
-- yAxisTitle = mw.wikibase.label(property)
}
-- Set legends / series titles
for seriesIdx, caption in ipairs(series.captions) do
chartArgs["y" .. seriesIdx] = ""
chartArgs["y" .. seriesIdx .. "Title"] = caption
end
-- Set values
local seriesCount = #series.captions
for _, x in ipairs(xValues) do
yValues = series.points[x]
for seriesIdx = 1, seriesCount do
chartArgs["y" .. seriesIdx] = chartArgs["y" .. seriesIdx] .. "," .. (yValues[seriesIdx] or "")
end
end
-- Remove separators at the beginning
for seriesIdx, _ in ipairs(series.captions) do
chartArgs["y" .. seriesIdx] = mw.ustring.sub(chartArgs["y" .. seriesIdx], 2)
end
-- Transfer diagram parameters (all parameters that start with chart_ are transferred directly to the Graph module without a prefix)
for k, v in pairs(frame.args) do
local chartParam = string.match(k, "^chart_(.+)")
if chartParam then chartArgs[chartParam] = v end
end
--workaround, to better show dates since the extension doesn't support them yet properly
if chartArgs["xType"]=="date" then
xValuesCutted = {}
for _, k in pairs(xValues) do
table.insert(xValuesCutted,string.sub( k, 1, 10))
end
chartArgs["x"] = table.concat(xValuesCutted, ",")
end
-- if number, use precision to round (default 9=years)
if chartArgs["xType"]=="number" then
xValuesCutted = {}
for _, k in pairs(xValues) do
table.insert(xValuesCutted,mw.getContentLanguage():formatDate(xAxisFormat, k))
end
chartArgs["x"] = table.concat(xValuesCutted, ",")
end
-- create the plot
local resultplot
resultplot = mw.getCurrentFrame():expandTemplate {
title = 'Template:ChartDirect',
args = chartArgs
}
return resultplot
end
function p.plotWrapper(frame)
return p.plot(frame:getParent())
end
function applyPrecision(date, precision)
if not precision then precision = math.huge end
local _, _, year, month, day, hour, minute, second, timezone = string.find(date, "^(.?%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)(.+)$")
if precision < 14 then second = "00" end
if precision < 13 then minute = "00" end
if precision < 12 then hour = "00" end
if precision < 11 or day == "00" then day = "01" end
if precision < 10 or month == "00" then month = "01" end
return year .. "-" .. month .. "-" .. day .. "T" .. hour .. ":" .. minute .. ":" .. second .. timezone
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.