Module:Plotter

local p=

function pick(a,n)

return an+1

end

function loadColorSet(page)

if not(page) then page="" end

if mw.ustring.sub(page,1,7) ~= "Module:" then page="Module:Plotter/DefaultColors" end

local ct=mw.loadData(page)

if not ct then ct=mw.loadData("Module:Plotter/DefaultColors") end

local x=0

local color=

local name=

repeat

x=x+1

local n=ctx*2-1

local c=ctx*2

if not (n and c) then break end

table.insert(color,c)

table.insert(name,n)

until false

return color, name

end

function piechartslice(color,percent,radius,link)

radius=radius or 100

local quadrant=math.floor(percent/25)

local sin=math.floor(radiusmath.sin(percentmath.pi/50))

local cos=math.floor(radiusmath.cos(percentmath.pi/50))

local tan25=math.floor(-1radiusmath.cos(percentmath.pi/50)/math.sin(percentmath.pi/50))

local output,lr,lrv,tv,bw1,bw2,bw3,bw4,bd,lrB,bw2B

local a= -- throwaway array to make value matrix more apparent

-- quadrant 1 is upper left, quadrant 2 is lower left

lr=pick({'left','right','right','left','left'},quadrant)

lrv=pick({radius,radius,radius,radius,0},quadrant)

tv=pick({radius-sin,0,radius,radius,0},quadrant)

-- border width:bw1 (top) bw2 (right) bw3 (bottom) bw4 (left)

bw1=pick({0,0,-1*sin,radius,0},quadrant)

bw2=pick({0,tan25,-1cos,0,2radius},quadrant)

bw3=pick({sin,radius,0,0,2*radius},quadrant)

bw4=pick({cos,0,0,tan25,0},quadrant)

bd=pick({'bottom-','right-','top-','left-',},quadrant)

lrB=pick({'n/a','right','left','left','n/a'},quadrant)

-- right border for second div (the bottom border is radius and others are zero)

bw2B=pick({'n/a',radius,2radius,2radius,'n/a'},quadrant)

local output=

if quadrant==1 or quadrant==2 or quadrant==3 then

output=output..

if quadrant==3 then

output=output..

end

end

return output

end

function p.piechart(frame)

local parent=frame.getParent(frame) or

local color=loadColorSet(frame.args.colorset or parent.args.colorset) or {'red','green','blue','yellow','fuchsia','aqua','brown','orange','purple','sienna'}

local value=

local label=

local link=

local slicecount=0

local thumb,nowiki,radius

if parent.args then

thumb=parent.args.thumb

nowik=parent.args.nowiki

radius=parent.args.radius

end

thumb=frame.args.thumb or thumb

nowiki=frame.args.nowiki or nowiki

radius=frame.args.radius or radius or 100

radius=tonumber(radius)

if radiusslicecount then slicecount=k end -- not using #value to avoid randomness if some values are left out

else k=tonumber(mw.ustring.match(i,"label(%d*)"))

if k then labelk=j

end

end

end

end

--- innermost absolute div around circle, then a second thumbcaption div around legend. Note (/div)(div) at core between circle and legend. The rest are accreted around this center.

output=' '

for i,j in pairs(frame.args or ) do -- supersede parent.args values

local k=tonumber(mw.ustring.match(i,"color(%d*)"))

if k then colork=j or ""

else k=tonumber(mw.ustring.match(i,"value(%d*)"))

if k then

valuek=tonumber(j)

if k>slicecount then slicecount=k end -- not using #value to avoid randomness if some values are left out

else k=tonumber(mw.ustring.match(i,"label(%d*)"))

if k then labelk=j or ""

else k=tonumber(mw.ustring.match(i,"link(%d*)"))

if k then linkk=j or ""

end

end

end

end

end

local valuesum=0 -- sum of all slices

local imgmap="" -- beginning of a polygon specification for

for slice=1,slicecount do

if valueslice then

if linkslice then

-- center of the circle, NOTE coords are relative to 600 px image before scaling NOT the radius

imgmap=imgmap.."poly 300 300"

for x=valuesum,valuesum+valueslice do

local sin=math.floor(300math.sin(xmath.pi/50))

local cos=math.floor(300math.cos(xmath.pi/50))

imgmap=imgmap.." "..300+cos.." "..300-sin

end

imgmap=imgmap.." "..linkslice.."\n"

end

valuesum=valuesum+valueslice

output=piechartslice(colorslice,valuesum,radius)..output..""

end

end

--- imagemap has its own absolute div to position with a separate transparent image

imgmap='\n\nFile:transparent600.gif|'..2*radius..'px\n'..imgmap..'desc none\n'

if #link==0 then imgmap="" end -- make sure imgmap is blank if no links

--- outer thumb tleft/tright is float/clear left or right

--- thumbinner encapsulates the graph

--- third relative div container ends in the middle of ..output..

--- next third div style "thumbcaption" begins in ..output..

--- all three end at end

output=' '..output..

output=mw.ustring.gsub(output,"", imgmap)

if nowiki then return frame.preprocess(frame,"") else return frame.preprocess(frame,output) end

end

function p.main(frame)

local args=frame.args

local parent=frame.getParent(frame)

local pargs=parent.args or

local icon=args.icon or pargs.icon

local iconradius=args.iconradius or pargs.iconradius or 10

local lineicon=args.lineicon or pargs.lineicon or "•"

local lineiconradius=args.lineiconradius or pargs.lineiconradius or 5

local linefix=iconradius-lineiconradius

local plotsizex = args.plotsizex or pargs.plotsizex or 100

local plotsizey = args.plotsizey or pargs.plotsizey or 100

local plotstep = args.plotstep or pargs.plotstep or 10

local output =

if (args2 or pargs2) ~= nil then

local x=(args1 or pargs1)+0

local y=(args2 or pargs2)+0

local xmin = x

local xmax = x

local ymin = y

local ymax = y

local index = 3

while (argsindex+1 or pargsindex+1) ~= nil do

local x=(argsindex+0 or pargsindex+0)

local y=(argsindex+1+0 or pargsindex+1+0)

if (x xmax) then xmax = x end

if (y ymax) then ymax = y end

index = index + 2

end

local lastx=0

local lasty=0

if args2 ~= nil then

local x=(args1 or pargs1)+0

local y=(args2 or pargs2)+0

local plotx=math.floor(plotsizex*(x-xmin)/(xmax-xmin))

local ploty=math.floor((plotsizey-plotsizey*(y-ymin)/(ymax-ymin)))

output = output .. .. icon .. ""

lastx = plotx

lasty = ploty

end

index = 3

while (argsindex+1 or pargsindex+1) ~= nil do

local x=(argsindex or pargsindex)+0

local y=(argsindex+1 or pargsindex+1)+0

local plotx=math.floor(plotsizex*(x-xmin)/(xmax-xmin))

local ploty=math.floor((plotsizey-plotsizey*(y-ymin)/(ymax-ymin)))

if plotstep+0 ~= 0 then

local delx=plotx-lastx

local dely=ploty-lasty

plotdist=math.sqrt(delxdelx+delydely)

plotparm=plotdist-iconradius-plotstep/2

while plotparm>iconradius+lineiconradius+plotstep/2 do

output = output .. .. lineicon .. ""

plotparm = plotparm - plotstep

end

lastx = plotx

lasty = ploty

end

output = output .. .. icon .. ""

index = index + 2

end

else output = "error"

end

output = output .. ""

return output

end

-- data structure is

-- datayx.value

-- maxyvaly

-- datay.color

-- datay.legend

-- data.legendx

function p.bar(frame)

local debuglog=""

local args=frame.args

local parent=frame.getParent(frame)

local pargs=parent.args or

local delimiter = args.delimiter or pargs.delimiter or ","

local width = args.width or pargs.width or 200

local height = args.height or pargs.height or 200

---- Set up the table of "norms". Series 1 to N normalize to (%d+)

local normalize = args.normalize or pargs.normalize or ""

local prowl=mw.ustring.gmatch(normalize,"(%d+)")

norm=

local ngroup= -- ngroupyseries identifies an index for ymax

local nngroup=0 -- the current maximum ngroup assigned

repeat

local t=prowl

if not(t) then break end

t=tonumber(t)

table.insert(norm,t)

until false

--- import the actual data in group1 .. groupN

local yseries=0;local x=0

local data= -- main data storage array

local maxy=0;local maxx=0; local maxyval=; local minyval= -- keeping these out of the data array after being driven half mad giving them cutesy names in the array!

repeat

yseries=yseries+1

datayseries=

--- pull in the "groupN" data (delimited) --> text

local text=args"group"..yseries -- each group is a group of x-values in a y-series

if not (text) then maxy=yseries-1 break end

---- pull in the originN=some number

datayseries.origin=args"origin"..yseries or 0

datayseries.origin=tonumber(datayseries.origin)

datayseries.max=datayseries.origin;datayseries.min=datayseries.origin

debuglog=debuglog.."I"..yseries..tostring(normyseries)

--- set ngroupyseries to whatever its norm points at, or new

if normyseries

then if ngroupnormyseries

then ngroupyseries=ngroupnormyseries

else nngroup=nngroup+1

ngroupyseries=nngroup

end

else ngroupyseries=1 -- if no norm specified, just dump to the first series group

end

---- pull in the actual values

prowl=mw.ustring.gmatch(text,"(^" .. delimiter .. "+)")

x=0

repeat

x=x+1

datayseriesx=

datayseriesx.value=prowl

debuglog=debuglog.."V"..x..yseries..tostring(datayseriesx.value)

if not(datayseriesx.value) then if x>maxx then maxx = x-1 end; break end

datayseriesx.value=tonumber(datayseriesx.value)

if datayseries.max then if datayseriesx.value>datayseries.max then datayseries.max=datayseriesx.value end else datayseries.max=datayseriesx.value end

if datayseries.min then if datayseriesx.value"..tostring(datayseries.max)

if maxyvalngroupyseries

then if datayseries.max>maxyvalngroupyseries

then maxyvalngroupyseries=datayseries.max

end

else maxyvalngroupyseries=datayseries.max;debuglog=debuglog.."A"..tostring(datayseries.max)..tostring(datayseries.min)

end

if minyvalngroupyseries

then if datayseries.min

local output=

local topreserve=20*(maxy)

local bottomreserve=20

local leftreserve=20

local rightreserve=20

local reducedheight=height-topreserve-bottomreserve

local reducedwidth=width-leftreserve-rightreserve

local ew=math.floor(reducedwidth/((maxx)*(maxy+1)))

for y = 1,maxy do

for x = 1, maxx do

debuglog=debuglog..y..x..tostring(ngroupy)..tostring(datayx) .. tostring(maxyvalngroupy)..tostring(minyvalngroupy)

if datayx and maxyvalngroupy

then local pw=(datayx.value-datay.origin)/(maxyvalngroupy-minyvalngroupy) -- proportion of value to the max value for that y-series

local po=(datay.origin-minyvalngroupy)/(maxyvalngroupy-minyvalngroupy)

local eh=math.floor(pw*reducedheight)

local et=topreserve+math.floor(reducedheight - eh - po*reducedheight)

if eh'

end -- if datayx and maxvalngroupy

end -- for x = 1, maxx

end -- for y=1,maxy

---- draw the ylegends

for x = 1,maxx do

output=output .. ..data.legendx..

end

for y = 1,maxy do

output=output .. .. (datay.legend or "") ..

local point={minyvalngroupy,datay.origin,maxyvalngroupy}

for i,j in ipairs(point) do

local po=(j-minyvalngroupy)/(maxyvalngroupy-minyvalngroupy)

local et=topreserve+math.floor((1-po)*reducedheight)

debuglog=debuglog.."pass" .. y .. ngroupy

if tonumber(ngroupy)==1

then debuglog=debuglog.."left";output=output .. .. j ..

else debuglog=debuglog.."right";output=output .. .. j ..

end

end

end

debuglog=debuglog..tostring(maxyval1)..tostring(maxyval2)..tostring(maxyval3)..tostring(data1.max)..tostring(data2.max)..tostring(data3.max)..tostring(minyval1)..tostring(minyval2)..tostring(minyval3)..tostring(data1.min)..tostring(data2.min)..tostring(data3.min)..data.legend1..data.legend2..data.legend3

output = output .. "\n"

if (args.debug or pargs.debug) then output=output..debuglog end

return output

end

return p