Tabulator 5.0 は当面諦めとく。.0 だからまぁあまり文句は言わんでおこう。
今回したいのは、多くの人にとっては大した話ではなくて、ワタシ的にはもちっと早く気付いておきたかった、ちぅ「考え方」の話、である。
最初に、一連の「声優世代表のおとも」なお題について、今一度モチベーションを繰り返しておく。
欲しいのは、テレビ朝日の番組「声優パーク建設計画VR部」内のコーナー「声優世代表を作ろう!」のおともに使える表。その際に、MS Excel などのワークシートで作業をするのでも悪くないのだけれど、そもそもが「データは手持ちでそれを表集計したいだけ」ならともかく、基礎情報の集積から始まる作業なのだから「どのみち Python のような高級言語の助けを借りたい、だったら「ワークシートで作業」に執着するよりは、望みの加工のほぼすべてを Python でやっちゃえばいいんだから、出力はリードオンリーな html でええやん、Tabulator が提供してくれる UI は使いやすいし」てことで、結果としてそのアプローチとして「Python で wikipedia をスクレイプして、その結果を Tabulator な html に仕立て上げる」とした、ということ。
html というのは無論本来は「インターネットの世界でお披露目するための道具」であり、特に http との結びつきが極めて強いわけね、つまり「クライアント/サーバモデルに従っているアプリケーションで使われる」ことが強く念頭に置かれている。そして、ブラウザの内蔵言語としてスタートした javascript も、それに基づく Tabulator も同じく。けれども、ユーザインターフェイスとしての表現とその記述の簡単さから、今まさにワタシがやってるように、「オフラインで使うデスクトップアプリケーションを簡単に作る」ためのインフラの選択肢の一つ、でもあるわけだね、html (+ javascript) は。
この、「オフラインとして」作る/使うのと、インターネット上で動く WEB アプリケーションとして作る/使うのとではやはりかなり大きな違いはあるのだけれど、「サーバは小人さんが作ってくれて動かしてくれているのでワタシはそれに頼るだけ」だとした場合は、実はクライアント側はオフラインのものよりも遥かに考えやすく、作りやすかったりもする。やはりあくまでも C/S アプリケーション向けなのだ、オフラインだけで使おうとするといろんなところで不都合にブチ当たる。
「サーバを介さない」アプローチが抱える一番の問題は、実に、「一枚岩になる」ことである。indexDB の話をした際に触れたような気もするが、要するに処理の分割がほぼ出来ない。たとえばインターネット検索エンジンを我々が使う際、クライアントとサーバは検索ワードに対する全結果を全て一気にやりとりするわけではなく、適当なサイズでちぎって、「もっと欲しけりゃ Next ページ押しやがれベイベぇ」と、クライアントとサーバの連携によって、処理データサイズをコントロールするということをしているわけだ。こういうことが、オフライン相手の場合は、ほぼ出来ない。(出来ないのはインフラ開発者の努力が欠けているからではなくて、これはセキュリティ上の理由。簡単にローカル PC にある資材を好き勝手にいじれる能力があってはいけないのだ、それが簡単に出来てしまったら、クレジットカード番号は盗まれ放題になる。)
すなわち html をオフラインで使う場合の一番の問題は、大きなデータを扱いたい場合、それは「全てを一気に」扱わなければならない、という点にある。かろうじて「ファイルを選択」ダイアログで選んでロード、を繰り返す、ということは出来るけれど、これはあまり嬉しくないだろう。
ここまでは概ね一般論の話。以降は、どちらかといえばワタシのマインドセットの話。というか「頭の切り替えの話」、だな。
その「オフラインなのか C/S なのか」で、基本的に脳内では完全にある種モード切り替えが起こるんだけれど、それがつまり「オフラインなのでどうせ一枚岩なんだから」という諦めからスタートしてしまう、てことかな。
そもそも C/S として作る場合は、Tabulator の用法も必然的に「Tabulator の初期セットアプ」と「データ投入」は、コーディングとしてだけでなく、思考そのものが最初から完全に分離する。つまり脳内でもビルダパターンとして最初から考える、てことだ。けれどもオフラインではその思考を「諦めて」いる、がゆえに…、そう、「あ、これって悪い思考癖だな」とようやく思ったのだが、ついつい「Set Initial Data Array」だけを使おうとしてしまう、てこと。まぁ一種の馬鹿の一つ覚え、でもある。
Set Initial Data Array だけ使おうとする癖のせいで、適切な単位で処理ステップとして分解するのがますます困難になっていた。つまり:
1 <!-- ... -->
2 <link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.9.3/css/tabulator_site.min.css" rel="stylesheet">
3 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.9.3/js/tabulator.min.js"></script>
4 <!-- ... -->
5 </head>
6 <body>
7 <!-- ... -->
8 <!-- ... -->
9 <div id="actor_basinf"></div>
10 <script>
11 var actor_basinf_data = /* ... */;
12
13 /* ... */
14 var table = new Tabulator("#actor_basinf", {
15 /* ... */
16 "data": actor_basinf_data,
17 /* ... */
18 });
19 /* ... */
20 </script>
において actor_basinf_data の構築に時間がかかるとして、そしてデカいとして、ゆえにこの場合 new Tabulator が時間がかかるとして、エンドユーザにはこれがどうみえるかというと、「ブラウザがハングアップしているようにみえる」もしくは「白いページが見えてる時間が長い」、…、のだとしても、Set Initial Data Array を使おうとしている時点でもうアウトなんだよね、コンストラクタ内に割り込めないんだから。(Tabulator 部分以外だけ先に描画されて欲しい、くらいまでは Set Initial Data Array だけでも出来るけれど、「データが入ってない箱だけでも先に描画されて欲しい、と願っても、その術がない。」
答えは、見出しにしたとおりで、コンストラクタでは data を渡さずに、new で構築した後で setData を呼び出す、とすればいいだけ。ね、当たり前のことなんだよな。(実際 Tabulator の公式ドキュメントでの説明の順序も setData の方が先。そりゃそうだ。)ので、こういうことも出来るわけよな:
1 <!-- ... -->
2 <link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.9.3/css/tabulator_site.min.css" rel="stylesheet">
3 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/tabulator/4.9.3/js/tabulator.min.js"></script>
4 <!-- ... -->
5 </head>
6 <body>
7 <!-- ... -->
8 <!-- ... -->
9 <div id="actor_basinf"></div>
10 <script>
11 /* ... */
12 var table = new Tabulator("#actor_basinf", {
13 /* ... */
14 // これはやらない→ "data": actor_basinf_data,
15 /* ... */
16 });
17 /* 遅延実行しちゃいなよ */
18 setTimeout(function () {
19 var actor_basinf_data = /* ... */;
20 table.setData(actor_basinf_data);
21 }, 300);
22 /* ... */
23 </script>
これにより、「Tabulator の外箱だけは先に描画する」ことが出来て、(トータルでの時間はたとえ一緒だとしても)ちょっと印象が良くなる。
まぁ話としてはこれだけなんだけどさ、いつも思うんだよな、ワタシって、「外してはならない」ところを器用に外す才能があって、こうやって時間が経ってから気付いて損した気分になりがちなのよねぇ。才能が欲しいよ、才能が。あ、いらない才能のほうはいらないよ、そして終わるまでは終わらないよ。
てなわけで ver16: