Essa é uma versão alternativa de Módulo:Graph. Ele cria gráficos (
{{gráfico}}
) usando apenas CSS. Algumas funções adicionais estão disponíveis. Verifique Wikinotícias:Redação/Gráficos quebrados (05/06/2023) para mais detalhes.Esta documentação se encontra na subpágina Módulo:Graph 2/doc ( | histórico)
Por favor inclua as categorias à subpágina /doc. Subpáginas deste módulo.
Por favor inclua as categorias à subpágina /doc. Subpáginas deste módulo.
local p = {}
--gráfico de barras
function p.rect(frame)
local width = frame.args.width or ''
local height = frame.args.height or ''
local y = frame.args.y or ''
local colors = frame.args.colors or ''
local fontcolor = frame.args.fontcolor or ''
local html = mw.html.create()
local container = html:tag('div')
container:css('width', width .. 'px')
container:css('height', height .. 'px')
container:css('display', 'flex')
container:css('justify-content', 'space-between')
container:css('align-items', 'flex-end')
container:css('color', fontcolor)
local yValues = mw.text.split(y, ',')
local dataSize = #yValues
local maxY = 0
for i = 1, dataSize do
local yValue = tonumber(yValues[i]) or 0
maxY = math.max(maxY, yValue)
end
for i = 1, dataSize do
local bar = container:tag('div')
bar:css('min-width', '30px')
bar:css('margin', '.1em')
bar:css('height', (yValues[i] * 100 / maxY) .. '%')
bar:css('background', colors)
local text = mw.html.create('span')
text:wikitext(yValues[i])
bar:wikitext(tostring(text))
end
return tostring(html)
end
--gráfico de área
function p.area(frame)
local args = frame.args
local width = args.width or ''
local height = args.height or ''
local opacity = args.opacity or ''
local colors = args.colors or ''
local wValues = args.w and mw.text.split(args.w, ',') or {}
local yValues = args.y and mw.text.split(args.y, ',') or {}
local maxW = math.max(unpack(wValues))
local scale = 100 / maxW
local html = mw.html.create()
local table = html:tag('table')
table:attr('style', 'border-collapse: collapse;')
local row = table:tag('tr')
local numValues = #yValues
if numValues > 1 then
for i = 1, numValues - 1 do
local y = yValues[i]
local w = wValues[i]
local invertedY = tostring(100 - tonumber(y) * scale)
local invertedY2 = tostring(100 - tonumber(yValues[i + 1]) * scale)
row:tag('td')
:css('min-width', width .. 'px')
:css('height', height .. 'px')
:css('opacity', opacity)
:css('background', colors)
:css('clip-path', 'polygon(0% ' .. invertedY .. '%, 100% ' .. invertedY2 .. '%, 100% 100%, 0% 100%)')
end
end
return tostring(html)
end
--gráfico circular
function p.pie(frame)
local width = frame.args.width or ''
local height = frame.args.height or ''
local y = frame.args.y or ''
local colors = frame.args.colors or ''
local html = mw.html.create()
local container = html:tag('div')
container:css('width', width .. 'px')
container:css('height', height .. 'px')
container:css('border-radius', '50%')
container:css('background', 'conic-gradient(' .. generateConicGradient(y, colors) .. ')')
container:css('display', 'block')
return tostring(html)
end
function generateConicGradient(y, colors)
local yValues = mw.text.split(y, ',')
local colorValues = mw.text.split(colors, ',')
local dataSize = math.min(#yValues, #colorValues)
local total = 0
for i = 1, dataSize do
total = total + (tonumber(yValues[i]) or 0)
end
local anglePerUnit = 360 / total
local conicGradient = ''
local accumulatedAngle = 0
for i = 1, dataSize do
local angle = (tonumber(yValues[i]) or 0) * anglePerUnit
local endAngle = accumulatedAngle + angle
conicGradient = conicGradient .. colorValues[i] .. ' ' .. accumulatedAngle .. 'deg ' .. endAngle .. 'deg, '
accumulatedAngle = endAngle
end
conicGradient = conicGradient:sub(1, -3)
return conicGradient
end
--gráfico de linha
function p.line(frame)
local args = frame.args
local width = args.width or ''
local height = args.height or ''
local opacity = args.opacity or ''
local colors = args.colors or ''
local wValues = args.w and mw.text.split(args.w, ',') or {}
local yValues = args.y and mw.text.split(args.y, ',') or {}
local maxW = math.max(unpack(wValues))
local scale = 100 / maxW
local html = mw.html.create()
local table = html:tag('table')
table:attr('style', 'border-collapse: collapse;')
local row = table:tag('tr')
local numValues = #yValues
if numValues > 1 then
for i = 1, numValues - 1 do
local y = yValues[i]
local w = wValues[i]
local invertedY = tostring(100 - tonumber(y) * scale)
local invertedY2 = tostring(100 - tonumber(yValues[i + 1]) * scale)
local inverted3 = tostring(tonumber(invertedY) + 1)
local inverted4 = tostring(tonumber(invertedY2) + 1)
row:tag('td')
:css('min-width', width .. 'px')
:css('height', height .. 'px')
:css('opacity', opacity)
:css('background', colors)
:css('clip-path', 'polygon(0% ' .. invertedY .. '%, 100% ' .. invertedY2 .. '%, 100% ' .. inverted4 .. '%, 0% ' .. inverted3 .. '%)')
end
end
return tostring(html)
end
--legendas
function p.legenda(frame)
local args = frame.args
local xValues = args.x and mw.text.split(args.x, ",") or {}
local colors = args.colors and mw.text.split(args.colors, ",") or {}
local output = mw.html.create('table')
for i, x in ipairs(xValues) do
local color = colors[i] or ""
local row = output:tag('tr')
local th1 = row:tag('th')
th1:wikitext('<div style="width: 8px; height: 8px; background: ' .. color .. '; border-radius: 50%;"></div>')
row:tag('th'):css('white-space', 'nowrap'):wikitext(x)
end
return tostring(output)
end
--legendas com porcentagem
function p.conta(frame)
local args = frame.args
local xValues = args.x and mw.text.split(args.x, ",") or {}
local yValues = args.y and mw.text.split(args.y, ",") or {}
local colors = args.colors and mw.text.split(args.colors, ",") or {}
local total = 0
local output = mw.html.create('table')
for i, y in ipairs(yValues) do
total = total + tonumber(y)
end
for i, x in ipairs(xValues) do
local color = colors[i] or ""
local y = tonumber(yValues[i]) or 0
local percentage = total > 0 and y / total * 100 or 0
local row = output:tag('tr')
local th1 = row:tag('th')
th1:wikitext('<div style="width: 8px; height: 8px; background: ' .. color .. '; border-radius: 50%;"></div>')
row:tag('th'):css('white-space', 'nowrap')
:wikitext(x .. ' (' .. string.format("%.2f", percentage) .. '%)')
end
return tostring(output)
end
--quantos números
function p.quantos(frame)
local y = frame.args.y or ''
local yValues = mw.text.split(y, ',')
local dataSize = #yValues
return dataSize
end
--valores para coluna
function p.x(frame)
local width = frame.args.width or ''
local x = frame.args.x or ''
local html = mw.html.create()
local container = html:tag('div')
container:css('width', width .. 'px')
container:css('display', 'flex')
container:css('justify-content', 'space-between')
container:css('align-items', 'flex-end')
local xValues = mw.text.split(x, ',')
local dataSize = #xValues
for i = 1, dataSize do
local bar = container:tag('div')
bar:wikitext(xValues[i])
if i == 1 then
end
end
return tostring(html)
end
--números para lateral
function p.val(frame)
local x = frame.args.x or ''
local height = frame.args.height or ''
local values = mw.text.split(x, ',')
local formattedValues = {}
if #values >= 3 then
local min = math.min(unpack(values))
local max = math.max(unpack(values))
local middleIndex = math.ceil(#values / 2)
local middleValue = max / 2
local formattedMaxValue = '<div style="justify-content: flex-start; display: flex; flex-direction: column; height: ' .. tonumber(height) / 3 .. 'px">' .. max .. '</div>'
local formattedMiddleValue = '<div style="justify-content: center; display: flex; flex-direction: column; height: ' .. tonumber(height) / 3 .. 'px">' .. middleValue .. '</div>'
local formattedMinValue = '<div style="justify-content: flex-end; display: flex; flex-direction: column; height: ' .. tonumber(height) / 3 .. 'px">' .. min .. '</div>'
table.insert(formattedValues, formattedMaxValue)
table.insert(formattedValues, formattedMiddleValue)
table.insert(formattedValues, formattedMinValue)
end
local result = table.concat(formattedValues, ' ')
local finalResult = result
return finalResult
end
--valores inferiores
function p.vai(frame)
local x = frame.args.x or ''
local values = mw.text.split(x, ',')
local formattedValues = {}
if #values >= 3 then
local firstValue = values[1]
local middleValue = values[math.ceil(#values / 2)]
local lastValue = values[#values]
local formattedFirstValue = '<div style="text-align: left; width: 33%">' .. firstValue .. '</div>'
local formattedMiddleValue = '<div style="text-align: center; width: 33%">' .. middleValue .. '</div>'
local formattedLastValue = '<div style="text-align: right; width: 33%">' .. lastValue .. '</div>'
table.insert(formattedValues, formattedFirstValue)
table.insert(formattedValues, formattedMiddleValue)
table.insert(formattedValues, formattedLastValue)
end
local result = table.concat(formattedValues, ' ')
local finalResult = '<div style="display: flex;">' .. result .. '</div>'
return finalResult
end
return p