モジュール:PieChartTSV

出典: 謎の百科事典もどき『エンペディア(Enpedia)』
ナビゲーションに移動 検索に移動

※ここに呼び出す説明文 『 モジュール:PieChartTSV/doc 』 が作成されていません。

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