モジュール:PieChartTSV
ナビゲーションに移動
検索に移動
local p = {}
function round(n) -- nを四捨五入
return math.floor(n+0.5)
end
function yesno(v) -- ユーザ指定 Yes/No、T/F を判定
if v == 1 or v == 1.0 then return true end
if type(v) ~= 'string' then return false end
v = v:lower():gsub('%s+', '') -- 全て小文字にした上で空白文字除去
local yes_tbl = {'1', 't', 'true', 'y', 'yes'}
for i, yes_disc in ipairs(yes_tbl) do
if v == yes_disc then return true end
end
return false
end
function p.error(message)
return '<strong class="error">エラー:' ..message ..'</strong>'
end
function p.main(frame)
local args = require('Module:Arguments').getArgs(frame, {
wrappers = 'Template:PieChartTSV', -- trim = false, removeBlanks = false
})
local tsv = args.tsv or args[1] or ''
-- 引数perDirect ... Yes: データを%として直接入力する, No: データの総和を100%とみなす
local inputPer = yesno(args.inputPer)
-- 引数caption ... 円グラフ下に表示する説明文
local caption = args.caption or ''
-- 引数other ... 凡例に「その他」を表示する
local other = args.other or ''
local body = '{{Pie chart'
-- キャプション挿入
if #caption ~= 0 then body = body..'|caption='..caption end
-- 凡例「その他」挿入
if #other ~= 0 then body = body..'|other='..other end
-- csvを一旦2次元配列にする
local tbl = require('Module:TSV').toArr2D({tsv})
local hue_pts = {240, 0, 120, 50, 290, 190, 60} -- HSL空間のHが辿る各頂点
local lights = {50, 75, 35} -- HSL空間のL
-- データの総和を求める
local sum = 0;
if not inputPer then
for i, row in ipairs(tbl) do sum = sum + row[2] end
end
-- {{Pie chart}}テンプレに沿ったパラメータ生成
for i, row in ipairs(tbl) do
local hue_idx = (i-1) % #hue_pts + 1
local light_idx = (i-1) % #lights + 1
local color = #row >= 3 and row[3] or 'hsl('..hue_pts[hue_idx]..'deg 100% '..lights[light_idx]..'%)'
local value = (inputPer or sum == 0) and row[2] or round(row[2] / sum * 10000) / 100
body = body..'\n|label'..i..'='..row[1]
body = body..'|value'..i..'='..value
body = body..'|color'..i..'='..color
end
body = body..'\n}}'
return frame:preprocess(body)
end
return p