Module:Sandbox/Nzh21/sandbox
跳到导航
跳到搜索
local p = {} local getArgs = require('Module:Arguments').getArgs -- a -- --------------- -- \ alpha / -- \ / -- b\ / -- \ / -- \/ local function CreateTriangle(a, b, alpha, color) if (alpha > 90) then error() end local ALPHA = alpha * math.pi / 180 local A, B; if (a > math.cos(ALPHA) * b) then A, B = a, b else A, B = b, a end local outer = mw.html.create('div') :css('position', 'relative') local inner = mw.html.create('div') :css('position', 'absolute') :css('border-left', tostring(math.cos(ALPHA) * B)..'px solid transparent') :css('border-right', tostring(A - math.cos(ALPHA) * B)..'px solid transparent') mw.log(A, B, A - math.cos(ALPHA) * B) if (a > math.cos(ALPHA) * b) then inner :css('border-top', tostring(math.sin(ALPHA) * B)..'px solid '..color) else inner :css('border-bottom', tostring(math.sin(ALPHA) * B)..'px solid '..color) :css('transform', 'rotate('..tostring(alpha)..'deg)') :css('transform-origin', '0 100%') :css('top', tostring(-math.sin(ALPHA) * B)..'px') end outer:node(inner) return outer end local function CreateRadarChart(data, max, color, bgcolor, name, number) if (#name ~= #number or #data ~= #number or #data ~= #name) then error() end local n = #data local outer = mw.html.create('div') :css('position', 'relative') :css('width', tostring(max * 2)..'px') :css('height', tostring(max * 2)..'px') :css('margin', '0 auto') for i = 1, #data do local bg = CreateTriangle(max, max, 360 / n, bgcolor) local front = CreateTriangle(data[i], data[i % n + 1], 360 / n, color) local inner = mw.html.create('div') :css('position', 'relative') :css('transform', 'rotate('..tostring(-90 + 360 / n * (i - 1))..'deg)') :css('transform-origin', '0 0') :css('top', tostring(max)..'px') :css('left', tostring(max)..'px') inner:node(bg) inner:node(front) outer:node(inner) end for i = 1, n do local name_tag = mw.html.create('div') :css('position', 'absolute') :css('top', tostring(max - math.cos(2 * math.pi / n * (i - 1)) * (max + 8))..'px') :wikitext(name[i] or '') local number_tag = mw.html.create('div') :css('position', 'absolute') :css('transform', 'translate(-50%, -50%)') :css('left', tostring(max + math.sin(2 * math.pi / n * (i - 1)) * (max - 10))..'px') :css('top', tostring(max - math.cos(2 * math.pi / n * (i - 1)) * (max - 10))..'px') :wikitext(number[i] or '') if (i % math.ceil(n / 2) == 1 or (n % 2 == 1 and i == math.ceil(n / 2))) then -- 顶部/底部标签 name_tag :css('transform', 'translate(-50%, -50%)') :css('left', tostring(max + math.sin(2 * math.pi / n * (i - 1)) * (max + 8))..'px') elseif i > n / 2 then -- 左侧标签 name_tag :css('transform', 'translate(-100%, -50%)') :css('left', tostring(max + math.sin(2 * math.pi / n * (i - 1)) * (max + 4))..'px') else -- 右侧标签 name_tag :css('transform', 'translate(100%, -50%)') :css('right', tostring(max * 2 - (max + math.sin(2 * math.pi / n * (i - 1)) * (max + 4)))..'px') end outer:node(name_tag) outer:node(number_tag) end return outer end local function Color(color, text) return '<span style="color:'..color..'">'..text..'</span>' end function p.main(frame) local args = getArgs(frame) local size = tonumber(args.size) or 100 local color = args.color or '#666' local bgcolor = args.bgcolor or '#000' local width = tonumber(args.width) or size * 2 local height = tonumber(args.height) or size * 2 local data = {} local name = {} local number = {} i = 1 while (args['var'..tostring(i)] ~= nil) do data[i] = tonumber(args['var'..tostring(i)]) name[i] = Color(args.ftcolor or '#000', args['text'..tostring(i)] or '数据') if (args.num and args.num =='none') then number[i] = '' else number[i] = Color(args.numcolor or '#fff', args['num'..tostring(i)] or data[i]) end i = i + 1 end local outer = mw.html.create('div') :css('width', tostring(width)..'px') :css('height', tostring(height)..'px') :css('padding', tostring((height - size * 2) / 2 + 30)..'px '..tostring((width - size * 2) / 2 + 30)..'px') :node(CreateRadarChart(data, size, color, bgcolor, name, number)) return outer end local function CreateRadarChartSvg(data, max, color, bgcolor, name, number) if (#name ~= #number or #data ~= #number or #data ~= #name) then error() end local n = #data local outer = mw.html.create('div') :css('position', 'relative') :css('width', tostring(max * 2)..'px') :css('height', tostring(max * 2)..'px') :css('margin', '0 auto') val = tostring(data[1]) for i = 2, n, 1 do val = val..','..tostring(data[i]) end path = 'https://api.nzh21.site/RadarChart.php?color='..color:gsub('#', 'sharp')..'&bgcolor='..bgcolor:gsub('#', 'sharp') ..'&max='..tostring(max)..'&val='..val local svg = mw.html.create('img') :attr('src', path) :css('width', tostring(max * 2)..'px') :css('height', tostring(max * 2)..'px') outer:node(svg) for i = 1, n do local name_tag = mw.html.create('div') :css('position', 'absolute') :css('top', tostring(max - math.cos(2 * math.pi / n * (i - 1)) * (max + 8))..'px') :wikitext(name[i] or '') local number_tag = mw.html.create('div') :css('position', 'absolute') :css('transform', 'translate(-50%, -50%)') :css('left', tostring(max + math.sin(2 * math.pi / n * (i - 1)) * (max - 10))..'px') :css('top', tostring(max - math.cos(2 * math.pi / n * (i - 1)) * (max - 10))..'px') :wikitext(number[i] or '') if (i % math.ceil(n / 2) == 1 or (n % 2 == 1 and i == math.ceil(n / 2))) then -- 顶部/底部标签 name_tag :css('transform', 'translate(-50%, -50%)') :css('left', tostring(max + math.sin(2 * math.pi / n * (i - 1)) * (max + 8))..'px') elseif i > n / 2 then -- 左侧标签 name_tag :css('transform', 'translate(-100%, -50%)') :css('left', tostring(max + math.sin(2 * math.pi / n * (i - 1)) * (max + 4))..'px') else -- 右侧标签 name_tag :css('transform', 'translate(100%, -50%)') :css('right', tostring(max * 2 - (max + math.sin(2 * math.pi / n * (i - 1)) * (max + 4)))..'px') end outer:node(name_tag) outer:node(number_tag) end return outer end function p.SvgVersion(frame) local args = getArgs(frame) local size = tonumber(args.size) or 100 local color = args.color or '#666' local bgcolor = args.bgcolor or '#000' local width = tonumber(args.width) or size * 2 local height = tonumber(args.height) or size * 2 local data = {} local name = {} local number = {} i = 1 while (args['var'..tostring(i)] ~= nil) do data[i] = tonumber(args['var'..tostring(i)]) name[i] = Color(args.ftcolor or '#000', args['text'..tostring(i)] or '数据') if (args.num and args.num =='none') then number[i] = '' else number[i] = Color(args.numcolor or '#fff', args['num'..tostring(i)] or data[i]) end i = i + 1 end local outer = mw.html.create('div') :css('width', tostring(width)..'px') :css('height', tostring(height)..'px') :css('padding', tostring((height - size * 2) / 2 + 30)..'px '..tostring((width - size * 2) / 2 + 30)..'px') :node(CreateRadarChartSvg(data, size, color, bgcolor, name, number)) return outer end return p