Moduli:CS1 charts
Pamja
--[[--------------------------< C S 1 _ C H A R T S >----------------------------------------------------------
]]
require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;
local cfg = mw.loadData ('Moduli:Citation/CS1/Configuration');
local data = mw.loadData ('Moduli:CS1_charts/data');
local page_title = mw.title.getCurrentTitle().prefixedText; -- namespace and name
--[[--------------------------< S U B C A T _ D A T A _ F E T C H >--------------------------------------------
return the total number of pages, files, and subcats in a named category's (<cat>) subcategories; when no subcats
listed in <subcats_t>, returns 0
]]
local function subcat_data_fetch (cat)
local page_count = 0;
if data.subcats_t[cat] then -- if this category has listed subcats
local pages_in_cat_t = {};
for i, subcat in ipairs (data.subcats_t[cat]) do -- for each subcat
pages_in_cat_t = mw.site.stats.pagesInCategory (subcat, '*'); -- get the various counts and
page_count = page_count + pages_in_cat_t.files + pages_in_cat_t.pages + pages_in_cat_t.subcats; -- tally
end
end
return page_count;
end
--[[--------------------------< B A R _ C H A R T _ C R E A T E >----------------------------------------------
]]
local function bar_chart_create (frame)
local page_counts_t = {};
local subcat_counts_t = {};
local cat_names_t = {};
local cats_t = {};
local bar_chart_x_legends;
if 'error' == frame.args[1] then
cats_t = data.error_cats_t;
bar_chart_x_legends = (page_title == ('Kategoria:' .. data.bar_chart_error_cat_title)) and data.bar_chart_error_cat_title or table.concat ({'[[:Kategoria:', data.bar_chart_error_cat_title, '|', data.bar_chart_error_cat_title, ']]'});
else
cats_t = data.maint_cats_t;
bar_chart_x_legends = (page_title == ('Kategoria:' .. data.bar_chart_maint_cat_title)) and data.bar_chart_maint_cat_title or table.concat ({'[[:Kategoria:', data.bar_chart_maint_cat_title, '|', data.bar_chart_maint_cat_title, ']]'});
end
for i, cat in ipairs (cats_t) do
local pages_in_cat_t = {};
if cfg.error_conditions[cat] then
cat = cfg.error_conditions[cat].category; -- fetch the category name from Module:Citation/CS1/Configuration; use plaintext cat else
end
cat_names_t[i] = cat; -- save a copy of the category name
pages_in_cat_t = mw.site.stats.pagesInCategory (cat, '*'); -- get the table of counts
if 0 ~= subcat_data_fetch (cat) then
page_counts_t[i] = pages_in_cat_t.files + pages_in_cat_t.pages + subcat_data_fetch (cat); -- don't include pages_in_cat_t.subcats in tally
subcat_counts_t[i] = pages_in_cat_t.subcats; -- but remember for later annotation
else
page_counts_t[i] = pages_in_cat_t.files + pages_in_cat_t.pages; -- there are no subcats so don't bother
end
end
local out = {'chart', 'bar chart'}; -- init for #invoke parser function call with Module:Chart and function barChart()
out.delimiter = data.bar_chart_delimiter; -- |delimiter=
out['units suffix'] = data.bar_chart_units_suffix; -- |units suffix=
local tail;
local group_names_t = {};
local colors_t = {};
local j = 0; -- indexer for cats that that are not empty
for i, v in ipairs (cats_t) do
if 0 ~= page_counts_t[i] then
j = j + 1; -- bump the indexer
out['group ' .. j] = page_counts_t[i]; -- add |group 1= to |group n= pararameters
if subcat_counts_t[i] then -- if this cat has subcats
tail = table.concat ({' faqe nga ', subcat_counts_t[i], ' nënkategori'}) -- modify the group name tail
else -- here when no subcats
tail = ' faqe'; -- standard group name tail
end
out['tooltip ' .. j] = table.concat ({cat_names_t[i], ' ', page_counts_t[i], tail}); -- add |tooltip 1= to |tooltip n= pararameters
table.insert (group_names_t, table.concat ({'[[:Kategoria:', cat_names_t[i], '|', cat_names_t[i], ']] ', page_counts_t[i], tail}));
if 64 == j then
break;
end
end
end
out['group names'] = table.concat (group_names_t, data.bar_chart_delimiter); -- add |group names= parameter
for i, color in ipairs (data.bar_chart_colors_t) do -- make a local table for concatenation; necessary because <data.bar_chart_colors_t> is a metatable
colors_t[i] = color;
if i == j then -- no more than we need
break;
end
end
out['colors'] = table.concat (colors_t, data.bar_chart_delimiter, 1, j); -- add |colors= parameter
out['x legends'] = table.concat ({bar_chart_x_legends, ' (', #page_counts_t-j, ' nga ', #cats_t, ' kategori bosh janë fshehur)'}); -- add |x legends=
return frame:callParserFunction ('#invoke', out); -- {{#invoke:chart|bar chart|args...}}
end
--[[--------------------------< P I E _ C H A R T _ C R E A T E >----------------------------------------------
]]
local function pie_chart_create (frame)
local args_t = getArgs (frame);
local raw = {}; -- count, legend, and category extracted from category
local slices = {}; -- formatted output suitable for [[Module:Chart]] |slices= parameter
local link = true; -- slices are linked
local delimiter = ';'; -- default is ':' but catagory names have colons so use semicolon
local cats_t = {};
if 'lang' == args_t[1] then
cats_t = data.language_cats_t;
elseif 'script' == args_t[1] then
cats_t = data.script_lang_cats_t;
else
cats_t = data.language_cats_t;
end
for _, cat in ipairs (cats_t) do -- spin through category names and construct raw data for chart
local t = {}
table.insert (t, mw.site.stats.pagesInCategory (cat, 'pages'));
table.insert (t, cat and cat:match (args_t.pattern or '.*') or cat); -- extract legend; use cat name if pattern not provided
table.insert (raw, t); -- save this
end
if 0==#raw then
return string.format ('(%s%s%s%s%s)', -1, delimiter, 'Gabim: Grafiku nuk ka asnjë pjesë të përcaktuar', delimiter, '#d33');
end
for i, v in ipairs (raw) do -- look for duplicate names
for j=i+1, #raw do
if raw[i][2] == raw[j][2] then
return string.format ('(%s%s%s %s%s%s)', -1, delimiter, 'Gabim: Grafiku ka disa pjesë me emra të njëjta', raw[i][2], delimiter, '#d33');
end
end
end
local function comp (a, b) -- used in following table.sort()
if a[1] == b[1] then -- when same do
return a[2] < b[2]; -- ascending alpha sort on name
end
return tonumber (a[1]) > tonumber(b[1]); -- descending sort
end
table.sort (raw, comp); -- descending sort
local non_empty_count = 0; -- count of categories with at least one page
local empty_count = 0;
local other_pages_tally = 0; -- tally of pages not included in the first 25 slices
for i, t in ipairs (raw) do
if 26 > i and 0 ~= t[1] then -- slices 1 - 25 separately in the chart (as long as they have something in them)
if link then -- build a linked slice
table.insert (slices, string.format ('(%s%s%s%s%s[[:Category:%s]])', t[1], delimiter, t[2], delimiter, delimiter, t[2]));
else -- build an unlinked slice
table.insert (slices, string.format ('(%s%s%s)', t[1], delimiter, t[2]));
end
elseif 0 ~= t[1] then -- would-be slices 26+
non_empty_count = non_empty_count + 1; -- count the number of non-empty cats
if t[1] then -- in case t[1] is nil for whatever reason; shouldn't be; TODO: do we need this?
other_pages_tally = other_pages_tally + t[1]; -- sum the number of pages in these non-empty cats
end
else
empty_count = empty_count + 1; -- count the number of empty cats
end
end
if 0 == #slices then -- nothing in slices{}
return string.format ('(%s%s%s%s%s)', -1, delimiter, 'Gabim: Vlera e të gjitha pjesëve të përcaktuara është 0', delimiter, '#d33');
end
if 0 ~= non_empty_count or 0 ~= empty_count then -- 26th slice
table.insert (slices, string.format ('(%s%s%s kategori të tjera + %s kategori bosh)', other_pages_tally, delimiter, non_empty_count, empty_count));
end
local out = {'chart', 'pie chart'}; -- init for #invoke parser function call with Module:Chart and function pieChart()
out['delimiter'] = ';';
out['units suffix'] = '_faqe';
out['percent'] = 'true';
out['slices'] = table.concat (slices, '\n');
return frame:callParserFunction ('#invoke', out); -- {{#invoke:chart|bar chart|args...}}
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
bar_chart_create = bar_chart_create,
pie_chart_create = pie_chart_create,
}