Module:Bar/sandbox: Difference between revisions
Appearance
Content deleted Content added
Upgraded module to the new Lua class framework |
m Fixed display issue when no stacked bars are given |
||
Line 161: | Line 161: | ||
width = tonumber(('%.2f'):format(width)) |
width = tonumber(('%.2f'):format(width)) |
||
if width == 0 then |
if width == 0 then |
||
output[i+4] = '' |
output[i+4] = ' ' |
||
else |
else |
||
title = args['title' .. i] and ' title="' .. args['title' .. i] .. '"' or '' |
title = args['title' .. i] and ' title="' .. args['title' .. i] .. '"' or '' |
Revision as of 02:00, 14 June 2021
![]() | This is the module sandbox page for Module:Bar (diff). |
![]() | This module is rated as beta, and is ready for widespread use. It is still new and should be used with some caution to ensure the results are as expected. |
![]() | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
![]() | This module uses TemplateStyles: |
![]() | This module depends on the following other modules: |
![]() | This Lua module is used on many pages and changes may be widely noticed. Test changes in the module's /sandbox or /testcases subpages, or in your own module sandbox. Consider discussing changes on the talk page before implementing them. |
{{Bar box}}, is used for construction of horizontal bar charts.
Usage
{{Bar box
|width = ''width of the graph'' (optional)
|barwidth= ''width of the bar area'' (optional, defaults to 100px)
|float = (left|right|none) (optional, defaults to none)
|title = ''title of the chart'' (optional)
|titlebar= ''title bar colour'' (optional, defaults to none)
|left1 = ''first left column header'' (optional)
|left2 = ''second left column header'' (optional)
|right1 = ''first right column header'' (optional)
|right2 = ''second right column header'' (optional)
|bars = ''chart contents'' (see below)
|caption = ''caption under the chart'' (optional)
}}
Alternatives to avoid Wikipedia's Post-expand include size limit
Pages with many boxes and charts may come close to or exceed Wikipedia's Post-expand include size limit. In these cases consider using Module:Bar as follows:
- {{Bar box}} → {{#invoke:Bar|box}}
- {{Bar percent}} → {{#invoke:Bar|percent}}
- {{Bar pixel}} → {{#invoke:Bar|pixel}}
- {{Bar log}} → {{#invoke:Bar|log}}
- {{Bar stacked}} → {{#invoke:Bar|stacked}}
- {{Bar gap}} → {{#invoke:Bar|gap}}
Tracking category
See also
- {{Vertical bar chart}}
- {{Bar chart}}
- {{Data bars}}
- WP:Graphs
require('Module:Lua class')
local BarBox = class('BarBox', {
_css = 'Module:Bar box/styles.css',
__init = function (self, args)
self.css = args.css
self.float = args.float or 'none'
self.backgroundcolor = args.backgroundcolor or 'white'
self.borderwidth = args.borderwidth or '1'
self.style = args.style
self.width = args.width-- or 'auto'
self.barwidth = args.barwidth or '100px'
self.lineheight = args.lineheight-- or '1.6'
self.title = args.title
self.titlebar = args.titlebar-- or 'none'
self.left1 = args.left1
self.left2 = args.left2
self.right1 = args.right1
self.right2 = args.right2
self.bars = args.bars
self.caption = args.caption -- deprecated
self.footer = args.footer or args.caption
end,
create = function (cls, args)
args = mw.clone(args)
args.float = args.float and args.float:lower()
args.width = tonumber(args.width) and args.width .. 'px' or args.width and args.width:lower()
args.barwidth = tonumber(args.barwidth) and args.barwidth .. 'px' or args.barwidth and args.barwidth:lower()
return cls(args)
end,
_sDefaultAlign = 'lrlr',
_tDefaultAlign = {false, 'r', false, 'r'},
_setAlign = function (obj, align)
obj._alignClasses = {}
for i, d in ipairs(obj._tDefaultAlign) do
local a = align:sub(i,i)
if a == 'l' then
a = false
elseif a == 'd' then
a = d
elseif a ~= 'c' and a ~= 'r' then
error('unrecognized align[' .. i .. ']')
end
obj._alignClasses[i] = (a and ' class=bb-' .. a or '') .. '|'
end
end,
html = function (self)
local output = {}
local frame = mw.getCurrentFrame()
output[1] = frame:extensionTag('templatestyles', '', {src=self._css}) .. '\n'
output[2] = self.css and frame:extensionTag('templatestyles', '', {src=self.css}) .. '\n' or ''
local class = 'barbox'
if self.float == 'left' or self.float == 'right' then
class = class .. ' t' .. self.float
end
output[3] =
'<div class="' .. class .. '" style="background:' .. self.backgroundcolor ..
'; border:' .. self.borderwidth .. 'px solid silver' ..
(self.float == 'center' and '; margin:0 auto' or '') ..
(self.width and '; width:' .. self.width or '') ..
(self.style and '; ' .. self.style or '') .. '">\n' ..
'{|' .. (self.lineheight and ' style="line-height:' .. self.lineheight .. '"' or '') .. '\n'
output[4] = self.title and
'|+ class=bb-default' .. (self.titlebar and ' style="background:' .. self.titlebar .. '"' or '') .. ' |\n' ..
self.title .. '\n'
or ''
output[5] = '|- class=bb-default style="font-size:88%; min-height:4px"\n'
if self._alignClasses then -- same as self.__class._alignClasses
self._alignClasses = self._alignClasses
self.__class._alignClasses = nil
else
self._setAlign(self, self._sDefaultAlign)
end
output[6] = '!' .. (self.left2 and '' or 'colspan=2') .. self._alignClasses[1] .. (self.left1 or ' ')
output[7] = self.left2 and '!!' .. self._alignClasses[2] .. self.left2 or ''
output[8] = '!!style="width:' .. self.barwidth .. '"| '
output[9] = '!!' .. (self.right2 and self._alignClasses[3] or 'colspan=2' .. self._alignClasses[4]) .. (self.right1 or ' ')
output[10] = self.right2 and '!!' .. self._alignClasses[4] .. self.right2 or ''
output[11] = '\n'
output[12] = self.bars and self.bars .. '\n' or ''
if self.caption then
output[15] = '\n[[Category:Pages using bar box with deprecated caption parameter]]'
else
output[15] = ''
end
output[13] = self.footer and
'|- class=bb-default\n| colspan=5 style="padding:5px 0" | ' ..
self.footer .. '\n' -- <p> is created if \n precedes the footer
or ''
output[14] = '|}\n</div>\n'
return table.concat(output)
end,
__tostring = function (self)
return self.html()
end,
percent = function (args)
local output = {}
local percentage = (args[3] or '0') .. '%'
output[1] = '|-' .. (args.bg and 'style="background:' .. args.bg .. '"' or '') .. '\n'
output[2] = '|colspan=2 class=bb-min8|' .. (args[1] or ' ')
output[3] = '||class=bb-b|'
output[4] = '<div style="background:' .. (args[2] or 'gray') .. '; width:' .. percentage .. '">​</div>'
output[5] = '||' .. (args.note and '' or 'colspan=2 class=bb-r|') .. (args[4] or percentage)
output[6] = args.note and '||class=bb-r|' .. args.note or ''
return table.concat(output)
end,
pixel = function (args)
local output = {}
local pixels = args[3] or '0'
output[1] = '|-' .. (args.bg and 'style="background:' .. args.bg .. '"' or '') .. '\n'
output[2] = '|colspan=2|' .. (args[1] or ' ')
output[3] = '||class=bb-b|'
output[4] = '<div style="background:' .. (args[2] or 'gray') .. '; width:' .. pixels .. 'px">​</div>'
output[5] = '||class="bb-min3' .. (args.note and '"' or ' bb-r" colspan=2') .. '|' .. (args[5] or pixels .. (args[4] or ''))
output[6] = args.note and '||class=bb-r|' .. args.note or ''
return table.concat(output)
end,
stacked = function (cls, args)
local output = {}
output[1] = args.id and
'|-class="mw-collapsible' .. (args.collapsed and ' mw-collapsed' or '') .. '" id=mw-customcollapsible-' .. args.id .. '\n'
or '|-\n'
if not cls._alignClasses then
cls._setAlign(cls, args.align and args.align:lower() or cls._sDefaultAlign)
end
output[2] = '|' .. (args.note1 and '' or 'colspan=2') .. cls._alignClasses[1] .. (args[1] or ' ')
output[3] = args.note1 and '||' .. cls._alignClasses[2] .. args.note1 or ''
output[4] = '||class=bb-b|'
local len = 4 -- can't use #args because of [[Module:Arguments#Known limitations]]
for k in pairs(args) do
local idx = tonumber(k) or 0
if idx > len then len = idx end
end
for i = 1, (len-2) / 2 do
local width, title, background
width = args[2*i + 2] or 0
width = tonumber(('%.2f'):format(width))
if width == 0 then
output[i+4] = ' '
else
title = args['title' .. i] and ' title="' .. args['title' .. i] .. '"' or ''
background = args[2*i + 1] or 'gray'
output[i+4] = '<div' .. title .. ' style="background:' .. background .. '; width:' .. width .. 'px">​</div>'
end
end
output[#output+1] = '||' .. (args.note2 and cls._alignClasses[3] or 'colspan=2' .. cls._alignClasses[4]) .. (args[2] or ' ')
output[#output+1] = args.note2 and '||' .. cls._alignClasses[4] .. args.note2 or ''
return table.concat(output)
end,
gap = function (args)
local output = {}
local height = tonumber(args.height) and args.height .. 'px' or args.height and args.height:lower() or '10px'
output[1] = '|-\n'
output[2] = '|colspan=5 style="height:' .. height .. '"|' .. (args[1] or '')
return table.concat(output)
end,
__classmethods = {'create', 'stacked'},
__staticmethods = {'_setAlign', 'percent', 'pixel', 'gap'},
__slots = {'_alignClasses'}
})
local getArgs = require('Module:Arguments').getArgs
local p = {BarBox=BarBox}
function p.box(frame)
local args = getArgs(frame)
local box = BarBox.create(args)
return tostring(box)
end
function p.percent(frame)
local args = getArgs(frame)
return BarBox.percent(args)
end
function p.pixel(frame)
local args = getArgs(frame)
return BarBox.pixel(args)
end
function p.stacked(frame)
local yesno = require('Module:Yesno')
local args = getArgs(frame, {
valueFunc = function (key, value)
if value then
if key == 'collapsed' then
return yesno(value)
end
value = mw.text.trim(value)
if value ~= '' then
return value
end
end
return nil
end
})
return BarBox.stacked(args)
end
function p.gap(frame)
local args = getArgs(frame)
return BarBox.gap(args)
end
return p