kondoumh のブログ

- とあるソフトウェアエンジニアのめったに更新されないブログ -

JointJS でトイ・ダイアグラムエディタ

前回 CodePen でトイ・ダイアグラムエディタを作った時は、Konva.js を使っていました。

blog.kondoumh.com

今回は、JointJS で同様のトイプログラムを書いてみました。

JointJS: Visualize and interact with diagrams and graphs

f:id:kondoumh:20180708083705g:plain

JointJS 自体は、2014年末ぐらいから知ってはいました。

当時は、スマートデバイスへの対応が今一つという印象でしたが、3年ぐらい経つと当然のように対応してきて機能的にもかなり進化している印象です。 商用の Rappid というライブラリの基盤となっていて、作図関係の機能は Rappid と遜色ありません。Rappid には Undo / Redo とか Inline TextEditor などアプリ寄りの機能がアドオンされています。

Rappid and JointJS Comparison

最近 Node-RED Spring Flo などのパイプラインエディタを調査していて、Node-RED はエディタ機能を自前で作り込んでいてかなりコード規模が大きくなっているのに対し、Spring Flo のコードはシンプルなのでよく見たら JointJS を採用していたので、その存在を思い出しました。

Backbone.js に依存しているというのが時代を感じますが、使いやすい API を提供している機能豊富なライブラリに仕上がっています。

ダイアグラムエディタの JointJS 版は Konva.js 版と比べても 1/3 ぐらいのコード量でした*1。ノードやリンクの管理をお任せできてしまうので楽できます。

See the Pen JointJS-dia by kondoumh (@kondoumh) on CodePen.

*1:Konva.js 版は CoffeeScript で書いてるのでかなり短くなってるのですが。

Chrome で Desktop PWAs が実装されたので Twitter Lite を macOS デスクトップで使う

Chrome 67 の feature flags に Desktop PWAs が入って Android で使える PWA が macOS や Windows でも使える日が近づいてきました。

Chrome のタブを別ウィンドウで開いておくよりもデスクトップアプリらしい振る舞いをします。Chrome に限らずメジャーブラウザが対応中。かなり前から Chrome にはサイトをアプリケーション化する機能がありましたが、PWA が Web 標準であること、サイト側が PWA に対応することで、よりアプリらしい体験を得ることができます。

Desktop PWAs は Chrome 67 では無効化されているため chrome://flags で有効化します。

f:id:kondoumh:20180628003406p:plain

昨年末に PWA サイトとして話題になった dev.to や Twitter Lite で試せます。

dev.to

有効化して PWA 対応サイトに行くと、メニューに 「サイト名」をインストールしています... と表示されます。

f:id:kondoumh:20180628004023p:plain

メニューをクリックすると確認のポップアップが表示されます。

f:id:kondoumh:20180628004052p:plain

インストールをクリックするとアプリが、/Users/<user>/Applications/Chrome Apps.localized (「Chrome アプリ」フォルダ ) にインストールされます*1

f:id:kondoumh:20180628004908p:plain

起動すると Chrome とは独立したウィンドウで表示され、Dock にも専用アイコンが表示されます。

f:id:kondoumh:20180628005318p:plain

これで、ようやく Mobile Twitter サイト (Twitter Lite) をデスクトップアプリとして使えるので、連休中に作った Electron アプリを捨てられます。

blog.kondoumh.com

Electron アプリは Chrome を丸ごと動かしているようなものなのであまりたくさん起動したくありません。そうでなくても、VS Code や Slack などを常駐しているので。Chrome も1タブ1プロセスですが Electron アプリよりも軽量プロセスだと思います。PWA は Chrome の 1タブ程度のフットプリントと思われます。

ということで、早速 Twitter Lite をインストール

f:id:kondoumh:20180628010023p:plain

いい感じです。

f:id:kondoumh:20180628010044p:plain

*1:このフォルダには PWA アプリに限らず、Google のサービスのリンクもインストールされているようです。

本ブログの HTTPS 対応が完了

はてなブログが独自ドメイン運用のブログも HTTPS 対応を完了させました。

staff.hatenablog.com

本ブログも早速移行。

設定画面でポチッとするだけで意外とあっさり終わりました。独自の設定を何もしていないというのもあったと思います。数個の記事で混在コンテンツ対応しただけ (見落としもあるかもですが気付いたタイミングで直そうかと)。

これで管理してるサイトの HTTPS 化が完了しました。

blog.kondoumh.com

はてなブログの担当者の皆様お疲れ様でした。

VS Code の ChangeLog メモ用 Extension その後

年明けに作っていた ChangeLog 用 Extension

blog.kondoumh.com

日付+メルアドのヘッドライン挿入ぐらいしか作ってなくて、ローカルでアドホックに修正して使ってましたが、ちょいちょいコード修正するのが面倒になってきたので見直しました。

シンタックスハイライトの統合

まず、シンタックスハイライトの定義を別 Extension で作っていたので統合しました。

項目(タグ)のセットを挿入

ヘッドラインと一緒に定型的な項目(タグ)のセットを一式挿入できるようにしました。

f:id:kondoumh:20180609143752g:plain

VS Code 設定画面での設定

メールアドレスや、項目セットの設定を VS Code の設定画面で書けるようにしました。

f:id:kondoumh:20180608163957p:plain

設定用の JSON データのサンプルです。

    "changelog.mailaddress": "kondoh@local",
    "changelog.weekdayitems": [
        "task",
        "meeting"
    ],
    "changelog.weekenditems": [
        "running"
    ]

平日と週末で異なる項目セットを定義できるようにしました*1

スニペット

一括挿入ではなく個別に項目(タグ)を入力するためのスニペットを使えるようにしました。tag と打つことでスニペットが入力できます。

f:id:kondoumh:20180609143822g:plain

スニペットにするほどの入力量でもないんですが、まあ一応。

マーケットプレイスへの公開

めんどくさそうでまだやってません。

github.com

(2018.9.15 追記) マーケットプレイスに公開しました。

blog.kondoumh.com

*1:設定用の名前空間の衝突とかありそうですね。

HHKB Pro JP を macOS High Sierra に最適化 - with Karabiner-Elements & DIP switch

Mojave ではどうなるかわかりませんが・・

macOS Sierra 以降 Seil が動かなくなりアンインストールして、Magic Keyboard だけで生活してきました。

blog.kondoumh.com

久々に Realforce 91UBK を常駐先から持ち帰って、オールドな Windows キーボードもよいものだと思い、MacBook Pro に接続してみました。

blog.kondoumh.com

91UBK はもう生産してないんですね*1

接続してすぐに Seil がないから日本語と英語の切り替えがストレスフルだったのを思い出しました。この辺はもうそろそろ解決されてるんじゃないかとぐぐったら、Karabiner-Elements という後継ツールがいい感じに進化している模様。

早速インストールしたところ、変換 -> かな無変換 -> 英数 というマッピングが簡単にできて Seil の環境が復活しました。

常駐先での強い味方である Realforce 91UBK はテンキーレスではあるものの Magic Keyboard を使っている自宅の机にはちょっとでかいです。そこで、久々に Happy Hacking Keyboard Professional JP を引っ張り出してきました。サイズ感がちょうどよくて自宅使いにフィットします。

blog.kondoumh.com

ただ、HHKB JP は Realforce と比べ、メインキーのサイズこそほぼ同じですが、最下段のキー(漢字Alt無変換変換kana) がちんまりしていて、親指のポジショニングがシビアです。そこで、変換 の右にある kanaかな にマッピングしてしまいます。これで日本語と英語の切り替えで誤操作は無くなります。このマッピングは Realforce のようなフルピッチのキーキャップのキーボードでも設定してます。kana (カタカナ/ひらがな) って全然使わないので。

最下段キーが小さいことで、macOS の を駆使するショートカットと、Alt 系のショートカット( Emacs のMeta など) で打ち間違う問題があります。特に、Alt の位置が MacBook の配列と逆なので混乱を助長させます。これって入れ替えられないのかなあと HHK 裏面のディップスイッチの説明をよく見ると SW5 で入れ替え可能じゃないですか。

f:id:kondoumh:20180604235528j:plain

買ってから10年目で気づきました。早速 SW5 をオンにして、引き抜き工具で2つのキートップを入れ替えました。

ちなみに HHKB のディップスイッチ では SW1 を ON ( にマップ)、SW2 を ON (左 FnCtrl にマップ) してます。左 FnCtrl にすることで、Emacs キーバインドで多用する Ctrl を左小指の肉球で押せるため、左小指がつりそうになるのを防止できます。

最後に、漢字 です。HHKB JP の漢字 は 最下段の左 Fn の右という変態位置に申し訳程度に配置されていますが、これはさすがに誰も使っていないのではないかと思います*2漢字 は Karabiner-Elements では grave_accent_and_tilde(`) という分かりづらい名前で指定できます。HHKB に限りこのキーを 左 Alt(option) キーに変えてしまいます。

f:id:kondoumh:20180604235815p:plain

これで、Alt の数が増えて打ちやすくなりました。キーボード毎にきめ細かく設定できるのも Karabiner-Elements の素晴らしいところです。

以上を纏めますと以下のようになります。

マップ元 マップ先 方法
SW1
Fn Ctrl SW2
Alt SW5
Alt SW5
漢字 Alt Karabiner-Elements
変換 かな Karabiner-Elements
kana かな Karabiner-Elements
無変換 英数 Karabiner-Elements

ということで、自宅では暫く HHKB Pro JP (墨) に回帰してみます。しかし墨ってほぼ無刻印ですね。キートップの印字がくっきりしてるモデルの方がいいなあと10年経って思いました。

f:id:kondoumh:20140204000402j:plain

*1:後継の静音タイプ UBK-S も今年6月に生産終了

*2:HHK JP からこのキーを取っ払って最下段のキーピッチを広くしてもらいたいと思うのは僕だけではないでしょう。

WPF に再入門中

久々に使うことになりそうなので、再入門しています。

.NET Framework 3.0 で Avalon のコードネームで搭載され、3.5 で WPF として登場した GUI フレームワーク。当時のプロジェクトで運用系ツールの画面で使いましたが、多くのプロジェクトでは Windows Forms が使われ続け早10年。ただ Silverlight, Windows Mobile, UWP, Xamarin ... と XAML 系 GUI プラットフォームが数年置きに登場する*1ため断続的に触っており、プログラミングモデル自体には結構なじみがあります。

XAML 編集用に Blend という別 IDE が提供されていますが、Visual Studio 本体でも地味に GUI デザイナーが進化しています。

リハビリがてら、RSS Reader 的なサンプルを作っているところです。

github.com

参考記事:[C# / WPF] 最新のC# 6.0でMVVMパターンを実装する

WPF 登場時はプロパティベースのデータバインディングが新鮮でした*2が、プロパティの更新通知のためにプロパティ名をハードコーディングしなくてはならず、リファクタリングでイベントが発火しなくなる恐れがあるのが残念でした。

    private string hoge;
    public string Hoge
    {
        get { return this.hoge; }
        set
        {
            this.hoge = value;
            OnPropertyChanged("Hoge");
        }
    }

C# 6 で nameof 演算子が導入されプロパティ名のリテラルが取れるようになったので、リファクタリングも大丈夫になりました。

    private string hoge;
    public string Hoge
    {
        get { return this.hoge; }
        set
        {
            this.hoge = value;
            OnPropertyChanged( nameof(Hoge) );
        }
    }

実は Behavior という Blend 由来の仕組みを使えば更新通知も簡単に実装できるようですが、別途 Blend SDK が必要となります*3。今回はとりあえず Behavior は使っていません。

  • イベントハンドラではなく、Command バインディングで書く
  • リモート API の非同期呼び出し - 呼び出し中に画面を固まらせない
  • 呼び出し中の Command 呼び出し無効化 - 呼び出し中に更新ボタンを押せなくする

あたりを意識して書いてみました。

Command バインディング (正式な呼び方ではないかもしれません) は、画面のボタンに対応する Command を実装して XAML にバインドする書き方です。

    <Button
        Content="Update"
        Command="{Binding FetchCommand}" />

Command の実装はこんな感じ。

    class FetchRSSCommand : ICommand
    {
        // 中略

        public bool CanExecute(object parameter)
        {
            return !Fetching;
        }

        public async void Execute(object parameter)
        {
            Fetching = true;
            var contents = await Task.Run(() => FetchRssAsync());
            foreach (var content in contents)
            {
                _vm.Items.Add(content);
            }
            Fetching = false;
        }

        private Task<List<RSSViewModel.RSSContent>> FetchRssAsync()
        {
            using (var reader = XmlReader.Create(_vm.Url))
            {
                var feed = SyndicationFeed.Load(reader);
                // 中略
                var result = (from f in feed.Items
                              select new RSSViewModel.RSSContent()
                              {
                                  Title = f.Title.Text,
                                  Summary = f.Summary.Text,
                                  PubDate = f.PublishDate.DateTime,
                                  Link = f.Id
                              }).ToList();
                return Task.FromResult(result);
            }
        }
    }

XmlReader には非同期用メソッドがないみたいなので、取得処理を Task にラップして、async / await で呼んでます。

Execute の前後でFetching というプロパティを変化させて強制的に Button の Disable / Enable を切り替えています。 Fetching プロパティの実装は次のようになっています。

    private bool _fetching = false;
    public bool Fetching
    {
        get { return _fetching; }
        set
        {
            _fetching = value;
            RaiseCanExecuteChanged();
        }
    }

    public void RaiseCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }

RSS 取得中かどうかを保持する bool 値 _fetching の setter で CanExecute 状態変化を通知するためのメソッドを呼び出しています。

昨今の JS の Single Page Application のような、非同期に Web API を叩いて結果を画面表示するアプリはサクッと書きたいのですが、なかなか定石が分からず迷いますね。.NET Framework や C# はがんがんバージョンアップしているので、ドキュメントもリニューアルされると嬉しいのですが、公式の WPF 関連情報は滞っている印象です

今は UWP や Xamarin 推しなのでしょうけどエンプラユーザーのことも時々ケアが必要。

*1:そして衰退していく・・あ、Xamarin は現役ですね。

*2:昨今の JS フレームワークでは普通ですね。

*3:標準に取り込んで欲しいものです。

Electron 版 Twitter クライアントを急造 - macOS PWA 版までのつなぎ

2月に macOS の公式 Twitter クライアントはディスコンになりました。

iphone-mania.jp

僕のマシンでは最後の方は接続エラーが出まくるようになっていたので、使わなくなっていました。代替として推奨されている TweetDeck をインストールしたのですが、Web 版やスマートフォンアプリとの UI の違いが大きくて馴染めずに起動することもなくなっていました。

最近はずっと Chrome で Twitter やってましたがブラウザの1タブなので閉じてしまうことも多く、タイムラインが常駐している感じがなくなりました。

2月に Microsoft は Web フロントエンドディベロッパーの取り込みを狙って Windows 10 における PWA (Progressive Web Apps) サポートを発表しました。

blogs.windows.com

Windows 10 UWP 版 Twitter アプリが先日 PWA 対応の一環でリニューアルされました。

japanese.engadget.com

www.microsoft.com

Twitter のタイムラインでは使いにくいみたいな声が目につきましたが、ライトユーザーである (と思っている) 自分にはスマホと同じ UI で馴染みやすい感じでした。

VMware Fusion の Windows 10 で、新 Twitter アプリと Edge *1を並べて使うと macOS 本体側と Twitter & ネット記事閲覧環境が分離できていい感じになりました。

f:id:kondoumh:20180504201302p:plain

ボーっとタイムライン眺めてる時間と作業用スペースがスワイプで切り替えられるのでコンテキストの切り替えが楽になる気がします。

Edge なので Twitter で出会った記事をストックするために Pocket 拡張を入れました*2。でも Tumblr に Quote 流したいなあと思うとブックマークレット必要ですが Edge でブックマークレットを使うのはとてつもなく面倒そうに見えました。英語のページだったら翻訳して読んだりしたいし・・・ここで、仮想マシンに Chrome を入れたら負けです。

macOS でも PWA 対応は進められているようで、もう数ヶ月したら、Windows 10 と同様の PWA 版 の公式 Twitter アプリが AppStore に登場しそうな気がします。

www.publickey1.jp

それをちょっと先に体験したくて Electron で Mobile 版 Twitter サイトをデスクトップアプリ化するの試してみました。

Electron は数年前に少し触ったきりだったので、ローカルの NPM パッケージが壊れてたりしました。公式サイトから Quick Start プロジェクトをダウンロードしてきて改造。起動時に外部リンクを開くための EventListener を追加したり、ウィンドウいっぱいに WebView 描画するようにした程度。

Mobile Twitter のシンプルな画面 はデスクトップでも邪魔にならないし、作業用とは別のデスクトップに 閲覧専用 Chrome のウィンドウを置いて、その隣に置くと 仮想マシンの Edge と Twitter アプリは不要になりました。

1日使ってみて、Mobile 版 Twitter をデスクトップで使うとスマホの引っ張って更新 (Pull to Reflesh) が使えないので、無意味に下にスクロールしたり、画面内リンク踏んだりしなければいけないところが微妙に感じました。PC 版サイトだと、未読ツイートが溜まってくるとツイートの一番上に 「新しいツイート n 件を見る」というリンクが勝手に出てくれるので楽です。

ということで、デフォルトは Mobile 版ですが、PC サイト版 Twitter に切り替えられるようにしてみました。PC 版だとユーザーアイコンにマウスオーバーするとユーザー情報をポップアップしてくれたり細かいところで使い勝手もよいですし。

これでかなり快適なタイムライン閲覧環境になりました。

f:id:kondoumh:20180504204157p:plain

自分用に作ったため特に配布予定はないですが、GitHub にソースコードは置いておきました。

github.com

PS. 作った後でこれ思い出した。

jackhanford.com

追記) Chrome 67 で Desktop PWAs が Feature Flags に入ったので Electron 版を捨てて PWA 版に乗り換えました。

blog.kondoumh.com

*1:仮想マシンには Chrome 入れないポリシー

*2:Edge の拡張機能もストア経由でインストールします。