| @労働

DHH が Twitter で言及していた記事がおもしろかったので著者の許諾をもらった上で翻訳しました。

Salesforce の Product Manager 、 Blair Reeves さんの記事。


僕は自分のテクノロジー業界でのキャリアのすべての期間をリモートワーク擁護者として過ごしてきた。それは自分自身のリモートワークの経験から始まった(ありがとう IBM !)。以前も書いたことがあるが、リモートワークというものは破壊的なテクノロジーでその優位は揺るぎない。このことは自明なのでここでは労力を割かない。

今週、 Facebook が一部の従業員に対して好きなところに住んでリモートワークすることを認めた(訳注: Zuckerberg says employees moving out of Silicon Valley may face pay cuts )ことで、これまでたびたび論争になっていたリモートワーカーへの報酬についての議論が再燃した。この問題は究極的にはリモートワーカーにいかに "公平に" 支払うか、ということだ。このことが報酬についての議論を難しくしている。たくさんの会社がこの件に悪戦苦闘しているが、それはよこしまな理由からではない。

とはいえ、正しい議論と間違った議論があると思う。現実主義によって多少脚色されている。

現実的な観点では、テック部門の人件費をサンフランシスコやニューヨーク以外のレートに切り詰めるということだ。たとえば Facebook の Product Marketing Manager の初任給から 20% 削減された金額だとしても、ウィンストン・セーレムやジャクソンビル、リトル・ロック、ブルーミントン(訳注: すべてアメリカの地方都市)に住んでる人には魅力的に思えるだろう。多くの雇い主が給与額で競争するような状況が我々にとっては望ましい。機会が増えることは常に望ましい。だからどんどんやって欲しい。

上記を踏まえた上で主張するが、生活コストに応じた給与額の調整はとても不公平だしよくない習慣だと思う。同じ仕事をして同じ価値を発揮している人には同じ給料を支払うべきだ。

何が変わったか

最近までフルリモートで働くことは多くの人にとって選択肢になかった。もし X 社で働きたいと思ったなら、 X 社のオフィスがある大都市に引っ越す必要があった。それが取引だった。

しかしこれまで自分が働いてきたソフトウェア企業では、ほとんどの人の仕事はオンラインかつリモートでこなすことが可能だったし、実際にそうしていた。そう、すべてだ。プロダクトマネジメント、エンジニアリング、デザイン、オペレーション、マーケティングなどなど。リモートワークに懐疑的な人でさえ心の底ではこのことはわかっている。そしていま、(訳注: コロナウイルスの影響でリモートワークをするようになり)長い間信じられてきたリモートワークの優位性が実際に証明されてしまった。リモートワークで問題ないのだ。リモートワーク懐疑主義者達が間違っていたことが完全に証明された。

言い換えれば、従業員を大都市圏に住まわせることのビジネス面での合理性は崩壊したということだ。多くの人がニューヨークのような大都市に住みたいと思っているが、大都市に住むことは会社の成功にとって重要ではないし実際には無関係だ。ソースコードの善し悪しにどこで書かれたかは関係ない。ユーザーストーリーも、デザインモックアップも、販促資料もだ。テンペ(訳注: アリゾナ州の人口 16 万人の都市)でできることはメンロパーク(訳注: Facebook の本社があるシリコンバレーの都市)でもできる。

(ここはインターネットなのであら探しが好きな人もいるから捕捉しておくと、確かにある種の人たちは実際にビジネス上の理由で特定のエリアに住む必要があるだろう。具体的には顧客対応が必要な仕事、営業やカスタマーサクセスだ。これらの職種は希な例外としておく)

生活コストベースの報酬の理論的根拠が生活費が高い大都市に住む従業員への配慮なのだとしたら、もし雇用者が大都市の労働者を好まなくなったとしたらどうなるだろう? 違う言い方をしてみよう。「なぜ生活費が安い場所に住んでる連中が必要以上のお金を欲しがるんだ?」という問いをひっくり返すと「なぜ会社はサンフランシスコに住んでる連中が必要なんだっけ?」になる。

生活費が高い/安い場所で、労働者がゆとりのある生活を送るために必要な報酬はいくらだろう、というのはよく議論の的になる。ただ、こういう問いの立て方は問題に対する間違ったアプローチで、どのくらいの生活費がかかる場所に住むかというのは完全に個人の問題だ。もしサンフランシスコに住んでる人が自分の収入の大半をサンフランシスコに住むために使いたいとしたら、それは結構なことだし、その人自身の選択だ。一方でもしサンマテオ(訳注: シリコンバレーの街。 YouTube の創業地)でリモートワークをしている(あるいはオフィスで働いている)人が、 リトル・ロック(訳注: アーカンソー州の人口 18 万人の街)に住んでいる同僚と全く同じ働きをしているとして、どうして一方は給料を優遇されてもう一方は減額されないといけないのだろうか? もしリトル・ロックの従業員には子どもがいて年老いた親の面倒も見ていたとしたら? 一方でサンマテオの従業員は独身で単身者だったとしたら? 必要な額を考慮するとき、こういった個人の家庭の事情は考慮されないのはどうしてだろう? つまり、生活コストによる給与の調整は、従業員はこういう風にお金を使うべきという本質的に不適切な思い込みに基づいて行われている訳だ。生活費の高い大都市に住むことは価値のある選択で、そうでない選択は価値がないと言っているに等しい。

例えば GitLab はこんな風に公言している。

もしみんなが標準的な給料を受け取ったら、所得の高いエリアに住んでる人たちは所得の低いエリアに住んでいる人たちに比べて可処分所得が少なくなってしまう。

えーっと、はい。これがポイントだ。

住む場所の選択によって発生する生活コストの違いは不可避的に、誰かにとっては補助金的なものであり、誰かにとってはペナルティのようなものなのだ。多くの人が住みたがる、生活コストの高い大都市に住む人に対して企業が高い給料を払う義理はないのだ。どこに住むかというのは、これまでもこれからも消費選択の問題に過ぎない。その選択の問題が今日、よりくっきりと明らかになったのだ。

インターネット全体で労働力の供給と需要が行われる

生活コストを報酬の決定に加味する件に関してよく言われることの一つに、労働力の需要と供給の問題がある。すなわち、市場メカニズムが地域ごとに異なる給与額を規定するので、企業はその地方の基準に従って支払うしかないのだと。 GitLab のような、完全にリモートで従業員を採用している会社がよくとるアプローチだ。彼らは報酬調整の式を公開している

この方法の問題点は、 "労働力供給" の定義だ。オフィスへの出社を求める企業にとって、潜在的な労働力というのは会社の半径 20 マイルに住んでいる人々のことだ。しかしリモート企業では、 "インターネット全体" が潜在的な労働力だ。(もっと実務的な言い方をすると、裁判所の管轄権の及ぶ居住者全体だ。あとで詳しく述べる。)これらの観点から、フォート・ウェイン(訳注: インディアナ州の人口 25 万人の街)に住んでいる労働者にとって、彼女の住んでいる街には "競争相手" がいない(企業側からしても、労働者側からしても)。メンフィスやスポーケン、シュリーブポートあたりの人だってそうだ。企業が市場経済の仕組みによって給料を減額調整しようとするのは、本当のところ仕事ぶりとは無関係に懲罰的に給料を下げようとしているということと同じなのだ。ある従業員の地理的選好によって補助金を出すのは、組織としてビジネス的に意味のないひいきをしていると表明しているのと同じだ。

ある人はこのモデルを "底辺への競争" (訳注: 規制緩和でかえって経済全体が貧しくなること。底辺への競争 - Wikipedia)と見るだろう。僕は違う。機会の拡大だと捉えている。もしどこか別の場所により少ない給料で与えられた仕事を完璧にこなす人がいたとしたら、その人に仕事をしてもらうのが合理的だ。これは Menlo Park で働き一年で 50 万ドルを稼ぎ出す Facebook のエンジニアにとって驚異だろう。ほとんどのリモート企業が希少な才能を必要としていることを考えると、バンガー(訳注: メーン州の街)やリノ(訳注: ネバダ州の街)で仕事をしている人にとっては、幾ばくか値切られたとしてもリモートワークの報酬は充分によい、中の上レベルの給与になるだろう。

ではここで質問だ。このやり方はどこまで認められるだろう?

慎重な反論を紹介しよう。論理的に考えれば、世の中のテック系の仕事がすべてリモートワークへ移行すると、アメリカ中から条件のよい仕事はなくなってしまって、すべて外国に奪われてしまうだろう。結局のところ、ハイデラバード(訳注: インドの大都市)やキエフ(訳注: ウクライナの首都)、ラゴス(訳注: ナイジェリアの旧首都)に住んでる連中も充分に賢くて、アメリカのテック企業で必要とされる水準の働きをするだろう。文字通り 1990 年代にはソフトウェア産業でエンジニアリングの領域はオフショアの波に呑まれてしまうだろうと言われていた( 90 年代後半にはマジで大問題だと認識されていた)。しかしそうはならなかったどころか、アメリカ国内のエンジニアや頭脳労働者の求人は拡大する一方だ。恐らくこの傾向は続くだろう。主にアメリカで使われることを想定したプロダクトを作っている会社はアメリカ人の労働者を重要視する。リモートでの雇用は国境ほどには州境を気にしない。精々法規制や税金のことくらいだ。

(政策決定の観点からすると、アメリカのリーダーたちは、高給の仕事を大規模にオフショアすることを規制すべきだ。代替案のないグローバリゼーションがいかにアメリカの労働者階級の雇用を悪化させたかという興味深い議論がある。しかしこの議論は別の投稿で行うとしよう。いまは企業レベルの話をしている。)

報酬の話になると、多くのアメリカ人がバンガロール(訳注: インドの IT 産業の中心地)に住んでいる Puja やイズミル(訳注: トルコの大都市)に住んでいる Mustafa に、パロアルト(訳注: シリコンバレーの街。スタンフォード大学やヒューレット・パッカードがある)に住んでいるプロダクトデザイナーと同額の給料を払うのは不合理だと言うだろう。僕はこういうのは自己中心的だと思うし、 Puja や Mustafa も同意しないだろう。彼らが確実に同じ価値を会社に対して提供しているのなら、同じ額の給料を支払うのが正しいはずだ。もし Puja と Mustafa が王様や女王様のような暮らしをしたとしても気にする必要はない。それでいいじゃないか。ひどく安い給料でオフショアの人々を雇うのは、本人の意思で決めることができない生まれた場所に基づいて労働者にペナルティを与えているようなもので、自分の意思で住む場所を決めた人に対して給料の調整を行うのよりももっと正当化できない。

人件費が高くなりすぎやしないかって? さぁ、どうだろう。確かに人件費は高くなるだろう。しかし例えば GitLab は 5 億ドルも VC から調達している。従業員に公平に支払う余裕はあるはずだ。じゃあ Microsoft や IBM のような、何千人も雇っていて物価の安い国ではアメリカでの給料よりも低い給料で従業員を雇用している会社はどうだろう? 僕には答えがわからない。ただ、正しいことは常に正しい。人は国籍によらず平等に給料を支払われるべきだ。バンガロールで雇われてる人がアメリカ人よりも給料が少なかったとしても、バンガロールの標準的な給料に比べたらずっといいじゃないか、という現実主義的な反論があるのはわかってる。審判を下せる問いではない。でもこれって公平かな? いや、まったく公平じゃない。

Day one

企業が従業員に特定の場所に居住してもらう必要がある場合には、その土地に応じた給料を支払うことが正当化できる。でもそうでない場合には — 多くのソフトウェア開発の仕事が当てはまる — 労働市場ってのはかつてなく広がっていて深さもある。

この数ヶ月、もしくは数年でこの激震の勝者と敗者がはっきりするだろう。どういう結末になるかは誰にもわからない。しかし給料の良いテック企業で働くには西海岸か東海岸に住まなければならないという制約は崩壊し、我々の社会と産業は随分よくなるだろう。リモートワークは会社にとってもチームにとってもよい。従業員にとっても、その家族やコミュニティーにとってもよい。みんながリモートワークを好きになれるわけじゃないが、オフィスで働くのだってそうだ。(リモートがよいかオフィスがよいかについて、これまで個人の好みが問題になったことはないはずだ)

リモートワークは津波のように我々の上にのしかかったわけではない。近い将来に関していうと、いくつかの企業はリモートワークを躊躇し続けるだろう。僕はコロナ禍がリモートワークを推し進めるだろうと楽観しているが、油断はできない。僕の考えは間違っているかもしれないが、大躍進ではなくとも小さな一歩を踏み出すことになるだろう。ところで確信していることもある。僕がシリコンバレーで長期の商業ビルの賃貸契約をすることは決してないだろう。


リモートワークをしていて、地方に住んでいるからという理由で給料を少なくされたらやっぱりいい気もちはしない。同じ仕事をしているのに、自分だけコンビニの 100 円コーヒーで我慢しないといけなくて、同僚はスターバックスのコーヒーを飲んでる、という状況を想像してみて欲しい(自分にはそういう経験がある)。会社の中で所得の格差がありすぎると、ただでさえリモートワークでは同僚と雑談する機会が少なくて打ち解けにくいのに、より一層個人個人の間に壁を作ってしまって会社やチームになじむことができないと思う。日本国内では居住地による所得格差はアメリカほどには大きくないかもしれないが、コロナウイルスの影響でリモートワークが普及するにつれ、同じような問題に直面するケースが出てくるかもしれない。そのとき、リモートワーカーは決して安い給料に甘んじてはいけないと思う。

| @写真

Flickr の Pro プランの有効期限が今月末で切れるので念のため全データを DL しておいた。自分は 2007 年に車上荒らしにあって PowerBook 17" を盗まれてしまい、そこに保存しておいたそれまでの人生のデジタル写真もすべて失ってしまった。一部は Flickr にアップロードしておいたので、それらを Mac 上に取り込むのが目的。 Flickr はちゃんとしていて、データの DL リクエストをすると一日くらいで画像だけでなく文章はコメント含めて全部 DL できるようになってる。 GDPR 便利。

何枚かの写真はアップロード時に縮小されてしまっていて、 5K のディスプレイで見るとかなりちっちゃい。試みに image upscale などでググってみると以下の Web サービスが見つかった。

最大 4 倍までアップスケールできる。利用にはアカウント登録が必要だった。無料っぽいので試してみた。アップロードしたのは以下の写真。この写真は 800×600 の解像度でしか落とせなかった。

VW Golf 2 GTI

それがこうなった。ぱっと見綺麗。

VW Golf 2 GTI Upscaled

ただし拡大してみると欠点がないわけではなかった。こんな感じ。

Deep Image Drawbacks

暗い部分、光が反射している部分は綺麗にアップスケールできないみたいだった。機械学習モデルが進化するとこの辺も綺麗にアップスケールできるようになるのかな。

変換の方法はファイルを都度アップロードする方法のほかに、 Google Drive にファイルを置いてディレクトリ指定で一括変換したり、REST API も用意されていて、 curl や自分でプログラムを書いて変換させることも可能っぽい。なかなか便利そう。

なおこのサービスは無料で使えるのは 5 枚までで、それ以上はサブスクリプションか都度払いでお金がかかるシステムのようだ。

Deep Image Pricing

Flickr から落とした低解像度の写真が何枚かあるので都度課金かサブスクリプションの単月契約で利用してみようかなと思ってる。

| @Mac/iPhone

リモートワークをするようになって会社から貸与されている MacBook Pro の本体キーボードを使うようになった。普段、会社には私物の 4K ディスプレイと Happy Hacking Keyboard を持ち込んで外付けキーボードと外部ディスプレイの組み合わせで仕事をしているが、在宅に切り替えるタイミングで MacBook Pro 本体だけ持ち帰り、キーボードやディスプレイはオフィスに置きっぱなしにしていた。本体のキーボードを使うようになったことで、キーが引っ込んだまま戻らなくなる例の問題に遭遇するようになった。

修理を依頼しようと Apple のサイトを覗いてみると、緊急事態宣言の影響か配送による修理受付は停止しているようだった。

しょうがないので修理は諦めて外付けキーボード使いたいのだけど、家に USB-C への変換用ドングルがなく困ってる(ドングルも会社に置いている)。 15 インチの画面もなかなか厳しいので iMac の画面を使って仕事ができないかと思ったが、自分が持っている iMac はターゲットディスプレイモードにならないモデルなので無理。

Rebuild のエピソード 266 で miyagawa さんが Mac mini から Remote Desktop で会社支給の Macbook Pro につないで仕事してるって言ってて、なるほどなと思って真似してみた。

私物 iMac から会社の MacBook Pro に vnc でつないでみる。しかし単なる画面共有だとキーボードショートカット使えなくて厳しかった( Command + Space で Alfred を呼び出そうとすると、クライアント側の Mac の Alfred が反応する)。 Apple Remote Desktop でならショートカットも使えるという未確認情報があるのだけど、値段が 10,000 円もしてちょっと試すには厳しいお値段。

一回オフィスに車で行ってディスプレイを持ち帰るとよさそうだなとは思うのだけど、またオフィスで仕事を始めるときにディスプレイを会社に持っていくのもなかなか厳しい(持ち帰るときとまたオフィスに持っていくときの二回、車で送ってもらわないといけない)。こういうことで悩まなくて済むくらいのお金が欲しい

| @労働

瑞梅寺川の桜

リモートワークが長くなってきた。正直どのくらい自宅で仕事しているか定かではない。ほとんど外出しないので時間の感覚がおかしくなってきている。職場がリモートワークを許可するようになってもしばらくは出社していたが、二週間ほどで自分の具合が悪くなり会社に行くのを控えるようになった。その後本格的に具合が悪くなって家庭内隔離状態になり、同時に会社もリモートワークを推奨から出社禁止という状態に変わった。約 3 年ぶりのリモートワークで色々思うことがあったので雑に書きます。

リモート会議

リモートのミーティングでは前職の頃から Zoom をよく使っていた。いまの職場でも Zoom を多用している。リモートミーティングの Tips みたいなのは最近どこかで流れてきたのを読んだ気がするけど自分も思うところがあるのでまとめておく。

まず第一にはミュートだ。話さない人はとにかくミュート。 Zoom は音が鳴っているマイクの音を拾って音声ストリームに載せる。そして音声ストリームでは主として話している(音を出している)人の音声が採用されて、その他の人の音声はカットされてしまうようだ。図にするとこんなイメージ。

オフラインの会話

Zoom の会話 1

Zoom の会話 2

Zoom の会話 3

イヤフォン・ヘッドフォンを使う

自宅だとイヤフォンを付けずにスピーカーから音を出しがちだ。 Zoom のミーティングにもイヤフォンを付けずに参加してしまうかもしれないが、ハウリングしてしまったりするのでなるべくイヤフォンを付けてパソコンのスピーカーからは音を出さずに参加したい。

またイヤフォンを付けずに参加するとパソコンのマイクを使うことになって、会話と会話の切れ目が聞き取りにくくなる。 Zoom はハウリングが起こらないよう、ストリームで流している音と同じ音がパソコンのスピーカーから出ていたらそれを拾わないようにしているはずで、パソコンのマイクで話し始めるときに切り替え処理が必要になり、会話の始まりのあたりが拾われなかったりする。マイク付きのイヤフォンを使うことでこの問題は回避できる。

ちなみに以前も書いているけど Apple の iPhone 用イヤフォンはよくできていると思う。 2800 円くらいなのにマイクの音が良好で、相手の声もよく聞こえる。 10 倍以上の値段がする AirPods Pro を使っている人の声より、 2800 円の iPhone 用イヤフォンを使っている人の声の方が聞き取りやすい。 Lightning 端子ではなく 3.5mm ジャックのやつじゃないとパソコンにつなげないので注意。

やっとるわ感

先週、 sudoken さん( Kaizen Platform の CEO )が三戸正和さんという人と対談してる YouTube Live を見た。ほとんど三戸さんという方の話で sudoken さんの話はあまり聞けなかったが、「リモートワークではプロセスでの評価ができないので、アウトプットを意識的に行い、自分の成果をアピールすることまでが仕事のうち」という話が面白かった。リモートワークでは結果による評価に移行せざるを得ないということだ。

エンジニア業を止めてからつくづく感じるのが、人はしつこいほど言わないとわかってくれないということだ。伝えたいことは社内ブログに書いていたらみんな読んでくれるわけではなく、目立つような場所に掲示したり、目立つ方法で喧伝したり、何度もしつこく見せたりしないとなかなか見聞きしてもらえない。リモートワークをやっていて自分はそこそこ頑張って仕事してるつもりでも、その成果をちょっと過剰なんじゃないのと思えるくらいにアピールしないと、組織や同僚からは仕事してる風には受け取ってもらえないだろうな、と思った。リモートワークではやっとるわ感を出すところまでが仕事の範疇に入ることになる。

増えた自由に使える時間を有効に

リモートワークに移行して、毎日通勤にかかっていた 2 時間を自由に使えるようになった。前職時代は朝仕事を始めるギリギリまで寝ていたけど、いまは 7 時くらいに起きて仕事を始める 9 時半くらいまでブログを書いたり散歩したり食器を洗ったりしてる。最近、ブログの記事が増えているのはそういうわけだったりする。

コロナウイルスのせいで恐らく世界大恐慌に陥るだろうと思う。 1 ヶ月も 2 ヶ月も世界中の人が外出しなかったら経済回らなくなる。この時期にゲームしたり Netflix 見たりするだけでなく、何かしら一つ生産的なことをして自分に投資しておかないと数ヶ月後に泣きを見ることになるだろうなと思う。いまはインターネットの会社はコロナウイルスの影響をあまり受けていないか、あるいは Zoom や Slack 、そのほか EC をやっているところは逆に業績好調かもしれない。ただ、世の中が全体的に不景気になると必ずその余波が及ぶわけで、そのときをどう迎えるかはソフトウェア企業に勤める人々にも重要なテーマとなるだろう。

| @ブログ

75 件ほどあった tech.portalshit.net の記事を取り込んだ。実家に住んでいた 10 年前に始めた技術ブログで、最初は Rails 製の Mephisto 、その次に Jekyll で構築した。まだ GitHub Pages の仕組みが存在する前で、自前で用意したさくら VPS に git push すると自動でビルドして記事が公開されるような仕組みを作ったりしてた。

職業プログラマーになろうとしてもがいてた頃にやってたブログで、いま読み返すと「頑張ってたんだな」感があっていなたい記事が多い。

だいぶ放置していて、いまは S3 で静的サイトとして公開していたのでそのまま放置でもよかったが、 10 年前と違って何でも一カ所にまとめて書いておきたいという気持ちが強くなって取り込むことにした。ブログはトピックを混ぜずに一つのトピックにフォーカスした方がよいと 10 年前は考えていたのだけど、最近の世の中のブログ記事の読まれ方は変わってきていて、一人の人のブログをフィードリーダーに登録して読むというより、 SNS をだら見していて流れてきた記事を適当に消費するというスタイルに変わってきているので、一つのブログに一つのテーマという書き分けは不要になったと感じる。

tech.portalshit.net を取り込んだおかげで Archive ページのグラフに占める技術記事の割合が増えた。

Tech category Bar extension

ちなみに取り込みは以下のようなコードを書いて SQL の INSERT 文に変換した。

require 'yaml'
require 'pathname'

files = Dir.glob(File.join(__dir__, '_posts', '*.markdown'))
files.each do |file|
  content = File.read(file)
  _, header, body = content.split('---')
  header_yml = YAML.load(header)
  title = header_yml['title']
  tags = header_yml['category']
  tags = tags.is_a?(Array) ? tags.map(&:downcase) : [tags&.downcase]
  slug = Pathname.new(file).basename.to_s.sub(/\d{4}\-\d{2}\-\d{2}\-(.+?)\.markdown/, '\1').gsub('_', '-')
  body = body.strip.gsub(/\n/, "\\n").gsub('\'', '\'\'')
  created_at = File.birthtime(file).to_s.sub(' +0900', '')
  updated_at = File.mtime(file).to_s.sub(' +0900', '')
  puts <<~EOS
    INSERT INTO entries(title, user_id, category_id, slug, markup, type, draft, body, frozen_tag_list, created_at, updated_at) VALUES('#{title}', 1, 6, '#{slug}', 'redcarpet', 'Post', 0, '#{body}', '#{tags.join(',')}', '#{created_at}', '#{updated_at}');
  EOS
end

| @ブログ

Chart Tooltip

Archive ページにこだわってしまう理由、グラフを表示させてみて(ブログ過去記事をカテゴリーごとに集計してグラフ化 - portal shit!)何となくわかった気がする。過去記事ページというのはブログの書き手にとってはアクティビティダッシュボードなのだ。ジョギング系アプリ使ってる人なら記録をあとから振り返ることがあると思う。それと同じで、自分が過去にどのくらいの頻度、密度でブログを書いていたかを自分は知りたいと思うのだろう。その用途に適しているのが過去記事ページというわけで、 Archive ページの使い勝手の改善は自分のブログアクティビティをふり返りやすくしたいという欲求の表れだったのだと思う。

ちなみにグラフを作ってみたことで、 2006 年頃に異常な数の記事を書いていたことがわかったし、かなり内容のない記事(新聞やテレビを見た感想)ばかり書いていたことがわかって興味深かった。 2007 年からは記事の数が減るが、これは Twitter を使い始めたからだと思う。2009 年頃、病気療養を終えて就職しようとしているあたりからプログラミング関係の記事の数が増え、実家を出て福岡のブラック企業に勤め始めてからは記事数が減った。

あまり ASP 型のブログを使ったことがないのでよく分からないが、こういうカテゴリーごとの Chart 機能はないような気がする。一時期、ダイエット日記を書いていたはてなブログにはアクセス解析機能とアクセス数の統計機能はあったが、自分のブログアクティビティを振り返る機能はないと思う( PRO になればあるのかもしれない)。

自己満足的なブログの書き手にとっては、どれだけ読まれたかももちろん気になるけど、どれだけ書いたかも重要なのではないかと思う。読まれたかというのは結果であり、書いたかというのはプロセスというか、自分の頑張りだ。仕事をする上では結果にフォーカスにしなければ意味がないけど(使われない機能を作ってリリースするのは自己満足)、ブログは趣味なのだからプロセスの部分(自分の頑張り)が可視化される仕組みがあってもよいと思う。

| @技術/プログラミング

Chart

Rechars という React のチャートライブラリを利用して、 Archive ページにカテゴリーごとに記事を集計してグラフ化する機能を作った。

グラフの Bar にカーソルを載せると Tooltip が表示されて、具体的な件数がわかる。

Chart Tooltip

カテゴリごとに表示・非表示を切り替えることも可能。グラフ下のカテゴリー名( Legend )をクリックして切り替えられる。

Chart Show-Hide Toggle

ただし残念なことに Bar を非表示にしたときに Legend の表示を変化させるのが難しくてできていない。

仕事で使ってる Looker とか Redash であれば Legend をクリックして表示・非表示を切り替えることができ、それに連動して Legend の色をトーンダウンさせたりする機能が付属しているが、利用した Recharts にはその機能がなかった。 Bar の表示・非表示切り替えも標準サポートされていなかったので、 GitHub の Issue の情報を頼りに無理矢理実装した。

コードはこんな感じ。結構汚い Hack で、 Bar の表示・非表示を、表示用のキー文字列に空白を追加するかしないかで切り替えている。

  // クリックされたアイテムが `this.state.disabled` 配列の中にすでに存在していれば除外し、
  // 存在してなければ追加する
  selectBar(event) {
    let dataKey = event.dataKey.trim()
    if (this.state.disabled.includes(dataKey)) {
      this.setState({ disabled: this.state.disabled.filter(item => item !== dataKey) })
    } else {
      this.setState({ disabled: this.state.disabled.concat([dataKey]) })
    }
  }

  render() {
    return (
      <ResponsiveContainer height={500}>
        <BarChart
          data={this.state.data}
          margin={{
            top: 20, right: 20, left: 0, bottom: 20,
          }}
          style={{ fontSize: '14px' }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="year" />
          <YAxis />
          <Tooltip labelStyle={{ color: '#000', fontWeight: 'bold' }} itemStyle={{ margin: '0 2px 0 4px', padding: '0' }} />
          {// Legend クリック時のコールバックに `this.selectBar` を指定する }
          <Legend onClick={this.selectBar} />
          {/*
            `this.state.categories` 配列と `this.state.disabled` 配列の内容を比較し、
            `this.state.disabled` に追加済のカテゴリーは dataKey に空白を追加することで非表示に
          */}
          {this.state.categories.map((category, index) => {
            let dataKey = this.state.disabled.includes(category) ? category + " " : category
            let color = this.colors[index % this.colors.length]
            return(<Bar key={index} dataKey={dataKey} stackId="a" fill={color} />)
          })}
        </BarChart>
      </ResponsiveContainer>
    );
  }