このままでは2023年がQiitaに1個も記事を書かないまま終わってしまうので最近やったSVG帳票について残しておく。
きっかけは開発中のWebサービスの帳票をどうすっぺと思って探してたらこの記事を見つけたこと。
https://zenn.dev/ttskch/articles/1f1572cfd2e375
フムフム、だよねーと思いながら読んだが例がPHPなのでVueでどうやるんだ?ってなった。
https://zenn.dev/ttskch/articles/8ee0eaaabf0657
npmモジュールまであるじゃん。これは試すしかない。しかし、
https://github.com/ttskch/svg-paper
GitリポジトリがPrivateなのかリンク切れ。探して見つけた。たぶん同じ人。
https://github.com/nakano-dskllc/svg-paper
ここまで揃ってたらやるしかない。
$ yarn add svg-paper
初めて使うFigmaでレイアウトを作ってみた。なかなかいい感じに作れる。FileMakerみたいにコマンドキーを押しながらドラッグして内側にあるものだけを複数選択というのはできないけど、IDをちゃんとつけて左側の一覧からコマンドキーを押しながらクリックしていけば前面にあろうがなかろうが飛び飛びで複数選択できる。グループ化(フレーム化?)した中身もマウスで選択しやすい。よくできててAdobeからこっちに移行してくる人もいて買収したがるのも納得(頓挫したみたいだけど)。SVGエクスポートでオプションが選べず悩んだが最終的にフレーム全体を選択した状態でエクスポートすればよいことがわかった(わかんねぇよ)。
レイアウトができたので次はVue側。適当に書いて試すがプレースホルダーが置き換わらない。何で?と悩んだがよく見ると.paperクラスを指定する必要があるみたい。できた。Documentちゃんと読もうね。
さて、文字の置き換え方法は(プレースホルダーの文字が切れると正常に機能しないのではみでてもいいのでレイアウトは広めに取る)わかった。位置合わせも(SVGレイアウトで中央や右寄せしてもうまくいかないのでレイアウトは全て左寄せにしておいてプログラムのadjustTextメソッドで行う)なんとかわかった。次はチェックボックスを使いたいんだけど...
どうやんのこれ?文字の置き換えだけじゃ無理じゃん。SVGのプロパティを変更するsetAttributeみたいなメソッドがいるんじゃないの。ということでリポジトリからcloneしてきてメソッドを追加してみた。動いた。
https://github.com/mackey66/svg-paper
具体的にはチェックボックスの枠とチェックを用意する。Vueで
.setAttribute('#checked1', 'display', this.printDmh.check01 ? 'inline' : 'none')
みたいな感じでデータに応じてチェックのdisplayプロパティを操作する。
これができたら文字色も変えられるね。異常値だったら赤くするみたいなの。
// Judgement
let judgement = 'paper'
for (let i = 1; i < n; i++) {
// High
if (parseFloat(this.results[4 + j * 4][i]) > parseFloat(this.results[2][i])) {
judgement += '.setAttribute("#day1_result_' + i + '", "fill", "red")'
}
if (parseFloat(this.results[5 + j * 4][i]) > parseFloat(this.results[2][i])) {
judgement += '.setAttribute("#day2_result_' + i + '", "fill", "red")'
}
if (parseFloat(this.results[6 + j * 4][i]) > parseFloat(this.results[2][i])) {
judgement += '.setAttribute("#day3_result_' + i + '", "fill", "red")'
}
if (parseFloat(this.results[7 + j * 4][i]) > parseFloat(this.results[2][i])) {
judgement += '.setAttribute("#day4_result_' + i + '", "fill", "red")'
}
// Low
if (parseFloat(this.results[4 + j * 4][i]) < parseFloat(this.results[1][i])) {
judgement += '.setAttribute("#day1_result_' + i + '", "fill", "blue")'
}
if (parseFloat(this.results[5 + j * 4][i]) < parseFloat(this.results[1][i])) {
judgement += '.setAttribute("#day2_result_' + i + '", "fill", "blue")'
}
if (parseFloat(this.results[6 + j * 4][i]) < parseFloat(this.results[1][i])) {
judgement += '.setAttribute("#day3_result_' + i + '", "fill", "blue")'
}
if (parseFloat(this.results[7 + j * 4][i]) < parseFloat(this.results[1][i])) {
judgement += '.setAttribute("#day4_result_' + i + '", "fill", "blue")'
}
}
eval(judgement)
というわけでこれが最近やったこと。
今年はがんばったな。来年はその成果がでていい年になりますように。