モノトーンの伝説日記

Apex Legends, Splatoon, Programming, and so on...

MediaWiki で使える Lua で書いた tableutil の話。

 結構いい感じだと思います。

1. table と graph を合わせた表

 Excel みたいな、cell の背景にを書いて数値と文字を同時に表示するっていうそういう技。

f:id:mntone:20210818013949p:plain
こういうやつ

 完全に CSS で、table 自体の構造まで変えてグラフにする「Charts.css」ってやつもある。これは table としては使えないけど、検索エンジンのロボットにはテーブルで認識させるっていうセマンティックなもの。コード自体もなかなか面白いので読んでみるとよいかも。カスタムプロパティー (--*) を使って書かれていて面白い。ただ、table 自体のコードにちょっと手を加えないといけないから、個人的にどっちもどっちだなーって思ったやつ。

chartscss.org

2. Lua で生成

 実は一作品目を書いてたんですが、それは没。ほぼ 1 つのクラスに機能を集約させるみたいなスパゲティーだったんですが、クラス化して機能を整理することできれいになった感じ。その分、当時実装してた LineRange っていう 2 値の値の棒グラフを生成するものを新実装にはまだ追加できていませんが。

 基本的にユーザーサイドで用意するデータとして、

  1. テーブルのためのメタデータ
    (1列目は RankCell で、データ index を使用、とか…)
  2. テーブルを生成するためのデータセット
    (table in table 形式)

っていう簡単な感じ。

 未来の自分に向けて一応ドキュメント書いておきます。

3. ドキュメント

 コード。MIT ライセンスです。

https://mntone.minibird.jp/aw/Module:Utility/TableUtil

3.1 [Class] Cell (root)

 すべてのメタデータの根源となるクラス。データを扱わない。純粋にセルの管理だけ行う。

Cell.new(name, opts)
引数 説明
name 項目名。ヘッダーセルに表示される内容
opts.attributes セルに対する属性指定。data-sort-value といった値を追加するのに使う。
opts.cellClass セルに付与するクラス
opts.headerClass ヘッダーに付与するクラス
opts.headerColspan ヘッダーの結合数。1 は結合なし、0 以下はヘッダーを出力しない。
opts.headerStyle ヘッダーの追加スタイル。min-widthmax-width などグラフのための幅を確保するために使用。

3.2 [Class] ValueCell: Cell

 1 つのデータを扱うことのできるセル。データを表示する以外はない。

ValueCell.new(name, dataIndex, opts)

 継承元の引数説明は省略。

引数 説明
dataIndex データが格納されているインデックス。型は number or string
opts.format データのフォーマット関数。表示のみに利用され、ソートのための属性 data-sort-value は生の値を使う

3.3 [Class] RankCell: Cell

 順位セル。順位を管理、表示する。

RankCell.new(name, dataIndex, descending)

 継承元の引数説明は省略。

引数 説明
dataIndex データが格納されているインデックス。型は number または string
descending 順位を降順に表示するか。

3.4 [Class] LineCell: Cell

 棒グラフセル。棒グラフを表示する機能のみもつ。

付与されるクラス
  • st-line
  • st-line-h%d: 高さ指定。デフォルト値の 1.2 なら st-line-h12
LineCell.new(name, dataIndex, descending)

 継承元の引数説明は省略。

引数 説明
dataIndex データが格納されているインデックス。型は number または string
opts.colorStops セルの色指定。型は string または tablestring のときは単色の棒グラフ、table のときは [1] から [2] へのグラデーション。
デフォルト値 #A7D7F9
opts.height 棒グラフの高さ指定。
デフォルト値 1.2
opts.minimumValue データの最小値。
デフォルト値 0
opts.maximumRate データの最大値に対する割合。
デフォルト値 1.05
補足説明

 グラフは (value - min) / (1.05 * (max - min)) で描画される。

 この辺り扱いづらいので将来的に改変するかも。具体的な値を設定できたりとか…?

 理想としては 5400 という値が存在すれば、4 等分するグリッドを表示する場合、6000 に最大値を設定できると、1500 間隔でグリッドが表示されるので better。実装めんどくさいし後回し。

3.5 [Class] LineValueCell: LineCell

 棒グラフセルに ValueCell と同じようなフォーマット機能によるデータ表示機能を追加したもの。

 LineCell からの自動生成となり、内部型名は value+line となる。

3.6 [Function] specifyUICell

 特化した UI を作るためのセル。内部型名は ui+[指定名]

specifyUICell(klasstype, renderFunction, propNames)

 継承元の引数説明は省略。

引数 説明
klasstype お好きな内部型名。
renderFunction(that, row, dataset, i, datainfo) セルを描画する関数。スーパークラスの関数 __cell__render を呼び出せる。
propNames 追加のプロパティー名を指定する。任意の UICell を初期化する際、opts.~ をオブジェクト自体がコピーしておく。

3.7 [Function] createTable

 テーブル生成するやつ。

createTable(dataset, metadata, opts)

 継承元の引数説明は省略。

引数 説明
dataset データ。
metadata 上記で説明したセルの table が入る。
opts.tableClass 追加のクラス名を指定する。

4. サンプルコード

 最初のスクショを生成するのに使ってたコード。

 ただし、CSS のカスタムはめっちゃしてあるので、通常の MediaWiki で表示しても同じ表示にはならないです。

function __test()
  local dataset = {{ 45, 110 }, { 40, 60 }, { 40, 120 }, { 50, 90 }}
  local metadata = {
    tableutil.RankCell.new('', 1),
    tableutil.ValueCell.new('Value', 1),
    tableutil.LineCell.new('Line', 1),
    tableutil.LineCell.new('LineGradient', 1, { colorStops = { '#F8B3BC', '#F26D7D' }, height = 1.4 }),
    tableutil.LineValueCell.new('LineValue', 2, { cellClass = 'st-textshadow' }),
  }
  local node = tableutil.createTable(dataset, metadata)
  return tostring(node)
end

 カスタム UI クラスのコード。ただリンク構文として [[~]] とします。

local tableutil = require('Module:Utility/TableUtil')

-- =========================
-- type: LinkCell: Cell (UI)
-- =========================
local __TableUtil__LinkCell = tableutil.specifyUICell('link', function(that, row, dataset, i, datainfo)
    local value = dataset[that.dataIndex]
    local text = string.format('[[%s]]', value)
    local cell = that:__cell__render(row, dataset, i, datainfo):wikitext(text)
    return cell
end)
tableutil.LinkCell = __TableUtil__LinkCell

まとめ

 説明雑になりましたがこんな感じで。

 適宜カスタムしてください。あと、今後もコード改変はしばらく続くと思うので、ここにある簡易ドキュメントは将来のバージョンで動かなくなることがあるかもしれません。

 もし誰か使う人がいれば、程度で記事を用意したので、深い意味はないです。MediaWikiLua が使えるので、コード書けば書くほどリッチになる(笑)っていう、割とガチ開発しちゃう奴ですよね。

 MediaWiki 普通に使いやすいから好きですね。正直、レンタルサーバMediaWiki を使うために契約してるまでありますからねぇ…

 最後に、カスタム UI クラス集へのリンクも貼っておきます。専用機能を使っている部分が多いので、参考になるか微妙ですが。まあこのクラス群が汚いのは認めます。でもまあ汎用性ないし、別にいらなくなったら捨てるレベルのコードには投資しなくていいでしょう(ぁ

https://mntone.minibird.jp/aw/Module:Utility/TableUtil/Apex