Info Istruzioni per l'uso
Questo è un modulo scritto in Lua. Le istruzioni che seguono sono contenute nella sottopagina Modulo:Grafico XY/man (modifica · cronologia)
Sandbox: Modulo:Grafico XY/sandbox (modifica · cronologia) · Sottopagine: lista · Test: Modulo:Grafico XY/test (modifica · cronologia · esegui)

Questo modulo serve a creare un grafico per {{Grafico XY}}.


require("Module:No globals")
local getArgs = require('Module:Arguments').getArgs
local p = {}

local flex = {}
flex['primo'] = {'<div style="display:flex;flex-direction:row;flex-wrap:wrap"><div style="flex-grow:0;flex-shrink:0;flex-basis:auto;padding: 0 2em 0 0">','</div>'}
flex['medio'] = {'<div style="flex-grow:0;flex-shrink:0;flex-basis:auto;padding: 0 2em 0 0">','</div>'}
flex['ultimo'] = {'<div style="flex-grow:0;flex-shrink:0;flex-basis:auto;padding: 0 2em 0 0">','</div></div>'}

-- =====================================================================
-- Legge gli argomenti per caricare un array di valori numerici.
-- =====================================================================
local function leggi(args, a)
	local array = {}
	if args[a] then
		array = mw.text.split(string.gsub(args[a], "%s", ""), ",")
	end
	for _,v in ipairs(array) do
		v = tonumber(v)
	end
	return array
end
-- =====================================================================
-- Fonde due liste in un'unica lista
-- =====================================================================
local function unisci(a,b,c,d)
	local values = { }
	for i =1,#b do
		values[i] = { nx = a[i]/c, ny = b[i]/d, num = i }
	end
	return values
end

-- =====================================================================
-- Generazione del grafico
-- =====================================================================
function p._grafico(args)
	-- Definizione base del grafico
	local graph = {
		version = 2,
		width = 350,
		height = 250,
		padding = "auto",
		data = {
			{
				name = "table",
				transform = { { type = "sort", by = "nx" } },
				values = { }
			},
			{
				name = "table2",
				transform = { { type = "sort", by = "nx" } },
				values = {  }
			}
		},
		scales = {
			{
				name = "x",
				type = "linear",
				range = "width",
				zero = false,
				___domain = {fields = {{data = "table",field = "nx"}, {data = "table2",field = "nx"}}}
			},
			{
				name = "y",
				type = "linear",
				range = "height",
				zero = true,
				nice = true,
				___domain = {fields = {{data = "table",field = "ny"}, {data = "table2",field = "ny"}}}
			}
		},
		axes = {
			{
				type = "x",
				scale = "x",
				title = "X",
				format = "d",
				grid = true,
			},
			{
				type = "y",
				scale = "y",
				title = "Y",
				grid = true,
				format = "d",
				layer = "back"
			}
		},
		marks = {
			{
				type = "line",
				from = {data = "table" },
				properties = {
					enter = {
						interpolate = {value = "linear"},
						x = {scale = "x",field = "nx"},
						y = {scale = "y",field = "ny"},
						stroke = {value = "#1f77b4"},
						strokeWidth = {value = 4},
						opacity = {value = 0.5}
					}
				}
			},
			{
				type = "line",
				from = {data = "table2" },
				properties = {
					enter = {
						interpolate = {value = "linear"},
						x = {scale = "x",field = "nx"},
						y = {scale = "y",field = "ny"},
						stroke = {value = "#b80000"},
						strokeWidth = {value = 4},
						opacity = {value = 0.5}
					}
				}
			},
			{
				type = "symbol",
				from = {data = "table"},
				properties = {
					enter = {
						x = {scale = "x",field = "nx"},
						y = {scale = "y",field = "ny"},
						stroke = {value = "1f77b4"},
						fill = {value = "#fff"},
						size = {value = 30}
					}
				}
			},
			{
				type = "symbol",
				from = {data = "table2"},
				properties = {
					enter = {
						x = {scale = "x",field = "nx"},
						y = {scale = "y",field = "ny"},
						stroke = {value = "#b80000"},
						fill = {value = "#fff"},
						size = {value = 18}
					}
				}
			},
			{
				type = "text",
				from = { data = "table" },
				properties = {
					enter = {
						x = {scale = "x",field = "nx"},
						y = {scale = "y",field = "ny", offset = -6},
						align = {value = "center"},
						fill = {value = "#000"},
						text = {field = "ny" }
					}
				}
			},
			{
				type = "text",
				from = { data = "table2" },
				properties = {
					enter = {
						x = {scale = "x",field = "nx"},
						y = {scale = "y",field = "ny", offset = -6},
						align = {value = "center"},
						fill = {value = "#000"},
						text = {field = "ny" }
					}
				}
			}
		}
	}
	local titoloX = args.titoloX or 'X'
	local fattoreX = args.fattoreX and tonumber(args.fattoreX) and tonumber(args.fattoreX) or 1
	if fattoreX == 0 then
		fattoreX = 1
	elseif fattoreX == 1000 then
		titoloX = titoloX..' (migliaia)'
	elseif fattoreX == 1000000 then
		titoloX = titoloX..' (milioni)'
	end
	graph['axes'][1]['title'] = titoloX
	local titoloY = args.titoloY or 'Y'
	local fattoreY = args.fattoreY and tonumber(args.fattoreY) and tonumber(args.fattoreY) or 1
	if fattoreY == 0 then
		fattoreY = 1
	elseif fattoreY == 1000 then
		titoloY = titoloY..' (migliaia)'
	elseif fattoreY == 1000000 then
		titoloY = titoloY..' (milioni)'
	end
	graph['axes'][2]['title'] = titoloY
	
	if (args.zeroX and args.zeroX == 's') then
		graph['scales'][1]['zero'] = true
	end
	if (args.zeroY and args.zeroY == 'n') then graph['scales'][2]['zero'] = false end

	local dx1 = leggi(args, "x1")
	local dy1 = leggi(args, "y1")
	local dx2 = leggi(args, "x2")
	local dy2 = leggi(args, "y2")
	graph['data'][1]['values'] =  unisci(dx1, dy1, fattoreX, fattoreY)
	graph['data'][2]['values'] =  unisci(dx2, dy2, fattoreX, fattoreY)
	graph['width'] = args.dimx and tonumber(args.dimx) and tonumber(args.dimx) or 350
	graph['height'] = args.dimy and tonumber(args.dimy) and tonumber(args.dimy) or 250

	if args.etichette1 then
		if args.etichette1 == 'dispari' then
			graph['marks'][5]['from']['transform'] = {{ type = "filter", test = "(datum.num > 1) && (datum.num % 2 == 1)"}}
		elseif args.etichette1 == 'pari' then
			graph['marks'][5]['from']['transform'] = {{ type = "filter", test = "(datum.num > 1) && (datum.num % 2 == 0)"}}
		elseif args.etichette1 == 'no' then
			graph['marks'][5]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
		end
	end
	if args.tipo1 then
		if args.tipo1 == '1' then
			graph['marks'][3]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
		elseif args.tipo1 == '2' then
			graph['marks'][1]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
		end
	end
	if args.etichette2 then
		if args.etichette2 == 'dispari' then
			graph['marks'][6]['from']['transform'] = {{ type = "filter", test = "(datum.num > 1) && (datum.num % 2 == 1)"}}
		elseif args.etichette2 == 'pari' then
			graph['marks'][6]['from']['transform'] = {{ type = "filter", test = "(datum.num > 1) && (datum.num % 2 == 0)"}}
		elseif args.etichette2 == 'no' then
			graph['marks'][6]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
		end
	end
	if args.tipo2 then
		if args.tipo2 == '1' then
			graph['marks'][4]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
		elseif args.tipo2 == '2' then
			graph['marks'][2]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
		end
	end

	local ris = {}
	local allinea = args['allinea'] or ''
	if (flex[allinea]) then table.insert(ris,flex[allinea][1]) end
	table.insert(ris,mw.getCurrentFrame():extensionTag('graph', mw.text.jsonEncode(graph)))
	if (args.didascalia) then
		table.insert(ris,'<p>'..args.didascalia..'</p>')
	end
	if (flex[allinea]) then table.insert(ris,flex[allinea][2]) end
	return table.concat(ris)
end

-- ======================================================================================================
-- Funzione di intefaccia con template:Demografia
-- ======================================================================================================
function p.grafico(frame)
	local args = getArgs(frame)
	return p._grafico(args)
end

return p