2023年政策修订增补工作正在进行中,欢迎参与!
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