Jump to content

Module:Graph

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Mps (talk | contribs) at 18:12, 2 June 2015 (AZ: Die Seite wurde neu angelegt: local p = {} function p.map(frame) -- Kartendaten local map = mw.title.new(frame.args.map or "Wikip…). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
(diff) ← Previous revision | Latest revision (diff) | Newer revision → (diff)

local p = {}

function p.map(frame)
	-- Kartendaten
	local map = mw.title.new(frame.args.map or "Wikipedia:Graph/WorldMap-iso2.json")
	-- Kartenskalierung (hängt von den Kartendaten ab)
	local scale = tonumber(frame.args.scale) or 80
	-- Kartenprojektion: siehe https://github.com/mbostock/d3/wiki/Geo-Projections
	local projection = frame.args.projection or "equirectangular"
	-- Standardfarbe für Staaten ohne Daten
	local defaultColor = frame.args.defaultColor or "#C0C0C0"
	local scaleType = frame.args.scaleType or "linear"
	-- minimaler Wertebereich (nur für numerische Daten)
	local domainMin = tonumber(frame.args.domainMin)
	-- maximaler Wertebereich (nur für numerische Daten)
	local domainMax = tonumber(frame.args.domainMax)
	-- Farbwerte der Farbskala (nur für numerische Daten)
	local colorScale = frame.args.colorScale or "category10"
	
	-- Kartenmarkierungen als Schlüssel-Wert-Paare: Schlüssel müssen Großbuchstaben, Ziffern oder "-" sein (idealerweise ISO-Codes) und den "id"-Werten der Kartendaten entsprechen
	local values = {}
	local isNumbers = nil
	for name, value in pairs(frame.args) do
		local startPos, endPos = string.find(name, "[A-Z0-9\-]+")
		if startPos == 1 and endPos == string.len(name) then
			if isNumbers == nil then isNumbers = tonumber(value) end
			local data = { id = name, v = value }
			if isNumbers then data.v = tonumber(data.v) end
			table.insert(values, data)
		end
	end

	-- Skalen
	local scales
	if isNumbers then
		if colorScale == "category10" or colorScale == "category20" then else colorScale = mw.text.split(colorScale, ",") end
		scales =
		{
			{
				name = "color",
				type = scaleType,
				domain = { data = "highlights", field = "data.v" },
				range = colorScale,
				nice = true
			}
		}
		if domainMin then scales[1].domainMin = domainMin end
		if domainMax then scales[1].domainMax = domainMax end

		local exponent = string.match(scaleType, "pow%s+(%d+%.%d+)") -- auf Exponenten für exponentielle Darstellung prüfen
		if exponent then
			scales[1].type = "pow"
			scales[1].exponent = exponent
		end
	end
	
	local mapNamespace = map.nsText
	if string.len(mapNamespace) > 0 then mapNamespace = mapNamespace .. ":" end
	
	local output =
	{
		width = 1,  -- Dummywert, da Ausgabegröße von den Kartendaten und der Skalierung abhängt
		height = 1, -- dito
		data = 
		{
			{
				-- Datenquelle der Kartenmarkierungen
				name = "highlights",
				values = values
			},
			{
				-- Datenquelle der Kartendaten
				name = "countries",
				url = "/w/index.php?title=" .. mapNamespace .. map:partialUrl() .. "&action=raw",
				format = { type = "topojson", feature = "countries" },
				transform =
				{
					{
						-- geografische Transformation ("geopath") der Kartendaten
						type = "geopath",
						value = "data",			-- Datenquelle
						scale = scale,			-- Skalierungsfaktor
						translate = { 0, 0 },	-- Translation
						projection = projection	-- Projektionsmethode
					},
					{
						-- Zusammenführung ("zip") mehrerer Datenquellen: hier Kartendaten mit Kartenmarkierungen ("highlights")
						type = "zip",
						key = "data.id",     -- Schlüssel der Kartendaten
						with = "highlights", -- Name der Datenquelle der Kartenmarkierungen
						withKey = "data.id", -- Schlüssel der Kartenmarkierungen
						as = "zipped",       -- Ergebnistabellenname
						default = { data = { v = defaultColor } } -- Standardaktion für geografische Objekte ohne Entsprechung in unserem Datensatz
					}
				}
			}
		},
		marks =
		{
			-- Markierungen ausgeben
			{
				type = "path",
				from = { data = "countries" },
				properties = 
				{
					enter = { path = { field = "path" } },
					update = { fill = { field = "zipped.data.v" } },
					hover = { fill = { value = "darkgrey" } } -- hat außerhalb der Vorschau keine Wirkung, daher kein Extra-Parameter
				}
			}
		}
	}
	if (scales) then
		output.scales = scales
		output.marks[1].properties.update.fill.scale = "color"
	end

	return mw.text.jsonEncode(output)
end

return p