Module:Dot chart
local p = {}
 local getArgs = require(&quot;Module:Arguments&quot;).getArgs
 local yesno = require('Module:Yesno')
 
 --------------------------------------------------------------------------------
 ---------- P . D O T S ---------------------------------------------------------
 ---------- Returns all the dots (with absolute postions) -----------------------
 --------------------------------------------------------------------------------
 
 function p.data(frame)                                                          -- Returns the data of the graph
 	local args = getArgs(frame)
 	-- Dot related
 	local yTable = {}
 	local xTable = {}
 	local xCount = 0
 	local yCount = 0
 	local isx;
 	local dotTable = {}
 	local x;
 	-- Color related
 	local colorTable = {}
 	local num;
 	local colorTime;
 	-- X label related
 	local xLabels = {}
 	local xLCount = 0
 	-- Y label related
 	local yLabels = {}
 	local yLCount = 0
 
 	if yesno(args[&quot;yx&quot;]) == true then
 		isx = false
 	else
 		isx = true
 	end
 	
 	if args[&quot;x labels&quot;] then                                                    -- Create xLabels
 		for str in string.gmatch(args[&quot;x labels&quot;], &quot;([^,]+)&quot;) do
 	        table.insert(xLabels,str)
 	        xLCount = xLCount+1
 	    end
 	end
 	
 	if args[&quot;y labels&quot;] then                                                    -- Create yLabels
 		for str in string.gmatch(args[&quot;y labels&quot;], &quot;([^,]+)&quot;) do
 			table.insert(yLabels,str)
 			yLCount = yLCount+1
 	    end
 	end
 	
 	if args[&quot;dots&quot;] then                                                        -- Creates xTable from dots
 		local i = 0
 		local j = 0
 		
 		for k,v in pairs(args) do
 			if string.match(k,&quot;%d+&quot;) 
 			and not string.match(k,&quot;color%-&quot;) then
 				table.insert(yTable,v)
 				yCount = yCount+1
 			end
 		end
 		
 		local cols = yCount / tonumber(args[&quot;dots&quot;])
 		
 		if cols ~= math.floor(cols) then
 			return table.concat({'&lt;span style=&quot;font-size:100%&quot; class=&quot;error&quot;&gt;The amount of y parameters (',yCount,') ÷ parameter dots (',args[&quot;dots&quot;],') is not a integer (',cols,')&lt;/span&gt;'})
 		end
 		
 		while(cols&gt;i) do
 			local xValue = ((100/cols*i)+(100/cols/10))*1.1
 			i=i+1
 			while(tonumber(args[&quot;dots&quot;])&gt;j) do
 				j=j+1
 				table.insert(xTable,xValue)
 				xCount = xCount + 1
 			end
 			j=0
 		end
 	else                                                                        -- Divides args into the yTable and the xTable
 		for k,v in pairs(args) do                                               
 			if string.match(k,&quot;%d+&quot;) 
 			and not string.match(k,&quot;color%-&quot;) then
 				if isx == false then
 					table.insert(yTable,v)
 					yCount = yCount + 1
 					isx = true
 				elseif not args[&quot;dots&quot;] then
 					table.insert(xTable,v)
 					xCount = xCount + 1
 					isx = false
 				end
 			end
 		end
 	end
 	
 	if xCount &lt; yCount then                            
 		return table.concat({'&lt;span style=&quot;font-size:100%&quot; class=&quot;error&quot;&gt;The amount of x values (',xCount,') is less then the number y values (',yCount,')&lt;/span&gt;'})
 	elseif xCount &gt; yCount then
 		return table.concat({'&lt;span style=&quot;font-size:100%&quot; class=&quot;error&quot;&gt;The amount of x values (',xCount,') is more then the number y values (',yCount,')&lt;/span&gt;'})
 	end
 	
 	if args[&quot;color-even&quot;] then                                                  -- Creates the colorTable if color-even is set
 		colorTime = false
 		for k,v in pairs(yTable) do
 			if colorTime == true then
 				colorTable[k] = args[&quot;color-even&quot;]
 				colorTime = false
 			else
 				colorTime = true
 			end
 		end
 	end
 	
 	if args[&quot;color-odd&quot;] then                                                   -- Creates the colorTable if color-odd is set
 		colorTime = true
 		for k,v in pairs(yTable) do
 			if colorTime == true then
 				colorTable[k] = args[&quot;color-odd&quot;]
 				colorTime = false
 			else
 				colorTime = true
 			end
 		end
 	end
 	
 	for k,v in pairs(args) do                                                   -- Adds values to the colorTable if color-# is set
 		if k == mw.ustring.match(k,&quot;color%-%d+&quot;) then
 			num = mw.ustring.gsub(k,&quot;color%-&quot;,&quot;&quot;)
 			num = tonumber(num)
 			colorTable[num] = v
 		end
 	end
 	
 	for k,y in pairs(yTable) do                                                 -- Creates the dotTable
 		local InnerDiv = mw.html.create('div')
 		local div = mw.html.create('div')
 		local size; 
 		if args[&quot;size&quot;] then
 			size = tonumber(mw.ustring.match(args[&quot;size&quot;],&quot;(%d+)&quot;))
 		else
 			size = 8
 		end
 		x = xTable[k]
 		InnerDiv
 			:css('position','absolute')
 			:css('top',table.concat({'-',size/2,'px'}))
 			:css('left',table.concat({'-',size/2,'px'}))
 			:css('line-height','0')
 			:wikitext('[[File:Location dot ',colorTable[k] or 'red','.svg|',size,'x',size,'px]]')
 		div
 			:css('position','absolute')
 			:css('bottom',table.concat({y*0.85+15,'%'}))
 			:css('left',table.concat({x*0.85+15,'%'}))
 			:wikitext(tostring(InnerDiv))
 		table.insert(dotTable,tostring(div))
 	end
 	
 	for k,v in pairs(xLabels) do
 		local div = mw.html.create('div')
 		div
 			:css('position','absolute')
 			:css('bottom','0%')
 			:css('left',table.concat({((100/xLCount*k-100/xLCount)*0.85+15)-4,'%'}))
 			:wikitext(v)
 		table.insert(dotTable,tostring(div))
 	end
 	
 	for k,v in pairs(yLabels) do
 		local div = mw.html.create('div')
 		div
 			:css('position','absolute')
 			:css('bottom',table.concat({(((((100/yLCount*k-100/yLCount)-(100/yLCount/3))+5))+100/yLCount/2)*1.02,'%'}))
 			:css('left','0%')
 			:wikitext(v)
 		table.insert(dotTable,tostring(div))
 	end
 	
 	return table.concat(dotTable)
 end
 
 ---------- L E G E N D ---------------------------------------------------------
 ---------- Makes the legendTable -----------------------------------------------
 
 local function legend(args)
 	local color;
 	local aValue;
 	local Table = {}
 	for k,v in pairs(args) do                                                   -- Adds values to the table
 		if k == mw.ustring.match(k,&quot;legend%-%a+&quot;) then
 			color = mw.ustring.gsub(k,&quot;legend%-&quot;,&quot;&quot;)
 			v = table.concat({'&lt;div&gt;[[File:Location dot ',color or 'red','.svg|8x8px]] (',color,') = ',v,'&lt;/div&gt;'})
 			table.insert(Table,v)
 			aValue = true
 		end
 	end
 	if aValue == true then
 		return table.concat(Table)
 	else
 		return &quot;&quot;
 	end
 end
 
 --------------------------------------------------------------------------------
 ---------- P . G R A P H -------------------------------------------------------
 ---------- Returns all the dots in div tags-------------------------------------
 --------------------------------------------------------------------------------
 
 function p.graph(frame)         	                                        	-- Returns a graph with the dots on it
 	if mw.ustring.match(p.data(frame),&quot;&lt;span&quot;) then                             -- Return error messages from p.data
 		return p.data(frame) 
 	end   
 	local args = getArgs(frame)
 	local picture = &quot;Blank.png&quot;
 	local div = mw.html.create('div')
 	local center = mw.html.create('div')
 	local container = mw.html.create('div')
 	local top = mw.html.create('div')
 	local size; 
 	if args[&quot;size&quot;] then
 		size = tonumber(mw.ustring.match(args[&quot;size&quot;],&quot;(%d+)&quot;))
 	else
 		size = 8
 	end
 	
 	if args[&quot;width&quot;] then
 		if args[&quot;width&quot;] == mw.ustring.match(args[&quot;width&quot;],&quot;(%d+)&quot;) then
 			args[&quot;width&quot;] = table.concat({args[&quot;width&quot;],'px'})
 		end
 	end
 
 	if args[&quot;picture&quot;] then                                                     -- Set local picture
 		picture = args[&quot;picture&quot;]
 	elseif yesno(args[&quot;square&quot;]) == true then
 		picture = &quot;Transparent.png&quot;
 	end
 	
 	picture = mw.ustring.gsub(picture,'|.+','')
 	picture = mw.ustring.gsub(picture,'.-:','')
 	
 	if p.data(frame) == &quot;&quot; then                                                 -- Don't make box if empty
 		return &quot;&quot;
 	end
 	 
 	if args[&quot;top&quot;] then
 		top                                                                     -- Create top text
 			:css('font-weight','bold')
 			:css('text-decoration','underline')
 			:css('text-align','center')
 			:wikitext(args[&quot;top&quot;])
 	end
 	
 	container                                                                   -- Creates container
 		:css('width',args[&quot;width&quot;] or '240px')
 		:css('float','right')
 		:css('position','relative')
 		:wikitext('[[File:',picture,'|',args[&quot;width&quot;] or '240px',']]')
 		:wikitext(p.data(frame))
 	div                                                                         -- Creates box
 		:css('width',args[&quot;width&quot;] or '240px')
 		:css('display','inline-block')
 		:css('float',args[&quot;align&quot;] or 'right')
 		:css('margin',args[&quot;margin&quot;] or '2px')
 		:css('padding',args[&quot;padding&quot;] or table.concat({size/2,'px'}))
 		:css('background',args[&quot;color&quot;] or 'none')
 		:wikitext(tostring(top))
 		:wikitext(tostring(container))
 		:wikitext(legend(args))
 		:wikitext(args[&quot;bottom&quot;])
 		
 	if yesno(args['border']) ~= false then                                      -- Creates box border
 		div
 			:css('border-style','solid')
 			:css('border-color','black')
 			:css('border-width','3px')
 	end
 		
 	if args['align'] == 'center' then                                           -- Centers output if needed
 		center
 			:addClass('center')
 			:css('width','auto')
 			:css('margin-left','auto')
 			:css('margin-right','auto')
 			:wikitext(tostring(div))
 		return center                                                   
 	else
 		return div
 	end
 end