2023年政策修订增补工作正在进行中,欢迎参与!
  • Moegirl.ICU:萌娘百科流亡社群 581077156(QQ),欢迎对萌娘百科运营感到失望的编辑者加入
  • Moegirl.ICU:账号认领正在试运行,有意者请参照账号认领流程

Module:Sandbox/公的驱逐舰/radarGraph

萌娘百科,万物皆可萌的百科全书!转载请标注来源页面的网页链接,并声明引自萌娘百科。内容不可商用。
跳转到导航 跳转到搜索
Template-info.svg 模块文档  [创建] [刷新]
local p = {}
local getArgs = require ( 'Module:Arguments' ).getArgs
local wrapperArray = { 'Template:雷达图', 'Template:沙盒' }

local rad2rect = function (r,th)
	return r*math.cos(th),r*math.sin(th)
end
local round = function (num,exp)
	exp = exp or 0
	return math.floor((num*10^exp)+0.5)*10^(-1*exp)
end

p.radarGraph = function (args)
	-- process input data
	args = args or {}
	args.count = tonumber(args.count) or 6
	args.count = (args.count<3 and 3) or (args.count>8 and 8 or math.floor(args.count) ) -- min & max data count defined (3 & 8) 
	args.size = tonumber(args.size) or 100
	args.width = tonumber(args.width) or args.size*2
	args.height = tonumber(args.height) or args.size*2
	args.rotation = tonumber(args.rotation) or 0
	args.color = args.color or '#666' args.bgcolor = args.bgcolor or '#000'
	args.ftcolor = args.ftcolor or '#000' args.numcolor = args.numcolor or '#fff'
	args.labelsize = tonumber(args.labelsize) or 14 args.numsize = tonumber(args.numsize) or 14
	local maxVar = 0
	for i=1, args.count do
		args['text'..i] = args['text'..i] or (args['debug']~=nil and tostring(i) or '数据')
		args['var'..i] = tonumber(args['var'..i]) or (args.pmode~=nil and 0.5 or args.size)
		maxVar = maxVar < args['var'..i] and args['var'..i] or maxVar
		args['num'..i] = args['num'..i] or tostring(args['var'..i])
	end
	maxVar = args.pmode~=nil and maxVar*args.size or maxVar
	local overflow = maxVar-args.size>0 and maxVar-args.size or 0
	maxVar = nil
	mw.logObject(args)
	
	--build SVG path and texts
	local bgPathTable = {} local dataPathTable = {} local loneDataTable = {}
	local numTable = {} local labelTable = {}
	for i=1, args.count do
		local angle = ((2*(i-1)/args.count)-0.5)*math.pi+math.rad(args.rotation)
		local dx,dy = rad2rect( (args.pmode~=nil and args['var'..i]*args.size or args['var'..i]) , angle)
		local bx,by = rad2rect(args.size, angle)
		local nx,ny = rad2rect(args.size-(args.numsize*0.75), angle-math.rad(90))
		local lx,ly = rad2rect(args.size+(args.labelsize), angle-math.rad(90))
		bgPathTable[#bgPathTable+1] = i==1 and 'M' or 'L'
		bgPathTable[#bgPathTable+1] = round(bx+args.size,2)
		bgPathTable[#bgPathTable+1] = round(by+args.size,2)
		if (args['var'..(i==1 and args.count or (i-1))] == 0 and
			args['var'..(i==args.count and 1 or (i+1))] == 0
		) then
			loneDataTable[#loneDataTable+1] = { (args.pmode~=nil and args['var'..i]*args.size or args['var'..i]), angle }
		else
			dataPathTable[#dataPathTable+1] = i==1 and 'M' or 'L'
			dataPathTable[#dataPathTable+1] = round(dx+args.size+overflow,2)
			dataPathTable[#dataPathTable+1] = round(dy+args.size+overflow,2)
		end
		numTable[#numTable+1] = {x=round(nx+args.size,2), y=round(args.size-ny,2), str=args['num'..i]}
		labelTable[#labelTable+1] = {x=round(lx+args.size,2), y=round(args.size-ly,2), str=args['text'..i]}
	end
	bgPathTable[#bgPathTable+1] = 'Z'
	dataPathTable[#dataPathTable+1] = 'Z'
	local graphHTML = mw.html.create('div')
		:addClass(args.class):addClass('radar-graph'):addClass('outer')
		:css({
			['box-sizing']='content-box',
			width=args.width..'px', height=args.height..'px',
			--[[['margin-left']='20px', ]]padding='20px'
		})
		:newline()
		:tag('div')
			:addClass('inner')
			:css({
				position='relative',
				width=(args.size*2)..'px', height=(args.size*2)..'px',
			})
			:newline()
			:tag('div')
				:addClass('base-polygon')
				:css({
					position='absolute', top='0', left='0',
					width=(args.size*2)..'px', height=(args.size*2)..'px',
					background=args.bgcolor,
					['clip-path']=[[path(']]..table.concat(bgPathTable,' ')..[[')]]
				})	
			:done()
			:newline()
			:tag('div')
				:addClass('data-polygon')
				:css({
					position='absolute',
					top=(overflow==0 and '0' or ('-'..overflow..'px')),
					left=(overflow==0 and '0' or ('-'..overflow..'px')),
					width=((overflow+args.size)*2)..'px';
					height=((overflow+args.size)*2)..'px';
					background=args.color,
					['clip-path']=[[path(']]..table.concat(dataPathTable,' ')..[[')]]
				})	
			:done()
			:newline()
			:tag('div')
				:addClass('num-parent')
				:css({
					position='absolute', top='0', left='0',
					width=(args.size*2)..'px', height=(args.size*2)..'px',
					color=args.numcolor
				})		
	for i=1, args.count do
		graphHTML
			:newline()
			:tag('div')
				:addClass('radar-numtext')
				:css({
					position='absolute',
					top=(numTable[i].x..'px'),
					left=(numTable[i].y..'px'),
					transform=args['numtransform'..i] or (args.numtransform or 'translate(-50%,-50%)')
				})
				:wikitext(numTable[i].str)
			--:done()
	end
	graphHTML = graphHTML
		:done()
		:newline()
		:tag('div')
			:addClass('label-parent')
			:css({
				position='absolute', top='0', left='0',
				width=(args.size*3)..'px', height=(args.size*3)..'px',
				color=args.numcolor
			})
	for i=1, args.count do
		graphHTML
			:newline()
			:tag('div')
				:addClass('radar-labeltext')
				:css({
					position='absolute',
					top=(labelTable[i].x..'px'),
					left=(labelTable[i].y..'px'),
					transform=args['labeltransform'..i] or (args.labeltransform or 'translate(-50%,-50%)')
				})
				:wikitext(labelTable[i].str)
			--:done()
	end
	return tostring( graphHTML:newline():allDone() )	
end

p.radarDebug = function(a) mw.log( p.radarGraph(a) ) end
p.main = function( frame ) return p.radarGraph ( getArgs ( frame, { wrappers = wrapperArray } ) ) end

return p