Documentation for this module may be created at Module:Sandbox/Wnt/Not lowercase/doc
-- this code came from User:Martijn Hoekstra; I'm curious how he handled the task.
-- (for my version see Module:Plotter|bar -- Wnt)
local p={}
local better={} -- functions to make or snarf to put in some library
function better.concat(sometable,ignore,delimiter,delimiter2,delimiter3,level) -- This one's mine - Wnt
local output=""
delimiter=delimiter or ",";delimiter2=delimiter2 or "{";delimiter3=delimiter3 or "}"
if not(ignore) then ignore={} end -- ignore specifies types not to report
if not(next(sometable)) then return "" end
local notfirst;local display
for i,j in pairs(sometable) do
if not(ignore[type(j)]) then
if notfirst then display=delimiter end
if type(j)=="table" then
local stopexpansion
if level then
if level<=0 then
stopexpansion=true
else nextlevel=level-1
end
end
if stopexpansion then
if not(ignore["table"]) then output=output..(display or "").."table" end
else output=output..(display or "") .. better.concat(j,ignore,delimiter,delimiter2,delimiter3,nextlevel)
end
else output=output..(display or "")..tostring(j)
end
notfirst=true
end
end
return delimiter2..output..delimiter3
end
function p.main()
local testdata = { {"blue", {1, 2, 3}}, {"red", {3, 4, 5}} }
return better.concat(testdata,nil,",","{","}",2)..bar_chart("1000px", "1000px", testdata, nil, nil)
end
function bar_chart(height, width, data, xlabels, ylabels)
local maxy = maxr(data)
local paired = {}
--where is a map function when you need one?
for k, s in pairs(data) do
for i, d in pairs(s[2]) do
if paired[k] == nil then paired[k] = {} end
paired[k][i] = {s[1], d}
end
end
--now looks like { {{"blue", 1}, {blue, 2}, {blue, 3}}, { {"red", 3}, {"red", 4}, {"red", 5} } }
-- ? so paired [yseries][x]={color,y} ?
local trans = transpose(paired)
local content = ""
for i, v in pairs(trans) do
content = content .. string.format('<div name="datapointContainer",style="display:inline-block;position:relative;height=100%%"> %s<\/div>',datapoint(v, "label", maxy))
end
return better.concat(paired)..string.format('<div name="chartContainer",style="height: %s;width: %s">%s<\/div>', height, width, content)
end
function transpose(matrix)
local trans = {}
for i, r in pairs(matrix) do -- ? for each yseries pull out the [x]{color,y} part
for j, v in pairs(r) do -- for each x, {color, y}
if trans[j] == nil then trans[j] = {} end
trans[j][i] = v -- now trans[x][yseries]={color,y}
end
end
return trans
end
--borks on circular reference: pass seen tables along to fix
function maxr(mytable)
local max = 0
for k,v in pairs(mytable) do
if type(v) == "number" then max = math.max(v, max)
elseif type(v) == "table" then max = math.max(maxr(v), max)
end
end
return max
end
--data: one datapoint of n datasets: data = { {color1, value1}, {color2, value2}, {color3, value3} }
function datapoint(data, label, maxy)
--fix with margins instead? My css fu is weak.
local result = '<div style="position:absolute;bottom:1.5em;height:90%">'
for k,v in pairs(data) do
result = result .. '\n' .. bar(v[2], maxy, v[1])
end
return result .. string.format('<\/div>\n<div style="position:absolute;bottom:0">%s<\/div>', label)
end
function bar(value, maxvalue, color)
return string.format('<div style="display:inline-block;background-color:%s;height:%.0f%%;vertical-align:bottom"> <\/div>', color, math.ceil(value/maxvalue *100))
end
return p