文档图示 模块文档

Module:Bar可以為棒形圖產生有色的棒形,應用於較頂層的模板中。

用法

數據系

在調用該模塊時,須提供一系列數值。

系列由多組 == 組成,每組有2﹣3個參數:數值、顏色以及可選填的提示信息。

例如:

{{#invoke:bar|format|4,green,完成|2,gray,進行中|4,#FCC,未完成}}

總數

可以指定棒形中有多少個數值。如果指定的數量比實際提供的數量多,模塊就會在末端加入相應的空白。例如:

{{#invoke:bar|format|7,green,完成|total=10}}{{pb}}{{#invoke:bar|format|4,green,完成|total=10}}{{pb}}{{#invoke:bar|format|2,green,完成|total=10}}

寬度

默認寬度設為100%,但可換做任何CSS寬度值。例如:

{{#invoke:bar|format|7,green,完成|width=5em}}{{pb}}{{#invoke:bar|format|7,green,完成|width=15em}}

CSS

可用CSS改變棒形外觀。例如:

{{#invoke:bar|format|7,green,完成|total=10|width=30em|barCSS=border:1px solid #CCC}}

例子

完成度

{| role="presentation"|{{#invoke:bar|format|7,green,完成|total=10|width=30em|barCSS=border:1px solid #CCC;}}|{{#expr:7 / 10 * 100}}%|}
70%

層疊棒形圖

{| class="wikitable"|+ 支出與收入|-| 2011年| {{#invoke:bar|format|100,red,支出|50,green,收入|total=170|width=30em}}|-| 2012年| {{#invoke:bar|format|75,red,支出|90,green,收入|total=170|width=30em}}|}
支出與收入
2011年
2012年

分組棒形圖

{| class="wikitable"|+ 支出與收入|-| 2011| {{#invoke:bar|format|150,green,收入|total=160|width=15em}}{{#invoke:bar|format|100,red,支出|total=160|width=15em}}|-| 2012| {{#invoke:bar|format|160,green,收入|total=160|width=15em}}{{#invoke:bar|format|75,red,支出|total=160|width=15em}}|}
支出與收入
2011
2012

local p = {}local inner = {}--##########--## Public functions--##########--- Render a bar chart.-- @param frame The arguments passed to the script. See docs on renderFromLua.function p.format( frame )    -- extract args    local width = frame.args['width']    local barCSS = frame.args['barCSS']    local zeroWidth = frame.args['zeroWidth']    local total = frame.args['total']        -- extract bar series from arguments like 'value,color,title'    local series = {}    for key, spec in ipairs(frame.args) do        spec = mw.text.split(spec, ',')        local data = {value = tonumber(spec[1] or 0), color = spec[2] or '#CCC', title = spec[3] or ''}        if data['value'] > 0 then            table.insert(series, data)        end    end        return p.renderFromLua(series, total, width, barCSS, zeroWidth)end--- Render a bar chart from Lua.-- @param series A table representing the bars to render, consisting of a sequence of tables like {value = 14, color = '#CCC', title = 'tooltip text'}.-- @param total (optional) The total number of values represented by all bar series.-- @param width (optional) The CSS width of the bar.-- @param barCss (optional) Additional CSS to apply to the rendered bar table.-- @param zeroWidth (optional) function p.renderFromLua(series, total, width, barCSS, zeroWidth)    -- parse arguments    width = width or '100%'    total = tonumber(total or 0)    zeroWidth = zeroWidth or '1px'        -- calculate total    local seriesTotal = 0    for k,v in ipairs(series) do       seriesTotal = seriesTotal + v['value']    end    if total < seriesTotal then       total = seriesTotal    end        -- inject empty series for uncharted values    if(seriesTotal < total) then        table.insert(series, {value = total - seriesTotal, color = 'transparent', title = ''})    end        -- inject ratios    for k,v in ipairs(series) do       v['total'] = total       v['ratio'] = inner.getRatio(v['value'], total)       if v['ratio'] == 0 then           v['width'] = zeroWidth      end    end        -- render    result = mw.html.create 'table'    :attr('role', 'presentation')    :css('width', width)    :cssText(barCSS)    :css('border-spacing', '0')    :tag 'tr'    for k, v in pairs(series) do        result:node(inner.renderSeries(v))    end    return result:allDone()end--##########--## Private functions--##########--- Render an individual bar series.-- @param series The bar series to render.function inner.renderSeries(series)    -- ignore empty series    if not series.value or series.value == 0 then        return ''    end        -- set width    local width = series.width    if not(width) then        width = series.ratio .. '%'    end        -- format    return mw.html.create 'td'    :attr('title', series.title)    :css('width', width)    :css('background', series.color)    :attr('data-value', series.value)    :css('height', '1em')    :css('padding', '0')end--- Get the percentage ratio of two numbers as a decimal value.-- @param value The number of items in the subset.-- @param total The total number of items in the set.function inner.getRatio(value, total)    if(total == 0) then       error('the total for a series cannot be zero')    end    return math.floor(value / total * 10000) / 100endreturn p