Module:Parliament diagram

Implements {{Parliament diagram}}

Module:Parliament diagram

require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local errorCategory = '[[Category:Compilation error of the Parliamentary diagram template]]'
local getColor = require('Module:Political party').fetch
local dimx = 175
local dimr = 50
local dimc = 40
local limite = 2000
local bgcolor = "#fff"

-- Error handler using xpcall, format the error
local function errhandler(msg)
	local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or ''
	return string.format('<span class="error">%s</span>%s', msg, cat)
end

-- create a single array from string
local function agg(a,...)
    local args = {...}
    for _, s in ipairs(args) do
        table.insert(a, s)
    end
end

-- get the party color from Module:Party color
-- a = party; b = optional color
local function color(a,b)
	local c = '#CCC'
	if (b) then
		c = b
	else
		c = getColor({a, "color"})
	end
	if string.sub(c,1,5) == '&#35;' then c = "#" .. string.sub(c, 6, 11) end
	return c
end

-- create circles
local function values(n)
	local totals= {4, 17, 36, 65, 100, 144, 196, 255, 322, 398, 480, 571, 670, 776, 891, 1013, 1143, 1281, 1427, 1580, 1743, 1911, 2089}

   	local dots = 0
	local benches = 1
	local jj,rr,aa

	-- searches for the amount of benches needed to show all the dots
   	while (n > totals[benches]) do
      benches = benches + 1
	end
	local dd = dimr/benches -- distance between the arches
	dimc = 0.7*dimr/benches -- size of the circles
	local list = {} -- list of dots
	-- calculate angle and radius of each dot
	for rg=0,benches-2 do
		rr = dimx - dd*(2*rg+1) -- radius
    	jj = math.floor((n/totals[benches])*math.pi/(2*math.asin(dd/rr)))+1 --n° dots
    	if (jj==1) then
      		dots = dots + 1
        	list[dots] = {0.5, rr}
    	else
        	for ps=0,jj-1 do
        		aa = ps/(jj-1)
        		dots = dots + 1
        		list[dots] = {aa,rr}
        	end
        end
	end
	-- dots left to place on an internal arch
    jj=n-dots
    rr= dimx - dd*(2*benches-1) -- radius
    if (jj==1) then
		dots = dots + 1
		list[dots] = {1/2, rr}
    else
    	for ps=0,jj-1 do
			aa=ps/(jj-1)
			dots = dots + 1
			list[dots] = {aa,rr}
		end
	end
	-- order dots per increasing angle from the center
	table.sort(list, function(a,b) return ((a[1]<b[1]) or (a[1]==b[1] and a[2]<b[2])) end)
	return list
end

-- create the parliamentary arch
function p._parliament(args)
	local ss = {}
	local ss2 = {}
	local data = {}
	local num = 1
	local totalDots = 0
	local cap = args.caption or ''
	local show = tonumber(args.show) or 0

	while (args['n'..num]) do
		if (tonumber(args['n'..num])) then
			data[num] = {
				n = args['n'..num] and tonumber(args['n'..num]),
				c = color(args['p'..num] or '', args['c'..num]),
				b = args['b'..num] or '-',
				p = args['p'..num] or 'Serie '..num
			}
			totalDots = totalDots + data[num].n
			num = num+1
		else
			error(string.format('Invalid value for n%d', num),2)
		end
	end
	num = num - 1
	if (totalDots>limite) then
		error('Number of dots superior to the limit')
	elseif (totalDots<1) then
		error('No dots are indicated')
	end
	local dots = values(totalDots)
	local width = 2*dimx
	local height = dimx+dimc
	local scale = 1.0
	if (args['background']) then
		bgcolor = args['background']
	end
	if (args['width'] and tonumber(args['width'])) then
		width = tonumber(args['width'])
		scale = width/(2*dimx)
		height = (dimx+dimc)*scale
	elseif (args['height'] and tonumber(args['height'])) then
		height = tonumber(args['height'])
		scale = height/(dimx+dimc)
		width = 2*dimx*scale
	elseif (totalDots<29) then
		width = 280
		scale = width/(2*dimx)
		height = (dimx+dimc)*scale
	elseif (totalDots<101) then
		width = 300
		scale = width/(2*dimx)
		height = (dimx+dimc)*scale
	elseif (totalDots<281) then
		width = 350
		scale = width/(2*dimx)
		height = (dimx+dimc)*scale
	end
	
	-- TEMPORARY FIX WHILE THE GRAPH EXTENSION IS DISABLED --
	local seats_diagram = require('Module:Seats_diagram')
	args.width = width
	if true then return tostring(seats_diagram._parliament(args)) end
	---------------------------------------------------------
	
	local graph = {
		version = 2, width = width, height = height, padding = "no",
		background = bgcolor,
		data = { },
		scales = {
			{ name = "x", type = "linear", range = "width", zero = true, domainMin = 0, domainMax = 2*dimx },
			{ name = "y", type = "linear", range = "height", zero = true, domainMin = 0, domainMax = dimx + dimc }
		},
		marks = { }
	}
	local ee = 0
	local values
	for i=1,num do
		values = {}
		for j=1,data[i].n do
			ee = ee + 1
			values[j] = {
				px = dimx-dots[ee][2]*math.cos(math.pi*dots[ee][1]),
				py = dimc+dots[ee][2]*math.sin(math.pi*dots[ee][1]),
			}
		end
		graph['data'][i] = { name = "tab"..i, values = values }
		graph['marks'][i] = { type = "symbol", from = {data = "tab"..i },
			properties = {
				enter = {
					x = {scale = "x",field = "px"},
					y = {scale = "y",field = "py"},
					fill = {value = data[i].c},
					size = {value = (2*dimc*scale)^2}
				}
			}
		}
		if (data[i].b ~= "-") then
			local bl = data[i].b
			if string.sub(bl,1,5) == '&#35;' then bl = "#" .. string.sub(bl, 6, 11) end
			graph['marks'][i]['properties']['enter']['stroke'] = {value = bl}
			graph['marks'][i]['properties']['enter']['strokeWidth'] = {value = 1}
		end
	end
	graph['marks'][num+1] = {
		type = "text",
		properties = {
			enter = {
				x = {scale = "x",value=dimx},
				y = {scale = "y",value=dimc+8},
				align = {value = "center"},
				fill = {value = "#000"},
				font = {value = "Helvetica"},
				fontSize = { value = 36*scale },
				fontWeight = { value = "bold" },
				text = {value = totalDots }
			}
		}
	}
	agg(ss, mw.getCurrentFrame():extensionTag('graph', mw.text.jsonEncode(graph)))
	if (cap ~= '') then
		agg(ss,string.format('<p style="font-size:90%%; margin-left:10px">%s</p>',cap))
	end
	if show == 1 then
		for i=1,num do
			agg(ss2,string.format('<span style="display:inline-block;border:solid grey 1px;background:%s;width:1em;height:1em">&nbsp;</span>&nbsp;%s', data[i].c, data[i].n))
		end
		agg(ss,'<p style="font-size:90%; margin-left:10px">')
		agg(ss,table.concat(ss2," · "))
		agg(ss,'</p>')
	elseif show ==2 then
		for i=1,num do
			agg(ss2,string.format('<span style="display:inline-block;border:solid grey 1px;background:%s;width:1em;height:1em">&nbsp;</span>&nbsp;%s %s', data[i].c, data[i].p, data[i].n))
		end
		agg(ss,'<p style="font-size:90%; margin-left:10px">')
		agg(ss,table.concat(ss2,"<br/>"))
		agg(ss,'</p>')
	end
	if args['debug'] then
		return mw.text.jsonEncode(graph)
	else
		return table.concat(ss)
	end
end

function p.parliament(frame)
	return select(2, xpcall(function()
		return p._parliament(getArgs(frame, { parentOnly = true }))
	end, errhandler))
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.

  1. 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:
  2. 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.
  3. 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.
  4. 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.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.