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%%">&nbsp;%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">&nbsp;<\/div>', color, math.ceil(value/maxvalue *100))
end

return p