Module:Television ratings graph: Difference between revisions

Content deleted Content added
set width for colored cell in season row automatically, slightly increase the width of cells with viewer figures
oops typo
 
(49 intermediate revisions by 13 users not shown)
Line 9:
 
local TVRG = {}
 
-- Convert HEX codes to RGB values
function TVRG.hex2rgb(hex)
hex = hex:gsub('#', '')
if #hex == 3 then
-- #000 format
return tonumber("0x"..hex:sub(1,1)..hex:sub(1,1))/256, tonumber("0x"..hex:sub(2,2)..hex:sub(2,2))/256,
tonumber("0x"..hex:sub(3,3)..hex:sub(3,3))/256
else
-- #000000 format
return tonumber("0x"..hex:sub(1,2))/256, tonumber("0x"..hex:sub(3,4))/256, tonumber("0x"..hex:sub(5,6))/256
end
end
 
-- Allow usages of {{N/A}} cells
Line 47 ⟶ 34:
function TVRG.new(frame,args)
args = args or {}
local categories = ''
local title = mw.title.getCurrentTitle()
-- Variables
Line 61 ⟶ 50:
local numberargs = 0
for k,v in pairs(args) do
if (string.lower(v) == 'n/a') or (not string.match(k,'[^%d]+') and not string.match(v,'[^%d\%.]+')) then numberargs = numberargs + 1 end
end
 
-- Bar width
local barwidth
if numberargs < 20 then barwidth = 8
elseif numberargs >= 20 and numberargs < 50 then barwidth = 7
elseif numberargs >= 50 and numberargs < 80 then barwidth = 6
elseif numberargs >= 80 then barwidth = 5
end
-- Basis parameters
timeline = timeline .. "ImageSize = width:" .. (args.width or 1000) .. " height:" .. (args.height or 300) .. "\n"
timeline = timeline .. "PlotArea = left:50 bottom:70 top:20 right:50\n"
timeline = timeline .. "AlignBars = justify\n"
timeline = timeline .. "Colors =\n"
timeline = timeline .. " id:gray value:gray(0.7)\n"
-- Determine number of seasons
local num_seasons = -1
Line 88 ⟶ 61:
end
end
if num_seasons < 1 then
num_seasons = 1
end
 
-- Determine number of episodes and subtract averages if included (they should be equal to the number of seasons)
local num_episodes
if average == 1 then
num_episodes = numberargs-num_seasons
else
num_episodes = numberargs
end
 
-- Bar and graph width
local barwidth
if args.bar_width then barwidth = args.bar_width
-- Colour and legend variables
elseif num_episodes >= 120 then barwidth = 6
local season = 1
elseif num_episodes >= 100 then barwidth = 7
for season = 1,num_seasons do
elseif num_episodes >= 80 then barwidth = 8
local r,g,b = TVRG.hex2rgb(args['color' .. season] or '#006600')
elseif num_episodes >= 50 then barwidth = 9
elseif num_episodes >= 20 then barwidth = 10
local GraphLegend = season_title .. " " .. season
else barwidth = 11
if args["legend" .. season] then
local legendKey = string.sub(args["legend" .. season], 0, 1)
if type(tonumber(legendKey)) == "number" then
GraphLegend = season_title .. " " .. args["legend" .. season]
else
GraphLegend = args["legend" .. season]
end
end
timeline = timeline .. " id:season" .. season .. " value:rgb("..r..","..g..","..b..") " ..
(args.hidelegend == nil and "legend:" .. string.gsub(string.gsub(GraphLegend, ' ', '_'), "''(.-)''", '%1') or '') .. "\n"
season = season + 1
end
 
Line 126 ⟶ 102:
end
end
local is_singular = num_episodes == 1
 
-- FurtherBasis parameters, with rounded-up viewer figures as maximum period
timeline = timeline .. "\nImageSize = width:" .. (is_singular and 200 or 'auto') .. " height:"..(args.height or 500).. (is_singular and '' or " barincrement:"..(barwidth+(num_episodes == 2 and 16 or 4))).."\n"
timeline = timeline .. "DateFormat = x.y\n"
timeline = timeline .. "Period \nPlotArea = fromleft:050 tillbottom:"50 ..top:10 math.ceil(maxviewers) .. "right:100\n"
timeline = timeline .. "TimeAxis \nAlignbars = orientation:verticaljustify\n"
timeline = timeline .. "ScaleMajor\nPeriod = gridcolorfrom:gray0 incrementtill:" .. 10^math.ceil(math.log10(maxviewers)-math.log10(15)) .. " start:0\n"
timeline = timeline .. (args.hidelegend == nil and "Legend \nTimeAxis = orientation:horizontalvertical format:y\n" or "")
-- Colors
-- Interval parameter set to prevent overlapping bars
timeline = timeline .. "\nColors =\n"
local bar = 1
if args.intervals then
for season = 1,num_seasons do
timeline = timeline .. "BarData =\n"
args["color" .. season] = args["color" .. season] or '#CCCCFF'
for k,v in pairs(args) do
hex = args["color" .. season]:gsub("#","")
if string.lower(v) == 'n/a' then v = '' end
if #hex == 3 then
if tonumber(k) ~= nil and (tonumber(v) ~= nil or v == '') and (average == 0 or (average == 1 and args[k+1] ~= '-' and args[k+1] ~= nil)) then
-- If it's 3 hex chars then make it six instead
timeline = timeline .. " bar:"..bar.." text:"..((bar == 1 or bar % args.intervals == 0) and bar or '&nbsp;').."\n"
hex = hex:sub(1,1) .. hex:sub(1,1) .. hex:sub(2,2) .. hex:sub(2,2) .. hex:sub(3,3) .. hex:sub(3,3)
bar = bar + 1
end
end
rgbR = tonumber("0x"..hex:sub(1,2))/256
rgbG = tonumber("0x"..hex:sub(3,4))/256
rgbB = tonumber("0x"..hex:sub(5,6))/256
local legend = season_title.."_"..(args["legend" .. season] and args["legend" .. season] or season )
timeline = timeline .. "\n id:season"..season.." value:rgb("..rgbR..", "..rgbG..", "..rgbB..") legend:"..legend:gsub(" ", "_").."\n"
end
timeline = timeline .. "\n id:bars value:gray(0.95)"
timeline = timeline .. "\nLegend = orientation:vertical position:right\n"
timeline = timeline .. "\nBackgroundColors = bars:bars\n"
timeline = timeline .. "\nScaleMajor = unit:year increment:"..(multiple == 'thousands' and 100 or 1).." start:0\n"
timeline = timeline .. "\nScaleMinor = unit:year increment:"..(multiple == 'thousands' and 100 or 1).." start:0\n"
 
local x_intervals = args.x_intervals or (num_episodes >= 80 and 2 or 1)
-- Plot data
 
timeline = timeline .. "PlotData =\n"
timeline = timeline .. " width:" .. (args.bar_width or barwidth) .. "\nBarData=\n"
for episode = 1,num_episodes do
episodetext = ((episode % x_intervals == 0) and episode or "")
timeline = timeline .. "\n bar:"..episode.." text:"..episodetext.."\n"
end
-- Add bars to timeline, one per viewer figure
Line 155 ⟶ 147:
local season = 0
local thisseason = 0
local counted_episodes = 0
timeline = timeline .. "\nPlotData=\n"
for k,v in pairs(args) do
timeline = timeline .. "\n width:"..barwidth.." textcolor:black align:left anchor:from shift:(10,-4)\n"
for k,v in ipairs(args) do
if string.lower(v) == 'n/a' then v = '' end
if tonumber(k) ~= nil then
if v == '-' then
-- Hyphen means new season, so change season colour
season = season + 1
 
-- Determine highest number of episodescounted_episodes in a season
if thisseason > longestseason then
longestseason = thisseason
end
thisseason = 0
elseif average == 0 or (average == 1 and args[k+1] ~= '-' and args[k+1] ~= nil) then
-- Include white/black bar to act as border
local black_cr = contrast_ratio{args['color' .. season], 'black', ['error'] = 0}
local white_cr = contrast_ratio{'white', args['color' .. season], ['error'] = 0}
local bgrnd_cr = (black_cr > white_cr and 'black' or 'gray')
timeline = timeline .. " mark:(line," .. bgrnd_cr .. ")\n"
timeline = timeline .. " color:" .. bgrnd_cr .. "\n"
timeline = timeline .. " bar:" .. bar .. " width:" .. ((args.bar_width or barwidth)+2) .. " from:start till:" .. (v ~= '' and v or 'start') .. "\n"
-- Include bar for viewer figure, do not include if averages are included and the next parameter is a new season marker
timeline = timeline .. " color:season" .. season .. "\n"
timeline = timeline .. " bar:" .. bar .. " from:start till:" .. (v ~= '' and v or 'start') .. "\n"
-- Increment tracking variables
thisseason = thisseason + 1
bar = bar + 1
end
thisseason = 0
elseif average == 0 or (average == 1 and args[k+1] ~= '-' and args[k+1] ~= nil) then
-- Include bar for viewer figure, do not include if averages are included and the next parameter is a new season marker
timeline = timeline .. "\n bar:"..bar.." from:0 till:"..(v ~= '' and v or 0).." color:season"..season.."\n"
-- Increment tracking variables
counted_episodes = counted_episodes + 1
thisseason = thisseason + 1
bar = bar + 1
end
end
Line 197 ⟶ 183:
if args.country ~= nil and args.country ~= '' then
if args.country == "U.S." or args.country == "US" or args.country == "United States" then countryDisplayUS = 'U.S.'
elseif args.country == "U.K." or args.country == "UK" or args.country == "United Kingdom" then countryDisplayUK = 'U.K.UK'
else countryDisplayOther = args.country end
end
end
timeline = timeline .. "TextData =\n"
timeline = timeline .. " pos:(" .. ((args.width or 1000)/2-18) .. ",45) textcolor:black fontsize:S text:Episode\n"
timeline = timeline .. " pos:(10," .. ((args.height or 300)-10) .. ") textcolor:black fontsize:S text:" .. ((countryDisplayUS or countryDisplayUK or countryDisplayOther) or "") .. ((countryDisplayUS or countryDisplayUK or countryDisplayOther) and " v" or "V") .. "iewers (" .. multiple .. ")\n"
-- If there's a title, add it with the viewers caption, else just display the viewers caption by itself
if args.title ~= nil and args.title ~= '' then
root:wikitext("'''''" .. args.title .. "''" .. "&#8202;" .. ": " .. ((countryDisplayUS or countryDisplayUK or countryDisplayOther) or "") .. ((countryDisplayUS or countryDisplayUK or countryDisplayOther) and " v" or "V") .. "iewers per episode (" .. multiple .. ")'''"):css('margin-top', '1em')
root:wikitext("'''''" .. args.title .. "''" .. frame:expandTemplate{ title = 'hsp' } ..
else
": " .. ((countryDisplayUS or countryDisplayUK or countryDisplayOther) or "") .. ((countryDisplayUS or countryDisplayUK or countryDisplayOther) and " v" or "V") .. "iewers per episode (" .. multiple .. ")'''")
root:wikitext("'''Viewers per episode (" .. multiple .. ")'''"):css('margin-top', '1em')
end
root:tag('div'):css('clear','both')
-- Add timeline to div
if args.no_graph == nil then
if num_episodes > 100 then
root:tag('div'):wikitext("Too many episodes to display graph (maximum 100).")
if title.namespace == 0 then
categories = categories .. '[[Category:Articles using Template:Television ratings graph with excessive figures]]'
end
else
timelineBase = frame:preprocess("<timeline>"..timeline.."</timeline>")
root:wikitext("'''Viewers per episode (" .. multiple .. ")'''")
root:node(timelineBase)
root:tag('div'):css('clear','both')
end
 
-- Add timeline to div
if args.nograph == nil then
root:node(frame:extensionTag('timeline', timeline))
end
-- Create ratings table
if args.notableno_table == nil then
local rtable = mw.html.create('table')
:addClass('wikitable')
Line 227 ⟶ 218:
local row = rtable:tag('tr')
row:tag('th'):wikitext(season_title)
:attr('scope','col')
:attr('colspan','2')
:attr('rowspan','2')
:css('padding-left', '1em.8em')
:css('padding-right', '1em.8em')
row:tag('th')
:attr('scope','colgroup')
:attr('colspan',longestseason)
:wikitext("Episode number")
:css('padding-left', '1em.8em')
:css('padding-right', '1em.8em')
-- Average column
Line 244 ⟶ 237:
:attr('rowspan','2')
:wikitext("Average")
:css('padding-left', '1em.8em')
:css('padding-right', '1em.8em')
end
 
Line 267 ⟶ 260:
-- Spanning empty cells with {{N/A}}
if thisseason < longestseason then
row:node(TVRG.NACell(frame,"N/A"):attr('colspan',longestseason-thisseason))
end
Line 274 ⟶ 267:
if v ~= '' then
row:tag('td'):wikitext(args[k+1] ~= nil and args[k-1] or v)
:css('background-color', 'lightyellow')
else
row:node(TVRG.NACell(frame,"TBD"))
Line 288 ⟶ 280:
row:tag('th')
:css('background-color', args['color' .. season])
:css('width','14px')
:css('padding','0')
row:tag('th')
Line 313 ⟶ 307:
-- Finish by checking if final row needs {{N/A}} cells
if average == 0 and thisseason < longestseason then
row:node(TVRG.NACell(frame,"N/A"):attr('colspan',longestseason-thisseason))
end
-- Add table to div root and return
root:node(rtable)
root:tag('div'):css('clear','both')
end
local spancurrent_monthyear = mwos.html.createdate("%B 'span' %Y")
local span = mw.html.create('span'):wikitext(frame:expandTemplate{title='Citation needed', args={date=current_monthyear}})
span:css( 'color', 'red' )
:wikitext(frame:expandTemplate{ title='dummy reference', args={ '[[Wikipedia:Citation needed|citation needed]]', txtital = 'y' } })
if countryDisplayUS then
root:wikitext("<small>Audience measurement performed by [[Nielsen Media Research]].</small>" .. (args.refs ~= '' and args.refs or tostring(span)))
elseif countryDisplayUK then
root:wikitext("<small>Audience measurement performed by [[Broadcasters' Audience Research Board]].</small>" .. (args.refs ~= '' and args.refs or tostring(span)))
else
root:wikitext("<small>Source: </small>" .. (args.refs ~= '' and args.refs or tostring(span)))
end
return tostring(root) .. categories
end