跳转到内容
打开/关闭菜单
  • 173 条目
  • 16 文件
  • 3 用户
  • 2838 编辑
Novark
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
Phase1EmergencyAdmin​(留言 | 贡献)2026年10月23日 (五) 14:41的版本 (统一议会席位数据、半环图与作者模板参数)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

此模块的文档可以在模块:议会/doc创建

local p = {}

function p.render(frame)
    local args = frame:getParent().args
    local groups, total = {}, 0
    for line in mw.text.gsplit(args['席位'] or '', '\n') do
        line = mw.text.trim(line)
        if line ~= '' then
            local name, count = line:match('^(.-)%s*=%s*(%d+)%s*$')
            if not name or mw.text.trim(name) == '' then
                return '<strong class="error">议会席位:每行请填写“名称=席数”。</strong>'
            end
            count = tonumber(count)
            groups[#groups + 1] = { name = mw.text.trim(name), count = count }
            total = total + count
        end
    end
    if total == 0 then return '<strong class="error">议会席位:请填写席位数据。</strong>' end
    local capacity = tonumber(args['总席位']) or total
    if capacity ~= total then
        return '<strong class="error">议会席位:分组合计' .. total .. '席,与总席位' .. capacity .. '席不一致。</strong>'
    end

    local root = mw.html.create('div'):addClass('nv-parliament')
    root:tag('div'):addClass('nv-parliament__title'):wikitext(args['名称'] or '议会席位')
    root:tag('p'):addClass('nv-parliament__session'):wikitext((args['届次'] or '') .. ' · 共' .. total .. '席')
    local chamber = root:tag('div'):addClass('nv-parliament__chamber'):attr('aria-hidden', 'true')
    local positions, allocated = {}, 0
    local radii = { 46, 39, 32, 25, 18 }
    for ring, radius in ipairs(radii) do
        local count = ring == #radii and total - allocated or math.floor(total * radius / 160 + 0.5)
        allocated = allocated + count
        for seat = 1, count do
            local angle = count == 1 and math.pi / 2 or (seat - 1) * math.pi / (count - 1)
            positions[#positions + 1] = { angle = angle, radius = radius }
        end
    end
    table.sort(positions, function(a, b)
        if a.angle == b.angle then return a.radius > b.radius end
        return a.angle > b.angle
    end)
    local seat = 1
    for index, group in ipairs(groups) do
        local class = 'nv-parliament__party--' .. ((index - 1) % 12 + 1)
        group.class = class
        for _ = 1, group.count do
            local point = positions[seat]
            local x = 50 + math.cos(point.angle) * point.radius
            local y = 98 - math.sin(point.angle) * point.radius * 2
            chamber:tag('span'):addClass('nv-parliament__seat'):addClass(class)
                :css('left', string.format('%.3f%%', x)):css('top', string.format('%.3f%%', y))
            seat = seat + 1
        end
    end
    local legend = root:tag('table'):addClass('wikitable'):addClass('nv-parliament__legend')
    legend:tag('caption'):wikitext('席位构成')
    local header = legend:tag('tr')
    header:tag('th'):attr('scope', 'col'):wikitext('组别')
    header:tag('th'):attr('scope', 'col'):wikitext('席位')
    header:tag('th'):attr('scope', 'col'):wikitext('占比')
    for _, group in ipairs(groups) do
        local row = legend:tag('tr')
        local label = row:tag('th'):attr('scope', 'row')
        label:tag('span'):addClass('nv-parliament__key'):addClass(group.class):attr('aria-hidden', 'true')
        label:wikitext(mw.text.nowiki(group.name))
        row:tag('td'):wikitext(tostring(group.count))
        row:tag('td'):wikitext(string.format('%.1f%%', group.count / total * 100))
    end
    root:tag('p'):addClass('nv-parliament__note'):wikitext('按表中顺序排布,不表示政治光谱。')
    return tostring(root)
end

return p