Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Documentation for this module may be created at Module:AlbumDonut/doc

local p = {}
local chart = require("Module:Chart")

-- Album label and link overrides
local labelOverrides = {
	["No4"] = "Nº4",
	["HT EP"] = "Hybrid Theory EP",
	["Tiny Music"] = "Tiny Music...Songs From The Vatican Gift Shop"
}
local linkOverrides = {
	["Other"] = nil,
	["No4"] = "No4",
	["HT EP"] = "Hybrid Theory EP",
	["Tiny Music"] = "Tiny Music...Songs From The Vatican Gift Shop"
}

-- Helpers
local function albumOf(frame, song)
	return frame:expandTemplate{ title = "AlbumList", args = { song } }
end
local function albumColor(frame, key)
	return frame:expandTemplate{ title = "AlbumColor", args = { key } }
end

-- Build one legend row (with collapsible song list)
local function legendRow(frame, albumKey, count, songs)
	local color = albumColor(frame, albumKey)
	local label = labelOverrides[albumKey] or albumKey
	local link = linkOverrides[albumKey] or albumKey
	local toggleId = mw.ustring.gsub(albumKey, "%s+", "")

	-- label formatting
	local linkText
	if linkOverrides[albumKey] then
		linkText = string.format("[[%s|<i>%s</i>]]", link, label)
	else
		linkText = "<i>" .. label .. "</i>"
	end

	-- row container
	local row = mw.html.create("tr")
	row:tag("td")
		:css("width","6px")
		:css("background-color", color)
	row:tag("td")
		:css("padding-left","0.5em")
		:css("padding-right","0.5em")
		:wikitext(linkText)
	row:tag("td")
		:wikitext(string.format(
			'<div class="mw-customtoggle-%s">(&nbsp;<span style="color:var(--color-progressive)">%d</span>&nbsp;)</div>',
			toggleId, count
		))
	-- collapsible song list
	local songList = {}
	for _,s in ipairs(songs) do
		table.insert(songList, "<li><i>"..s.."</i></li>")
	end
	row:tag("td")
		:wikitext(string.format(
			'<div class="mw-collapsible mw-collapsed" id="mw-customcollapsible-%s">' ..
			'<div class="mw-collapsible-content"><ul><small>%s</small></ul></div></div>',
			toggleId, table.concat(songList,"\n")
		))
	return tostring(row)
end

function p.render(frame)
	-- Gather songs from args
	local songs = {}
	for i=1,32 do
		local s = frame.args["Song"..i]
		if s and s ~= "" then table.insert(songs, s) end
		local sx = frame.args["Song"..i.."x"]
		if sx and sx ~= "" then table.insert(songs, sx) end
	end

	-- Count per album
	local counts, songMap = {}, {}
	for _,song in ipairs(songs) do
		local album = albumOf(frame, song)
		if album == "" then album = "Other" end
		counts[album] = (counts[album] or 0) + 1
		songMap[album] = songMap[album] or {}
		table.insert(songMap[album], song)
	end

	-- Sort albums by count desc
	local albums = {}
	for k,v in pairs(counts) do table.insert(albums, { key=k, count=v }) end
	table.sort(albums, function(a,b) return a.count > b.count end)

	-- Build slices
	local sliceStrings = {}
	for _,a in ipairs(albums) do
		local label = labelOverrides[a.key] or a.key
		local color = albumColor(frame, a.key)
		local link = linkOverrides[a.key] or (a.key ~= "Other" and a.key or "")
		table.insert(sliceStrings, string.format("(%d:%s:%s:%s)", a.count, label, color, link or ""))
	end

	-- Chart
	local chartSvg = chart["pie chart"]{
		args = {
			["radius"] = "100",
			["inner percent"] = "70",
			["slices"] = table.concat(sliceStrings, " ")
		}
	}

	-- Legend
	local legend = mw.html.create("table"):css("margin-top","0.5em")
	for _,a in ipairs(albums) do
		legend:wikitext(legendRow(frame, a.key, a.count, songMap[a.key] or {}))
	end

	return tostring(mw.html.create("div")
		:css("padding","1em")
		:wikitext(chartSvg .. tostring(legend)))
end

return p