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>'}
flex['destra'] = {'<div class="floatright">','</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 = "tab",
transform = { { type = "sort", by = "nx" } },
values = { }
},
{
name = "tab2",
transform = { { type = "sort", by = "nx" } },
values = { }
},
{
name = "tab3",
transform = { { type = "sort", by = "nx" } },
values = { }
},
{
name = "nomi",
values = { }
}
},
scales = {
{
name = "x",
type = "linear",
range = "width",
zero = false,
___domain = {fields = {{data = "tab",field = "nx"}, {data = "tab2",field = "nx"}, {data = "tab3",field = "nx"}}}
},
{
name = "y",
type = "linear",
range = "height",
zero = true,
nice = true,
___domain = {fields = {{data = "tab",field = "ny"}, {data = "tab2",field = "ny"}, {data = "tab3",field = "ny"}}}
},
{
name = "colori",
type = "ordinal",
___domain = { data = "nomi", field = "testo"},
range = { "#1f77b4", "b80000", "#00c000" }
}
},
axes = {
{
type = "x",
scale = "x",
title = "X",
format = "d",
grid = true,
},
{
type = "y",
scale = "y",
title = "Y",
grid = true,
format = "d",
layer = "back"
}
},
legends = {
{
fill = "colori",
title = "",
orient = "top-left",
offset = 8,
shape = { value = "square" },
strokeWidth = { value = 0 }
}
},
marks = {
{
type = "line",
from = {data = "tab" },
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 = "tab2" },
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 = "line",
from = {data = "tab3" },
properties = {
enter = {
interpolate = {value = "linear"},
x = {scale = "x",field = "nx"},
y = {scale = "y",field = "ny"},
stroke = {value = "#00c000"},
strokeWidth = {value = 4},
opacity = {value = 0.5}
}
}
},
{
type = "symbol",
from = {data = "tab"},
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 = "tab2"},
properties = {
enter = {
x = {scale = "x",field = "nx"},
y = {scale = "y",field = "ny"},
stroke = {value = "#b80000"},
fill = {value = "#fff"},
size = {value = 30}
}
}
},
{
type = "symbol",
from = {data = "tab3"},
properties = {
enter = {
x = {scale = "x",field = "nx"},
y = {scale = "y",field = "ny"},
stroke = {value = "#00c000"},
fill = {value = "#fff"},
size = {value = 30}
}
}
},
{
type = "text",
from = { data = "tab" },
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 = "tab2" },
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 = "tab3" },
properties = {
enter = {
x = {scale = "x",field = "nx"},
y = {scale = "y",field = "ny", offset = -6},
align = {value = "center"},
fill = {value = "#000"},
text = {field = "ny" }
}
}
}
}
}
-- titoli assi
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
-- zero su assi
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
-- legge valori
local dx1 = leggi(args, "x1")
local dy1 = leggi(args, "y1")
local dx2 = leggi(args, "x2")
local dy2 = leggi(args, "y2")
local dx3 = leggi(args, "x3")
local dy3 = leggi(args, "y3")
graph['data'][1]['values'] = unisci(dx1, dy1, fattoreX, fattoreY)
graph['data'][2]['values'] = unisci(dx2, dy2, fattoreX, fattoreY)
graph['data'][3]['values'] = unisci(dx3, dy3, fattoreX, fattoreY)
-- dimensioni
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
-- colori
if args.colore1 then
graph['marks'][1]['properties']['enter']['stroke']['value'] = args.colore1
graph['marks'][4]['properties']['enter']['stroke']['value'] = args.colore1
graph['scales'][3]['range'][1] = args.colore1
end
if args.colore2 then
graph['marks'][2]['properties']['enter']['stroke']['value'] = args.colore2
graph['marks'][5]['properties']['enter']['stroke']['value'] = args.colore2
graph['scales'][3]['range'][2] = args.colore2
end
if args.colore3 then
graph['marks'][3]['properties']['enter']['stroke']['value'] = args.colore3
graph['marks'][6]['properties']['enter']['stroke']['value'] = args.colore3
graph['scales'][3]['range'][3] = args.colore3
end
-- opzioni etichette
if args.etichette1 then
if args.etichette1 == 'dispari' then
graph['marks'][7]['from']['transform'] = {{ type = "filter", test = "datum.num % 2 == 1"}}
elseif args.etichette1 == 'pari' then
graph['marks'][7]['from']['transform'] = {{ type = "filter", test = "datum.num % 2 == 0"}}
elseif args.etichette1 == 'no' then
graph['marks'][7]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
end
end
if args.mostra1 then
if args.mostra1 == '1' then
graph['marks'][4]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
elseif args.mostra1 == '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'][8]['from']['transform'] = {{ type = "filter", test = "datum.num % 2 == 1"}}
elseif args.etichette2 == 'pari' then
graph['marks'][8]['from']['transform'] = {{ type = "filter", test = "datum.num % 2 == 0"}}
elseif args.etichette2 == 'no' then
graph['marks'][8]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
end
end
if args.mostra2 then
if args.mostra2 == '1' then
graph['marks'][5]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
elseif args.mostra2 == '2' then
graph['marks'][2]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
end
end
if args.etichette3 then
if args.etichette3 == 'dispari' then
graph['marks'][9]['from']['transform'] = {{ type = "filter", test = "datum.num % 2 == 1"}}
elseif args.etichette3 == 'pari' then
graph['marks'][9]['from']['transform'] = {{ type = "filter", test = "datum.num % 2 == 0"}}
elseif args.etichette3 == 'no' then
graph['marks'][9]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
end
end
if args.mostra3 then
if args.mostra3 == '1' then
graph['marks'][6]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
elseif args.mostra3 == '2' then
graph['marks'][3]['from']['transform'] = {{ type = "filter", test = "datum.num < 1"}}
end
end
-- legenda
if args.nome1 then graph['data'][4]['values'][1] = { testo = args.nome1 } end
if args.nome2 then graph['data'][4]['values'][2] = { testo = args.nome2 } end
if args.nome3 then graph['data'][4]['values'][3] = { testo = args.nome3 } 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