Benutzer:Lövberg/Spielwiese/Modul:DiagrammEinwohnerentwicklung

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen
p = {}

function p._bargraph(data1, data2)
    data = {data1, data2}
    
    -- Daten überprüfen und zusammenstellen
    bardata = {}
    
    is_stacked = false
    is_first_series = true

    years = {}

    for _, series in ipairs(data) do
        entries = mw.text.split(series, '/')
        for _, entry in ipairs(entries) do
            entrydata =  mw.text.split(entry , '=')
            if #entrydata == 2 then
                year = entrydata[1]
                value = tonumber(entrydata[2])
                if #entrydata == 2 and tonumber(year) ~= nil and value ~= nil then
                    is_new_year = true
                    if is_first_series then
                        bardata[year] = {value, -1}
                    else
                        is_stacked = true
                        barentry = bardata[year]
                        if barentry then
                            bardata[year][2] = value
                            is_new_year = false
                        else
                            bardata[year] = {-1, value}
                        end
                    end
                    if is_new_year then
                         years[#years + 1] = year
                    end
                else
                    -- TODO: error
                end
            else
                -- TODO: error
            end
        end
        is_first_series = false
    end

    table.sort(years)
    
    graphdef = {'Colors=',
                '  id:minor value:gray(0.9)',
                '  id:major value:gray(0.7)',
                '  id:bar value:rgb(0.6,0.7,0.8)',
                '%s',
                'ImageSize  = width:%d height:250',
                'PlotArea = left:50 bottom:30 top:30 right:30',
                'TimeAxis = orientation:vertical',
                'AlignBars = justify',
                'Period = from:0 till:%d',
                'ScaleMajor = gridcolor:major start:0 increment:%d',
                'ScaleMinor = gridcolor:minor start:0 increment:%d'}

    max_value = 0
    barcount = 0

    for _, year in ipairs(years) do
        values = bardata[year]

        prev_value = 0
        sum = 0
       
        is_first_value = true
        textPos = values[2] > 0 and -12 or 3
        
        for _, value in ipairs(values) do
            if value > 0 then
                if is_first_value then
                     barcount = barcount + 1

                    graphdef[#graphdef + 1] = 'BarData='
                    graphdef[#graphdef + 1] = mw.ustring.format('  bar:%d text:%d', year, year)
                end

                sum = sum + value
                
                graphdef[#graphdef + 1] = 'PlotData='
                graphdef[#graphdef + 1] = mw.ustring.format('  color:%s width:30 align:center', is_first_value and 'bar' or 'bar2')
                graphdef[#graphdef + 1] = mw.ustring.format('  bar:%d from:%d till:%d', year, prev_value, sum)
                graphdef[#graphdef + 1] = mw.ustring.format('  bar:%d at:%d text:%d shift:(1,%d)', year, sum, value, textPos)
                if not is_first_value then
                    graphdef[#graphdef + 1] = mw.ustring.format('  bar:%d at:%d text:%d shift:(1,3)', year, sum, sum)
                end
                
                prev_value = value
            end
            is_first_value = false
        end
        max_value = math.max(max_value, sum)
    end

    -- Keine (gültigen) Daten
    if barcount == 0 then
        return nil
    end

    scale = {200000, 50000}
    if max_value <= 100 then
       scale = {10, 5}
    elseif max_value <= 200 then
       scale = {20, 5}
    elseif max_value <= 500 then
       scale = {50, 10}
    elseif max_value <= 1000 then
       scale = {100, 25}
    elseif max_value <= 2000 then
       scale = {200, 50}
    elseif max_value <= 5000 then
       scale = {500, 100}
    elseif max_value <= 10000 then
       scale = {1000, 250}
    elseif max_value <= 20000 then
       scale = {2000, 500}
    elseif max_value <= 50000 then
       scale = {5000, 1000}
    elseif max_value <= 100000 then
       scale = {10000, 2500}
    elseif max_value <= 200000 then
       scale = {20000, 5000}
    elseif max_value <= 1000000 then
       scale = {100000, 25000}
    end

    max_value = math.ceil(max_value * 1.1 / scale[1]) * scale[1]

    return mw.ustring.format(table.concat(graphdef, '\n'), is_stacked and '  id:bar2 value:rgb(0.7,0.8,0.9)' or '', barcount * 40 + 70, max_value, scale[1], scale[2])
end

function p.bargraph(frame)
    result = p._bargraph(frame.args[1], frame.args[2])
    if result ~= nil then
        return frame:extensionTag('timeline', result)
    else
        return '<span class="error>Keine Daten.</span>'
    end
end

return p