Zum Inhalt springen

Modul:WikidataChart

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 5. Juli 2017 um 01:06 Uhr durch Mps (Diskussion | Beiträge). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Modul mit Komfortfunktionen um Daten aus Wikidata grafisch in Diagrammform aufzubereiten.

Zur Verwendung siehe {{WikidataChart}}.


local graph = require("Modul:Graph")

local p = {}

function p.chartWikidata(frame)
	-- Datenparameter
	local property = frame.args[1] or error("Wikidata property to chart required")
	local xQualifier = frame.args["xQualifier"] or error("Wikidata qualifier for x axis required")
	local yIds = mw.text.split(frame.args["yIds"] or error("Wikidata ids for y axis required"), ",", true)
	local xStart = frame.args["xStart"]
	local xEnd = frame.args["xEnd"]
	-- Diagrammparameter
	local width = frame.args["width"]
	local height = frame.args["height"]
	
	local series = { captions = {}, points = {} }
	
	for seriesIdx, id in ipairs(yIds) do
		local entity = mw.wikibase.getEntity(id)
		
		local labels = entity.labels or {}
		series.captions[seriesIdx] = (labels.de or labels.en or {}).value or id

		local property = entity.claims[property]
		for _, item in ipairs(property) do
			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 = mw.text.trim(qualifier.datavalue.value.time, "+")
			
			if (not xStart or x >= xStart) and (not xEnd or x <= xEnd) 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

	local xValues = {}
	for k in pairs(series.points) do table.insert(xValues, k) end
	table.sort(xValues)

	local chartArgs =
	{
		width = width,
		height = height,
		type = "line",
		xType = "date",
		x = table.concat(xValues, ","),
		yType = "number"
	}
	local seriesCount = 0
	-- Legenden/Reihentitel setzen
	for seriesIdx, caption in ipairs(series.captions) do
		chartArgs["y" .. seriesIdx] = ""
		chartArgs["y" .. seriesIdx .. "Title"] = caption
		seriesCount = seriesCount + 1
	end
	-- Werte setzen
	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
	-- Separatoren am Anfang entfernen
	for seriesIdx, _ in ipairs(series.captions) do
		chartArgs["y" .. seriesIdx] = mw.ustring.sub(chartArgs["y" .. seriesIdx], 2)
	end

	return graph.chart({ args = chartArgs })
end

return p