Module:Creo/Components/Stats
Appearance
This documentation is transcluded from Module:Creo/Components/Stats/doc.
Output a stat chart with the data from Module:Creo.
Stats mapping are located in Module:Creo/Components/Stats/Map.json.
Implements Template:Creo/Stats.
It is powered by Chart.js.
require( 'strict' )
local STATS_MAP = mw.loadJsonData( 'Module:Creo/Components/Stats/Map.json' )
local chartJs = require( 'Module:ChartJs' )
local gameTabs = require( 'Module:GameTabs' )
local p = {}
local overlayData = {}
--- Get the chart options for Chart.js
---
--- @return table
local function getChartOptions()
return {
plugins = {
legend = {
display = false,
}
},
scales = {
r = {
beginAtZero = true,
min = 0,
max = 50,
ticks = {
display = false,
maxTicksLimit = 1
},
pointLabels = {
display = false
}
}
}
}
end
--- Get the dataset for Chart.js
---
--- @return table
local function getDataset()
-- TODO: Update styles
return {
label = 'Stats',
data = {},
backgroundColor = 'rgba(54, 162, 235, 0.2)',
borderColor = 'rgb(54, 162, 235)',
pointBackgroundColor = 'rgb(54, 162, 235)',
pointBorderColor = '#fff',
pointHoverBackgroundColor = '#fff',
pointHoverBorderColor = 'rgb(54, 162, 235)'
}
end
--- Build the stats data for Chart.js
---
--- @param data table
--- @param gameId string
--- @return table|nil
local function getChartData( data, gameId )
-- Reset the overlay data
overlayData = {}
local chartData = {
labels = {},
datasets = { getDataset() }
}
if not STATS_MAP[gameId] then
return nil
end
for _, stat in ipairs( STATS_MAP[gameId] ) do
local statValue = data[stat.id]
if statValue then
table.insert( chartData.labels, stat.label )
table.insert( chartData.datasets[1].data, statValue )
table.insert( overlayData, {
id = stat.id,
label = stat.label,
value = statValue,
icon = stat.icon
} )
end
end
return chartData
end
--- Get the wikitext for the stat label
---
--- @param stat table
--- @return string
local function getStatLabelWikitext( stat )
local wikitext = stat.label
if type( stat.icon ) == 'string' then
wikitext = string.format( '[[File:%s|20px|link=|class=metadata]] %s', stat.icon, stat.label )
end
return wikitext
end
--- Get the HTML for the overlay
---
--- @param labels table
--- @return mw.html
local function getOverlayHtml( labels )
local html = mw.html.create( 'div' ):addClass( 't-creo-stats-overlay' )
local numStats = #labels
if numStats == 0 then
return html
end
html:css( '--t-creo-stats-num-stats', numStats )
for i, stat in ipairs( overlayData ) do
html:tag( 'div' )
:addClass( 't-creo-stats-overlay-stat' )
:addClass( 't-creo-stats-overlay-stat--' .. stat.id )
:css( '--t-creo-stats-stat-index', i - 1 )
:tag( 'div' )
:addClass( 't-creo-stats-overlay-stat-label' )
:attr( 'title', stat.label )
:wikitext( getStatLabelWikitext( stat ) )
:done()
:tag( 'div' )
:addClass( 't-creo-stats-overlay-stat-value' )
:wikitext( stat.value )
:done()
:done()
end
return html
end
--- Get the HTML for the stats
---
--- @param chartData table
--- @return mw.html
local function getStatsHtml( chartData )
local html = mw.html.create( 'div' ):addClass( 't-creo-stats' )
html:tag( 'div' ):addClass( 't-creo-stats-inner' )
:wikitext( chartJs.render( {
type = 'radar',
data = chartData,
options = getChartOptions()
} ) )
:node( getOverlayHtml( chartData.labels ) )
return html
end
--- Get the data for the game tabs
---
--- @param context ComponentContext
--- @return table
local function getGameTabsData( context )
local gameTabsData = gameTabs.mapGameArgs( context.data, function( data, game )
local chartData = getChartData( data, game.id )
if not chartData then
return string.format( 'No stats available for %s (%s)', game.name, game.id )
end
return tostring( getStatsHtml( chartData ) )
end )
gameTabsData.noPadding = true
return gameTabsData
end
--- Return the wikitext for the stats
---
--- @param context ComponentContext
--- @return string
function p.render( context )
local root = mw.html.create( 'div' ):addClass( 't-creo-stats-container' )
:wikitext( gameTabs._main( getGameTabsData( context ) ) )
return mw.getCurrentFrame():extensionTag {
name = 'templatestyles', args = { src = 'Module:Creo/Components/Stats/styles.css' }
} .. tostring( root )
end
return p