🌟現在、鉄壁 鉄壁ヘッドショットには対応済みです。
鉄壁HSは通常HSと同じダメージになります。LMG及びDMR、チャージライフル、ハンマーポイント弾を除き、すべてのダメージ値が一致していることを確認しています。

「モジュール:Utility/TableUtil」の版間の差分

提供:Apex Data
ナビゲーションに移動 検索に移動
(ヘッダーのcolspanを指定できるように変更)
(クラスCellの初期化コードの改善)
27行目: 27行目:
}
}
if opts then
if opts then
obj.attributes   = opts.attributes or {}
obj.attributes = opts.attributes or {}
obj.cellClass     = opts.cellClass
obj.headerClass   = opts.headerClass
if type(opts.cellClass) == 'string' then
obj.headerColspan = opts.headerColspan or 1
obj.cellClass = opts.cellClass
obj.headerStyle   = opts.headerStyle
end
if type(opts.headerClass) == 'string' then
obj.headerClass = opts.headerClass
end
if type(opts.headerColspan) == 'number' then
obj.headerColspan = opts.headerColspan
else
obj.headerColspan = 1
end
if type(opts.headerStyle) == 'string' then
obj.headerStyle = opts.headerStyle
end
else
else
obj.attributes    = {}
obj.attributes    = {}
53行目: 67行目:
local headerCell = headerRow:tag('th'):wikitext(self.name)
local headerCell = headerRow:tag('th'):wikitext(self.name)
if type(self.headerClass) == 'string' then
if self.headerClass then
headerCell:addClass(self.headerClass)
headerCell:addClass(self.headerClass)
end
end
59行目: 73行目:
headerCell:attr('colspan', self.headerColspan)
headerCell:attr('colspan', self.headerColspan)
end
end
if type(self.headerStyle) == 'table' then
if self.headerStyle then
headerCell:css(self.headerStyle)
headerCell:css(self.headerStyle)
end
end
68行目: 82行目:
function __TableUtil__Cell:render(row)
function __TableUtil__Cell:render(row)
local cell = row:tag('td'):attr(self.attributes)
local cell = row:tag('td'):attr(self.attributes)
if type(self.cellClass) == 'string' then
if self.cellClass then
cell:addClass(self.cellClass)
cell:addClass(self.cellClass)
end
end

2021年8月17日 (火) 15:13時点における版

このモジュールについての説明文ページを モジュール:Utility/TableUtil/doc に作成できます

-- ====================
-- namespace: TableUtil
-- ====================
local tableutil = {}

-- =====
-- Config
-- =====
local aw = require('Module:Utility/Library')
local function __passthrough(num)
	return num
end

-- ==========
-- type: Cell
-- ==========
local __TableUtil__CellType__Cell = 'cell'
local __TableUtil__Cell = {
	__typename = __TableUtil__CellType__Cell,
}

-- [Constructor]
function __TableUtil__Cell.__new(typename, name, opts)
	local obj = {
		typename   = typename,
		name       = name,
	}
	if opts then
		obj.attributes = opts.attributes or {}
		
		if type(opts.cellClass) == 'string' then
			obj.cellClass = opts.cellClass
		end
		
		if type(opts.headerClass) == 'string' then
			obj.headerClass = opts.headerClass
		end
		
		if type(opts.headerColspan) == 'number' then
			obj.headerColspan = opts.headerColspan
		else
			obj.headerColspan = 1
		end
		
		if type(opts.headerStyle) == 'string' then
			obj.headerStyle = opts.headerStyle
		end
	else
		obj.attributes    = {}
		obj.headerColspan = 1
	end
	return setmetatable(obj, { __index = __TableUtil__Cell })
end
function __TableUtil__Cell.new(name, opts)
	return __TableUtil__Cell.__new(__TableUtil__CellType__Cell, name, opts)
end

-- [Function] Reset context
function __TableUtil__Cell:resetContext()
end

-- [Function] Render header
function __TableUtil__Cell:renderHeader(headerRow)
	if self.headerColspan <= 0 then
		return nil
	end
	
	local headerCell = headerRow:tag('th'):wikitext(self.name)
	if self.headerClass then
		headerCell:addClass(self.headerClass)
	end
	if self.headerColspan > 1 then
		headerCell:attr('colspan', self.headerColspan)
	end
	if self.headerStyle then
		headerCell:css(self.headerStyle)
	end
	return headerCell
end

-- [Function] Render
function __TableUtil__Cell:render(row)
	local cell = row:tag('td'):attr(self.attributes)
	if self.cellClass then
		cell:addClass(self.cellClass)
	end
	return cell
end

-- [Export]
tableutil.Cell = __TableUtil__Cell

-- =====================
-- type: ValueCell: Cell
-- =====================
local __TableUtil__CellType__ValueCell = 'value'
local __TableUtil__ValueCell = {
	__typename = __TableUtil__CellType__ValueCell,
}
setmetatable(__TableUtil__ValueCell, { __index = __TableUtil__Cell })

-- [Constructor]
function __TableUtil__ValueCell.__new(typename, name, dataIndex, opts)
	local obj = __TableUtil__Cell.__new(typename, name, opts)
	obj.__cell__render = obj.render
	obj.dataIndex = dataIndex
	if type(opts) == 'table' then
		obj.format = opts.format or __passthrough
	else
		obj.format = __passthrough
	end
	return setmetatable(obj, { __index = __TableUtil__ValueCell })
end
function __TableUtil__ValueCell.new(name, dataIndex, opts)
	return __TableUtil__ValueCell.__new(__TableUtil__CellType__ValueCell, name, dataIndex, opts)
end

-- [Function] Render
function __TableUtil__ValueCell:render(row, dataset, i, datainfo)
	local value = dataset[self.dataIndex]
	local formattedValue = self.format(value)
	local cell = self:__cell__render(row, dataset, i, datainfo)
		:attr('data-sort-value', value)
		:wikitext(formattedValue)
	return cell
end

-- [Export]
tableutil.ValueCell = __TableUtil__ValueCell

-- =========================
-- type: RankCell: ValueCell
-- =========================
local __TableUtil__CellType__RankCell = 'rank'
local __TableUtil__RankCell = {
	__typename = __TableUtil__CellType__RankCell,
}
setmetatable(__TableUtil__RankCell, { __index = __TableUtil__ValueCell })

-- [Constructor]
function __TableUtil__RankCell.new(name, dataIndex, descending)
	local obj = __TableUtil__ValueCell.__new(__TableUtil__CellType__RankCell, name, dataIndex)
	obj.currentRank  = 0
	obj.currentValue = -1
	obj.descending   = descending
	return setmetatable(obj, { __index = __TableUtil__RankCell })
end

-- [Property] Is descending?
function __TableUtil__RankCell:isDescending()
	return self.descending
end

-- [Function] Reset context
function __TableUtil__RankCell:resetContext()
	self.currentRank  = 0
	self.currentValue = -1
end

-- [Function] Render
function __TableUtil__RankCell:render(row, dataset, i)
	local value = dataset[self.dataIndex]
	if self.currentValue ~= value then
		self.currentRank = i
		self.currentValue = value
	end
	local cell = row:tag('th')
		:attr('data-sort-value', value)
		:wikitext(self.currentRank)
	return cell
end

-- [Export]
tableutil.RankCell = __TableUtil__RankCell

-- ====================
-- type: LineCell: Cell
-- ====================
local __TableUtil__CellType__LineCell = 'line'
local __TableUtil__LineCell = {
	__typename = __TableUtil__CellType__LineCell,
}
setmetatable(__TableUtil__LineCell, { __index = __TableUtil__ValueCell })

-- [Constructor]
function __TableUtil__LineCell.__new(typename, name, dataIndex, opts)
	local obj = __TableUtil__Cell.__new(typename, name, opts)
	obj.__cell__render = obj.render
	obj.dataIndex = dataIndex
	if type(opts) == 'table' then
		obj.colorStops   = opts.colorStops   or '#A7D7F9'
		obj.height       = opts.height       or 1.2
		obj.minimumValue = opts.minimumValue or 0
		obj.maximumRate  = opts.maximumRate  or 1.05
	else
		obj.colorStops   = '#A7D7F9'
		obj.height       = 1.2
		obj.minimumValue = 0
		obj.maximumRate  = 1.05
	end
	return setmetatable(obj, { __index = __TableUtil__LineCell })
end
function __TableUtil__LineCell.new(name, dataIndex, opts)
	return __TableUtil__LineCell.__new(__TableUtil__CellType__LineCell, name, dataIndex, opts)
end

-- [Property] Height
function __TableUtil__LineCell:setHeight(value)
	self.height = value
	return self
end

-- [Function] Render
function __TableUtil__LineCell:render(row, dataset, i, datainfo)
	local gradientFormat
	if type(self.colorStops) == 'table' then
		if self.mixinValue then
			gradientFormat = function(percentage, value)
				return string.format(
					'linear-gradient(to right,transparent,%s %s%%,%s %s%%,transparent %s%%)',
					self.colorStops[1],
					percentage,
					self.colorStops[2],
					percentage,
					percentage)
			end
		else
			gradientFormat = function(percentage, value)
				return string.format(
					'linear-gradient(to right,transparent,%s %s%%,%s %s%%,transparent %s%%)!important',
					self.colorStops[1],
					percentage,
					self.colorStops[2],
					percentage,
					percentage)
			end
		end
	else
		if self.mixinValue then
			gradientFormat = function(percentage, value)
				return string.format(
					'linear-gradient(to right,%s %s%%,transparent %s%%)',
					self.colorStops,
					percentage,
					percentage)
			end
		else
			gradientFormat = function(percentage, value)
				return string.format(
					'linear-gradient(to right,%s %s%%,transparent %s%%)!important',
					self.colorStops,
					percentage,
					percentage)
			end
		end
	end
	
	local value = dataset[self.dataIndex]
	local targetDataInfo = datainfo[self.dataIndex]
	local minimumValue   = self.minimumValue or targetDataInfo.minValue
	local percentage
	if value == math.huge then
		percentage = 100
	else
		percentage = 0.001 * aw.round(100000 * (value - minimumValue) / (self.maximumRate * (targetDataInfo.maxValue - minimumValue)))
	end
	local cell = self:__cell__render(row, dataset, i, datainfo)
		:addClass('stattable-line')
		:addClass(string.format('stattable-line-h%d', 10 * self.height))
		:attr('data-sort-value', value)
		:css('background-image', gradientFormat(percentage, value))
	return cell
end

-- [Export]
tableutil.LineCell = __TableUtil__LineCell

-- =================
-- type: Value+XCell
-- =================
local function transformValueCell(superklass, klasstype)
	local valuetype = string.format('value+%s', klasstype)
	local valueKlass = {
		__typename = valuetype,
	}
	setmetatable(valueKlass, { __index = superklass })
	
	function valueKlass.new(name, dataIndex, opts)
		local obj = superklass.__new(valuetype, name, dataIndex, opts)
		obj.__super__render = obj.render
		obj.mixinValue = true
		if type(opts) == 'table' then
			obj.format = opts.format or __passthrough
		else
			obj.format = __passthrough
		end
		return setmetatable(obj, { __index = valueKlass })
	end
	function valueKlass:render(row, dataset, i, datainfo)
		local value = dataset[self.dataIndex]
		local formattedValue = self.format(value)
		local cell = self:__super__render(row, dataset, i, datainfo)
		return cell:wikitext(formattedValue)
	end
	return valueKlass
end

-- [Export]
tableutil.LineValueCell = transformValueCell(__TableUtil__LineCell, __TableUtil__CellType__LineCell)

-- ===================
-- func: specifyUICell
-- ===================
function tableutil.specifyUICell(klasstype, renderFunction, propNames)
	local specifictype = string.format('ui+%s', klasstype)
	local specificKlass = {
		__typename = specifictype,
	}
	setmetatable(specificKlass, { __index = __TableUtil__Cell })
	
	function specificKlass.new(name, dataIndex, opts)
		local obj = __TableUtil__Cell.__new(specifictype, name, opts)
		obj.__cell__render = obj.render
		obj.dataIndex      = dataIndex
		if propNames and opts then
			for _, name in ipairs(propNames) do
				obj[name] = opts[name]
			end
		end
		return setmetatable(obj, { __index = specificKlass })
	end
	specificKlass.render = renderFunction
	return specificKlass
end

-- =================
-- func: createTable
-- =================
function tableutil.createTable(dataset, metadata)
	local tbl = mw.html.create('table')
		:addClass('numbertable')
		:addClass('sortable')
		:addClass('stattable')
		:addClass('wikitable')
	
	-- Build header
	local headerRow = tbl:tag('tr'):addClass('row-sticky')
	local sortIndex = 0
	local isDesc = false
	for _, m in ipairs(metadata) do
		-- Reset context for building process
		m:resetContext()
		
		if m.typename == tableutil.RankCell.__typename then
			sortIndex = m.dataIndex
			isDesc    = m:isDescending()
		end
		
		-- Render header
		m:renderHeader(headerRow)
	end
	
	-- Sort data
	if sortIndex ~= 0 then
		local sortFunction
		if isDesc then
			sortFunction = function(a, b)
				return a[sortIndex] > b[sortIndex]
			end
		else
			sortFunction = function(a, b)
				return a[sortIndex] < b[sortIndex]
			end
		end
		table.sort(dataset, sortFunction)
	end
	
	-- Preprocess data
	local datainfo = {}
	for _, ary in ipairs(dataset) do
		for key, d in pairs(ary) do
			if type(d) == 'number' and d ~= math.huge then
				if not datainfo[key] then
					datainfo[key] = {
						minValue = d,
						maxValue = d,
					}
				else
					if datainfo[key].minValue > d then
						datainfo[key].minValue = d
					end
					if datainfo[key].maxValue < d then
						datainfo[key].maxValue = d
					end
				end
			end
		end
	end
	
	-- Build cell
	for i, d in ipairs(dataset) do
		local row = tbl:tag('tr')
		for k, m in ipairs(metadata) do
			m:render(row, d, i, datainfo)
		end
	end

	return tbl
end

-- =================
-- test: Simple test
-- =================
function tableutil.__test()
	local metadata = {
		tableutil.RankCell.new('', 1),
		tableutil.ValueCell.new('Value', 1),
		tableutil.LineCell.new('Line', 1),
		tableutil.LineCell.new('LineGradient', 1, { colorStops = { '#F8B3BC', '#F26D7D' }, height = 1.4 }),
		tableutil.LineValueCell.new('LineValue', 2, { cellClass = 'stattable-graph-both' }),
	}
	local node = tableutil.createTable({{ 45, 110 }, { 40, 60 }, { 40, 120 }, { 50, 90 }}, metadata)
	return tostring(node)
end

return tableutil