跳至內容

模組:AbC Pie

維基百科,自由的百科全書
require('strict')

local getArgs = require("Module:Arguments").getArgs
local yesno = require("Module:Yesno")
local p = {}

local function list(args)
    local _args = {}
	
    local args = args
    if type(args) == 'nil' then
        args = {}
    elseif type(args) == 'string' then
        args = { args }
    end

    for _, v in ipairs(args) do
        table.insert(_args, v)
    end
	
    return '[ ' .. table.concat(_args, ', ') .. ' ]'
end

local function dict(args)
    local _args = {}
	
    local args = args
    if type(args) == 'nil' then
        args = {}
    elseif type(args) == 'string' then
        args = { args }
    end

    for i, v in pairs(args) do
        table.insert(_args, string.format('"%s" : %s', i, v))
    end
	
    return '{ ' .. table.concat(_args, ', ') .. ' }'
end

local function str(args)
    return '"' .. (args or '') .. '"'
end

local function get_page_count_by_category(category_name)
    return mw.getCurrentFrame():callParserFunction {
        name = 'PAGESINCATEGORY',
        args = { category_name, 'pages', 'R' }
    }
end

local function get_data_by_importance(args)
    
    -- importance information
        
    local default_importances = {'top', 'high', 'mid', 'low', 'unknown'}

    local importance_list = {
        ['top'] = { ['name'] = { ['hans'] = '极高重要度', ['hant'] = '極高重要度' }, ['color'] = '#FF97FF' },
        ['high'] = { ['name'] = { ['hans'] = '高重要度', ['hant'] = '高重要度' }, ['color'] = '#FFACFF' },
        ['mid'] = { ['name'] = { ['hans'] = '中重要度', ['hant'] = '中重要度' }, ['color'] = '#FFC1FF' },
        ['low'] = { ['name'] = { ['hans'] = '低重要度', ['hant'] = '低重要度' }, ['color'] = '#FFD6FF' },
        ['bottom'] = { ['name'] = { ['hans'] = '极低重要度', ['hant'] = '極低重要度' }, ['color'] = '#FFEBFF' },
        ['no'] = { ['name'] = { ['hans'] = '无重要度', ['hant'] = '無重要度' }, ['color'] = '#FFFFFF' },
        ['na'] = { ['name'] = { ['hans'] = '不适用重要度', ['hant'] = '不適用重要度' }, ['color'] = '#F5F5F5' },
        ['unknown'] = { ['name'] = { ['hans'] = '未知重要度', ['hant'] = '未知重要度' }, ['color'] = '#BEBEBE' },
    }
    
    if args.customimportance then
        local custom_importances = mw.text.split(args.customimportance:gsub('%s', ''), ';')
        for _, v in ipairs(custom_importances) do
            local tab = mw.text.split(v:lower():gsub('%s', ''), ':'), "", "", ""
            importance_list[tab[1]] = {
                ['name'] = { ['hans'] = tab[2], ['hant'] = tab[3] },
                ['color'] = tab[4]
            }
        end
    end
    

    local ret = {}
    
    local topic = args.topic or ''
    
    local importances = {}
    if args.importance then
        importances = mw.text.split(args.importance:lower():gsub('%s', ''), ',')
    else
        importances = default_importances
    end
    
    local counts = {}
    if args.count then
        counts = mw.text.split(args.count:gsub('%s', ''), ',')
    end

    for i, v in ipairs(importances) do
        local info = importance_list[v]
        local count, cat
        if #counts == 0 then
            cat = info.name.hans .. topic .. '条目'
            count = get_page_count_by_category(cat)
        else
            count = counts[i] or '0'
        end
        if yesno(args.hidezero) and count == '0' then
            -- pass
        else
            table.insert(ret, {
                ['name'] = info.name,
                ['color'] = info.color,
                ['count'] = count,
            })
        end
    end

    return ret
end

local function build_graph(title, height, width, pie_radius, data, variant)
    local temp_tab = {}

    -- graph
    local graph = {
        ['version'] = 2,
        ['axes'] = list(),
        ['height'] = height or '300',
        ['width'] = width or '300',
        ['padding'] = str('padding'),
    }

    -- graph['legends']
    graph['legends'] = list(dict{
        ['fill'] = str('color'),
        ['offset'] = '20',
        ['properties'] = dict(),
        ['title'] = str(title or ''),
    })

    -- graph['marks']
    graph['marks'] = list(dict{
        ['type'] = str('arc'),
        ['from'] = dict{
            ['data'] = str('table'),
            ['transform'] = list(dict{
                ['type'] = str('pie'),
                ['field'] = str('val'),
            }),
        },
        ['properties'] = dict{
            ['enter'] = dict{
                ['x'] = dict{
                    ['field'] = dict{ ['group'] = str('width'), },
                    ['mult'] = '0.5',
                },
                ['y'] = dict{
                    ['field'] = dict{ ['group'] = str('width'), },
                    ['mult'] = '0.5',
                },
                ['startAngle'] = dict{ ['field'] = str('layout_start'), },
                ['endAngle'] = dict{ ['field'] = str('layout_end'), },
                ['fill'] = dict{
                    ['field'] = str('idx'),
                    ['scale'] = str('color'),
                },
                ['innerRadius'] = dict{ ['value'] = '0', },
                ['outerRadius'] = dict{ ['value'] = pie_radius or '125', },
            },
        },
    })

    -- graph['data']
	local variant = (variant ~= 'hant' and 'hans' or 'hant')
    for _, v in ipairs(data) do
        table.insert(temp_tab, dict{
            ['col'] = str('data'),
            ['idx'] = str(v.name[variant] .. ':' .. mw.language.new('en'):formatNum(tonumber(v.count))),
            ['val'] = v.count,
        })
    end
    graph['data'] = list(dict{
        ['name'] = str('table'),
        ['values'] = list(temp_tab),
    })
    temp_tab = {}

    -- graph['scales']
    for _, v in ipairs(data) do
        table.insert(temp_tab, str(v.color))
    end
    graph['scales'] = list(dict{
        ['domain'] = dict{
            ['data'] = str('table'),
            ['field'] = str('idx'),
        },
        ['name'] = str('color'),
        ['type'] = str('ordinal'),
        ['range'] = list(temp_tab),
    })
    temp_tab = {}

    return mw.getCurrentFrame():extensionTag {
        ['name'] = 'graph',
        ['content'] = dict(graph),
    }
end

function p.main(frame)
    local args = getArgs(frame)
    return p._main(args)
end

function p._main(args)
    local hans_title = (args['topic-hans'] or args['topic'] .. '专题') .. '条目重要度统计'
    local hant_title = (args['topic-hant'] or args['topic'] .. '專題') .. '條目重要度統計'

    local height, width, radius = args.height, args.width, args.radius
    local data = get_data_by_importance(args)

    return require( 'Module:WikitextLC' ).selective { 
        ['zh-hans'] = build_graph(hans_title, height, width, radius, data, 'hans'),
        ['zh-hant'] = build_graph(hant_title, height, width, radius, data, 'hant'),
    }
end

return p