accagg開発日記: viewerでグラフを描けるようになった

GWから作っていた Viewer ですが、ようやくグラフがかけるようになりました。

現状は以下のような感じです。

グラフ表示がようになった

Python3 + PySide2 (Qt for Python) で作ってます。まだ公開はできるレベルじゃないんですが、ここにくるまででも結構紆余曲折ありまして、その苦労話というか愚痴のエントリーです。

当初の目論見としては、Qt の Python バインディングである PySide を使って、QChartを使えば簡単にグラフが表示できると思ってたんですよ。ですが・・・

まず、PySide2 のドキュメントが貧弱すぎる。

例えば QChart のリファレンスがこれです。

クラスのメソッドの羅列のみで、動作の内容がほとんど書かれていない・・。C言語で言えばヘッダしかないようなものです。これでどうやって作れと・・。

幸い、C++ の Qt をかじったことがあったので、C++ のAPIリファレンス(例:QChartのリファレンス)を見たり、ググって先人たちのブログを見ながらなんとか進めることができましたが、これは初学者にはかなりの障壁です。

今でもどうすればよいかわからないことだらけです。例えば QPolygon などのインスタンスをコピーしたい時、C++ でいうコピーコンストラクタが無いっぽいのでどうコピーすればよいかわかりません。copy.deepcopy で Python 的にコピーすれば良いのだろうか・・?

次につまずいたのは、QChart が思っていたほど使えなかった!

QChartのスクリーンショットをみると、簡単にグラフが描けそうじゃないですか。

Qt Charts Overview より引用

左上の Area chart なんてまさにそれ!データさえ揃えれば簡単に書けるでしょ。

と思っていたんですが、なんと、Area chart はポリゴンで書いてます

Qt Charts Overview より引用

↑これを組み合わせて描画しているのよ。まぁ、確かにStacked line chart ではなくて Area chart だから嘘はついてないんだけど、普通積み上げ折れ線グラフに見えますよねぇ・・。

それでもめげずに、Ok、わかったよ、ポリゴンで描けばいいんでしょ。積み上げ部分は自前で計算すればいいんでしょ。と手始めにシンプルな折れ線を描いてみたんですが・・・

QChart でグラフを描いてみた

一見良さそうですよね。

頑張って横軸目盛りを日付にまでしたんですが、致命的な問題が・・・。罫線をキリが良いところに引けない!それどころか領域を何分割するかしか指定できない!

・・・QChart は Excel のように、グラフを静的に描画することに特化しているようで、スクロールさせたりとインタラクティブに使うことは想定していないようです。

横にスクロールさせたら、上のように 4/6 みたいに月の途中から始まりますよね。でも左端に必ず罫線が引かれます。

上記ぐらいのズームレベルだったら、4ヶ月か6 ヶ月位の間隔でキリのいい、x月1日に罫線を引きたいですよね。でも、QChart だとそれはできません。左端と右端をx個で分割したところにしか罫線が引けないのです。

と、ここで心が折れまして、QChart は諦めて、QGraphicsView / QGraphicsScene を使って自分でグラフを描くことにしました。もともとポリゴンで描くからグラフ部分だけなら QGraphicsScene でも労力は変わらないし。軸の目盛りと罫線を自分で描く手間は増えるけど。

ということでできたのが、冒頭のスクリーンショットです。ちゃんと6ヶ月毎に罫線が引けてますよね。ズームすれば1ヶ月や1週間単位などの罫線に切り替わります。

なんか随分遠回りしてしまったような気がします。グラフ描画ライブラリを調べてみると JavaScrpt の Chart.js というライブラリを使えば積み上げ折れ線グラフも簡単に書けるらしいです。

QtQuick (QML) で Chart.js を使うための qchart.js というライブラリもあるようなので、これを使ったほうがグラフ部分は簡単に作れたのかもしれないですね。Javascript + CSS のほうが見た目のカスタマイズもしやすいでしょうし。失敗したかなぁ。

ただ、QtQuick 使ったことなくて、日本語の情報も少ないんですよね。Qt自体はよくできたフレームワークと思っていて個人的には好きなんですけど、日本語の情報が少ないのがもったいないですね。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です