Module:Setlist2
local p = {}
local function svg_arc(cx, cy, r, start_angle, end_angle, color, href)
local function polarToCartesian(cx, cy, r, angle)
local angle_rad = math.rad(angle - 90)
return cx + r * math.cos(angle_rad), cy + r * math.sin(angle_rad)
end
local x1, y1 = polarToCartesian(cx, cy, r, start_angle)
local x2, y2 = polarToCartesian(cx, cy, r, end_angle)
local largeArcFlag = ((end_angle - start_angle) % 360) > 180 and 1 or 0
local path = string.format(
"M %.2f %.2f A %.2f %.2f 0 %d 1 %.2f %.2f L %.2f %.2f Z",
x1, y1, r, r, largeArcFlag, x2, y2, cx, cy
)
return string.format(
'<a xlink:href="/wiki/%s"><path d="%s" fill="%s" stroke="#fff" stroke-width="0.5"/></a>',
href, path, color
)
end
local data = mw.loadData('Module:Setlist/Songs')
function p.fromArgs(frame)
local args = frame:getParent().args
local complete = (args['complete'] or "yes"):lower() == "yes"
local list = {}
for i = 1, 50 do
local song = args['song'..i]
if song and song ~= then
local label = args['label'..i] or ""
table.insert(list, { title = mw.text.trim(song), label = label })
end
end
-- Группируем песни по альбомам
local albumSongs = {}
local albumOrder = {}
for idx, songobj in ipairs(list) do
local title = songobj.title
local label = songobj.label
local albums = data.songs[title]
if albums then
for _, album in ipairs(albums) do
if not albumSongs[album] then
albumSongs[album] = {}
table.insert(albumOrder, album)
end
table.insert(albumSongs[album], {title = title, label = label, num = idx})
end
else
if not albumSongs["?"] then
albumSongs["?"] = {}
table.insert(albumOrder, "?")
end
table.insert(albumSongs["?"], {title = title, label = label, num = idx})
end
end
-- 1. Основной сетлист
local wikitext = '{| class="setlist-table setlist-anim" style="margin-top:1.6em;"\n|-\n| style="padding:0.7em 1.2em;" |\n'
for idx, songobj in ipairs(list) do
local numtxt = complete and (idx..".") or "*"
local label = (songobj.label and songobj.label ~= ) and (''..songobj.label..'') or
wikitext = wikitext .. '
'..numtxt..' '..songobj.title..''..label..'
\n'
end
-- 2. SVG круговая диаграмма (кликабельная)
local total = 0
for _, album in ipairs(albumOrder) do
total = total + #albumSongs[album]
end
local svg = {'<svg width="50" height="50" viewBox="0 0 50 50" style="vertical-align:middle;">'}
local angle = 0
for _, album in ipairs(albumOrder) do
local count = #albumSongs[album]
local percent = count / total * 100
local sweep = percent * 3.6
local color = data.albumColors[album] or "#ccc"
local href = (data.albumLinks[album] or album):gsub(" ", "_")
table.insert(svg, svg_arc(25,25,25,angle,angle+sweep,color,href))
angle = angle + sweep
end
table.insert(svg, '</svg>')
wikitext = wikitext .. table.concat(svg, '\n')
-- 3. Блоки по альбомам
for albumIdx, album in ipairs(albumOrder) do
local arr = albumSongs[album]
local color = data.albumColors and data.albumColors[album] or "#eee"
local link = data.albumLinks and data.albumLinks[album] or album
local uniqid = "myDivision"..albumIdx
wikitext = wikitext .. '\n{| class="wikitable" style="margin-top:1em; border-collapse:separate; border-spacing:4px; border:hidden;"'
wikitext = wikitext .. '\n| style="background:'..color..'; border:hidden;" |'
wikitext = wikitext .. '\n| style="border:hidden;" | '..album..''
wikitext = wikitext .. '\n| style="border:hidden;" | ('..tostring(#arr)..')'
wikitext = wikitext .. '\n| style="border:hidden;" |\n
'
for _, entry in ipairs(arr) do
wikitext = wikitext .. '○'..entry.title..'\n'
end
wikitext = wikitext .. '\n|}\n'
end
wikitext = wikitext .. '|}' return wikitext
end
return p