Module:Seats diagram

require('strict') local p = {} local getArgs = require('Module:Arguments').getArgs local errorCategory = '' local getPartyData = require('Module:Political party').fetch

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

local function partyShortLink(p) if getPartyData({p, 'abbrev', error=' '}) == ' ' then return p	end local shortname = getPartyData({p, 'abbrev'}) or getPartyData({p, 'shortname'}) or '' if shortname then return ..shortname.. end return ..p.. end

local function getData(args) local totalSeats = 0 local data = {} local num = 1 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 }			totalSeats = totalSeats + data[num].n			num = num+1 else error(string.format('Invalid value for n%d', num),2) end end data['totalSeats'] = totalSeats return data end

local function generateDiagram(root, args, data) local totalSeats = 0 local width = args.width or 240 local range = root local lastRotation = 0 for i, v in ipairs(data) do		if v.n > 0 then range = range:tag('div') range:css('transform', 'rotate('..tostring(180 * lastRotation)..'deg)') range:css('width', tostring(width)..'px') range:css('height', tostring(width/2)..'px') range:css('position', 'relative') range:css('transform-origin', 'bottom center') range:css('border-top-left-radius', tostring(width/2)..'px') range:css('border-top-right-radius', tostring(width/2)..'px') range:css('background', v.c)			range:tag('div') -- seats number :css('text-align', 'center') :css('width', tostring(width)..'px') :css('height', tostring(width/2)..'px') :css('position', 'absolute') :css('transform', 'rotate('..tostring(-90 + 180 * (v.n/data.totalSeats/2))..'deg)') :css('transform-origin', 'bottom center') :css('top', '-15px') :css('line-height', '15px') :css('padding-bottom', '15px') :wikitext(tostring(v.n)) :done lastRotation = v.n/data.totalSeats end end root:tag('div') --inner circle :css('width', tostring(width*3/8)..'px') :css('height', tostring(width*3/8)..'px') :css('margin', tostring(-width*3/16)..'px auto') :css('border-radius', tostring(width*3/16)..'px') :css('transform', 'translate(0,0)') :css('background', args.background) :done :tag('div') --cover below :css('width', tostring(width+1)..'px') :css('height', tostring(width*3/8)..'px') :css('transform', 'translate(0,0)') :css('background', args.background) :done return root end

local function generateCaption(root, args, data) local list = root:tag('ul') list:css('column-count', '2') list:css('margin-left', '0') for i, v in ipairs(data) do		list:tag('li') --li :css('list-style-type', 'none') :css('list-style-image', 'none') :css('margin', '0') :tag('span') --span :css('border', 'none') :css('width', '1.2em') :css('height', '1.2em') :css('background-color', v.c)				:css('margin-right', '0.3em') :css('vertical-align', 'middle') :css('display', 'inline-block') :done :wikitext(partyShortLink(v.p) .. ': ' .. v.n)			:done end return list end

local function parliamentFloat(root, args, data) local width = args.width or 240 local mainDiv = root:tag('div') mainDiv:addClass('thumb') mainDiv:addClass('t'..args['float']) local divThumbinner = mainDiv:tag('div') divThumbinner:addClass('thumbinner') divThumbinner:css('width', tostring(width*1.125)..'px') divThumbinner:css('padding-right', '6.5px !important') if args['title'] then local divTitle = divThumbinner:tag('div') divTitle:addClass('thumbdescription') divTitle:css('font-weight', 'bold') divTitle:css('text-align', 'center') divTitle:css('font-size', '100%') divTitle:wikitext(args['title']) end local divThumbimage = divThumbinner:tag('div') divThumbimage:addClass('thumbimage') divThumbimage:addClass('diagram') divThumbimage:addClass('noprint') divThumbimage:css('width', tostring(width)..'px') divThumbimage:css('height', tostring(width/2)..'px') divThumbimage:css('padding', tostring(width/15)..'px') divThumbimage:css('overflow', 'hidden') divThumbimage:css('background', args.background) generateDiagram(divThumbimage, args, data) local divThumbcaption = divThumbinner:tag('div') divThumbcaption:addClass('thumbcaption') divThumbcaption:wikitext('Total '..tostring(data.totalSeats)..' seats') generateCaption(divThumbcaption, args, data) return root end

local function parliamentNonFloat(root, args, data) local width = args.width or 240 local mainDiv = root:tag('div') local divCentered = mainDiv:tag('div') divCentered:addClass('centered') divCentered:css('margin-left', 'auto') divCentered:css('margin-right', 'auto') divCentered:addClass('diagram') divCentered:addClass('noprint') divCentered:css('width', tostring(width)..'px') divCentered:css('height', tostring(width/2)..'px') divCentered:css('padding', tostring(width/15)..'px') divCentered:css('padding-top', '15px') divCentered:css('padding-bottom', '5px') divCentered:css('overflow', 'hidden') divCentered:css('background', args.background) divCentered:css('text-align', 'center') generateDiagram(divCentered, args, data) return root end

function p._parliament(args) local root = mw.html.create('div') local data = getData(args) if not args.background then args.background = 'white' end if args['float'] then return parliamentFloat(root, args, data) else return parliamentNonFloat(root, args, data) end end

function p.parliament(frame) return p._parliament(getArgs(frame)) end

return p