えいのうにっき

a-knowの日記です

2012 JavaFX Advent Calendar 11日目・TableView内で棒グラフを表現する

こんにちは!a-knowです。 今日の更新は「JavaFX Advent Calendar 2012」の、11日目のエントリとなります。 Advent Calendarは初挑戦なもので、どうぞお手柔らかに・・・。。(これまでの皆様のエントリで、既に尻込みしてますw)

僕とJavaFX

僕とJavaFXとの関わりを簡単に申し上げさせて頂きますと。。 ちょうど1年ほど前、趣味で作っていたSwingアプリケーションが“改造につぐ改造”でかなりのスパゲッティになってしまっておりまして、 「そろそろ一気に作り直したいなー」と考えていたところにJavaFX 2.0が登場した(目についた)、というのが発端になります。 それじゃあせっかくだし、自分にとって新しい技術で・・・ってんで、FXで作り直したのが今年の5月・・・という、ただそれだけのお話なんですけどね。 (とはいえ何故だか、「はじめようJavaFX 2.x」というテーマで勉強会で登壇させて頂いたこともありましたがw)

もちろん、FXそのものやその考え方(FXMLとか、WebStartとか、cssへの対応とかはステキ!)、今後の展望など、どれをとっても好きなのですが、 それ(アプリケーションの作り直し)以来はあまり情報を追えていないのであまり新しいお話はできない・・・。。 ということで、ここは無理せず、実際に作ったFXアプリケーション「sa-boom!! client」を開発する際に 一番苦労した点について(今振り返ればなんてことはないのですが)、書かせて頂ければと思います。

今回のFXアプリケーションを作る上で一番苦労したところ

sa-boom!! client」は、一言でいうと「iTunesでの再生回数情報を記録し、グラフ化させることができる」アプリケーション。 下記のようなグラフ表示を、TableView内で、させてやりたいと考えていました。

この、

ここの部分が、どうやればいいのかわからなかった!w で、僕は、以下のようにして実現しました〜。

考え方

この棒グラフ的なものを表示させる際に、これを構成している要素に分解して、考えます。今回の場合は以下の3つ。 「大きい方の棒グラフ(赤色)」と「小さい方の棒グラフ(ピンク色)」、そして「再生回数表示」

「大きい方の棒グラフ(赤色)」は、Rectangleを使って以下のように作ることができます。

Rectangle r_to = new Rectangle();
r_to.setWidth(SaboomUtil.calcRectangleWidth(maxWidth, topCount, toCount));
r_to.setHeight(20);
r_to.setFill(Color.RED);

ここで、SaboomUtil.calcRectangleWidth()は再生回数によって変わる棒グラフの高さを計算するメソッドです。 (首位の再生回数による棒グラフの高さ(maxWidth)を1として、2位以降の高さはその再生回数により割合を算出してるだけです。)

続いて、「小さい方の棒グラフ(ピンク色)」も同様に。

Rectangle r_from = new Rectangle();
r_from.setWidth(SaboomUtil.calcRectangleWidth(maxWidth, topCount, fromCount));
r_from.setHeight(20);
r_from.setFill(Color.LIGHTPINK);

そして、「再生回数表示」のLabelを作ります。

Label l;
if (sa > 0) {
    l = new Label(thisCount + " (+" + sa + ")");
} else if (sa == 0) {
    l = new Label(thisCount + " (±" + sa + ")");
} else {
    l = new Label(thisCount + " (" + sa + ")");
}

最後の仕上げ・Groupでこれらの要素をまとめてやることで、棒グラフの完成です。

Group g = new Group();
g.setBlendMode(BlendMode.MULTIPLY);
g.getChildren().add(r_to);
g.getChildren().add(r_from);
g.getChildren().add(l);

setBlendMode(BlendMode.MULTIPLY) を忘れずに。 各要素のadd()は下になるものから順番に行うイメージでしょうか。

あとはこのできた棒グラフを、以下の様なインターフェースを持ったObservableなレコードにセット(ここでの例だとtotalPlayCountに、ですね)してやって、 そのレコードごと、TableViewにaddしてやればOKです(tableView.getItems().add(record))。

import javafx.beans.value.ObservableValue;
import javafx.scene.Group;

public interface ObservableRecordBySong{

    public ObservableValue<Integer> rank();
    public ObservableValue<String> songName();
    public ObservableValue<String> artistName();
    public ObservableValue<String> rating();
    public ObservableValue<Group> totalPlayCount();
}
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Group;

public final class RecordBySong implements ObservableRecordBySong {

    private final SimpleObjectProperty rank;
    private final SimpleStringProperty songName;
    private final SimpleStringProperty artistName;
    private final SimpleStringProperty rating;
    private final SimpleObjectProperty totalPlayCount;

    public RecordBySong(Integer rank, String songName, String artistName, String rating, Group totalPlayCount) {
        this.rank = new SimpleObjectProperty(rank);
        this.songName = new SimpleStringProperty(songName);
        this.artistName = new SimpleStringProperty(artistName);
        this.rating = new SimpleStringProperty(rating);
        this.totalPlayCount = new SimpleObjectProperty(totalPlayCount);
    }

    //アクセサは省略。
}

あとがき

このアプリ、サーバ(Google App Engine)との連携やiTunesプレイリストの出力など、結構色々と頑張ってるつもりですw iTunesユーザーの方でご興味を持たれた方は、ぜひ使ってみて頂きたいです♪

また、メイン技術がサーバーサイドな僕にとってのJavaFXは、クライアントアプリを作る際の貴重な手段。 趣味もかねて、Twitterクライアントアプリなんかを作ってみてもおもしろいかも!なんて、考えています(^^)。

・・・ふぅ。カレンダーのレベル下げ役、これにて終了です。(^^;) お目汚し、失礼しました! 明日はtaizさんによるAdvent Calendar記事です!お楽しみに!

クリスマス直前ハッカソン、『サンタソン』で優勝してきた!

f:id:a-know:20180210154346j:plain

してきました!!うれしーー♪ 会場でもお話させて頂きましたが、「アプリを作る」という一つの目標に、会場にいる全員が向かっているというあの熱気のこもった場所で、 8時間という限られた時間であっても、その時間を参加者の皆様と共有できたこと! そしてその結果をこのような形で飾ることができたこと! 全てがとても、嬉しいです!本当にありがとうございました!

経緯

参加してきたのは、『サンタソン【サンタは俺らに何もくれない!だったら、俺らでアプリを作ろう】』。 「アプリ完成者全員にkindle Paperwhiteをプレゼント!!」「昼食はカレー食べ放題!」という、釣り針の先に付いていたエサがあまりにも魅力的だったことと、 言わずと知れたTwitter4Jの生みの親・@yusukeさんにもお会いできる、ということで、ホイホイ参加してきちゃったのだ!

結果、@yusukeさんとはがっつり楽しくお話させて頂いましたし、カレーも美味しかったし、kindleはちゃんと後日発送されそうだし(僕はないですが)・・・で、まぁそれらの点では良かったのですが・・・。。

このようなハッカソンは初参加でしたが(さらにこんな賞を頂いておいてなんなんですが)、それでも目につくところが多々あったイベントだったように思います。

ぜひ次回以降改善して頂きたい点

ATNDページの地図の示す場所が全然違っていた。

違ってました。開催場所は田町だったのに、ATND上の地図では東京駅付近になっていました。 なんでもATNDの仕様上?あとから修正することができないそうで、そこは仕方がないにしても、 気づいた時点でTwitterやメールなどで周知できたのではないか、と思います。 (実際東京駅に向かって途中まで行ってしまっていた方もいたようです。。)

Twitterなどの活用が不十分。

上の点にも関連するのですが、せっかくハッシュタグも告知しているんですから、 これを使っていろんな連絡事項、盛り上げを図ればいいのに、もったいない。。と、感じました。 「投票はどうするの?」とか「対応しているプロジェクターのコネクタの種類はなんですか?」とか、 「プレゼンは何時からですか?」とか、その場で出ていた疑問は数多くあったと思います。 @yusukeさんも仰っていましたが、「誰かが感じた疑問は、その場全員も持っている疑問」だと思って、 できるだけ多くの人にその答えを届ける努力を、すべきだったように思います。

イベント運営の体制

とまぁ、イベントの趣旨がステキなだけに、全体的に「もったいない」感じが漂っていたわけですが、 どうやら今回のイベントは主催の企業様の新卒社員の方がメインで運営して頂いていたようです。 もちろん、こういうイベントを主催することは多くの学びがあるだろうし、 初めてであれば失敗すること、うまくいかないこともあるかと思います。

ただ、やはりそれも「責任者によるしっかりとしたコントロールの下で」、で行われるべきだと思います。 「イベントの成否を揺るがしかねない致命傷となる前に、責任者がしっかり軌道修正してあげる」、のが正しい姿であって、 「イベント、失敗しちゃったな。でも、学ぶべきことがたくさんあっただろ?」では、 責任者がいる意味がなくないでしょうか。

実際、今回のこのイベントは結構ギリギリだったのではないかと思います。。(´・ω・`) (ちなみに、「喫煙は下のファミマでお願いします」って言ってましたけど、  あれってちゃんと許可済みだったんでしょうか。。)

著作権等譲渡契約書」?!

そして何より一番大きな衝撃を受けたのが、受付と同時に渡された「著作権等譲渡契約書」。 これは、このハッカソンで出来たアプリのソースコード等一式を、 開発者の方さえ良ければ(ここは再三、強調されてましたが)著作権等をウチに譲渡してね!ということに了承を求める、というもの。

まぁ、タダでKindleをもらえる上に昼ごはんまで食べられる、それだけで「何かはあるんだろうなー」とは思っていましたが、 ・・・なかなかどうして、想像のナナメ上でした。

そういったことが事前に告知の上のことであれば、100歩譲っても良しとしましょう。 ただ、そういった告知は一切なし(「告知ページには小さく書いてます」とか仰っていましたが、帰宅して見てみてもそのような記述は見当たりませんでした)で 当日いきなりそんな条件を提示するのは、イカンでしょう。

僕は法律に疎いので「え・・・なにこれ。。」ぐらいなもんだったんですが、これは法律的に見てもそうとうなアレだったようで、 参加者の中には、ハッカソンを楽しむための開発ではなく、このことがいかにおかしなことか、を示すアプリを作って、プレゼンされた方もおられました(´・ω・`)。 これは本当に不幸なことだと思います・・・ご本人はケロっとしておられましたが。 真の勝者・・・勇者は、確かに僕とは別にいました。

こういった点、是非次回への反省につなげて頂ければと思います(´・ω・`)。 (@yusukeさんも、今回のことをトゥギャっておられます。)

つくったもの

・・・で、このハッカソンの、実質6時間で、僕が作ったものは 以下のものになります。

「ゆめにっきオンライン」・・・、、完全な名前負け感がありましたがw

アプリ自体は、極めて短時間での急ごしらえだったということもあり、ちょっとお行儀の悪いことをしているため、一時的に停止させています。 なので、一旦はスクリーンショットだけ。。

仕事がサーバーサイドなエンジニアということもあり、スマホ向けのネイティブなアプリなんて僕には短時間じゃ作れないよ! ということで、「日記を書く」という、ただでさえ地味な発想をただただ実直にWebアプリにした、という作品だったわけで、 ARとかGPSとか、「スマホであること」をフル活用した他の方々の作品にも申し訳ない・・・、という感じだったんですが。

ホントは「ゆめにっき」に書いたことをTwitterに投稿したり、 逆にTwitterに「ゆめにっき:ライオンに食べられる夢をみた!」とか書けば、ゆめにっきがそれを拾って自動で記録する、・・・とかも考えていたんですが、 まー時間が足りないったらありゃしないw

こういった機能追加も、いつかできるといいですね・・・できるかなぁ?w

オマケ

ハッカソン会場に来ていた、某Anonymousな方に、Anonymousマスクを頂いちゃいました☆

地味にうれしいw

Mashup Award #8に応募したよ!

こんにちは!a-knowです。 この度、 「ツイート内容感情解析サービス」として、「Emornal(エモーナル)」という Webアプリを作成し、それを「Mashup Award #8」に応募しました!

ツイート内容感情解析サービス「Emornal」

どういうサービス?

メタデータ株式会社様ご提供の「感情解析API」を用いて、登録ユーザーの一日のツイートを感情解析。 その結果を、「晴れ(良い)」「曇り(普通)」「雨(悪い)」の3パターンに分類し、 日記としてカレンダー上にマッピングする、ということをしてくれる、簡単なWebサービスです。 このサービス名は、「Emotion(感情)」と「Journal(日記)」を掛け合わせた造語です。

きっかけとか。

参加のきっかけ

前々からこういうコンテストには参加したいと思っていたのが第一にはあるのですが。。 Mashup Awardの存在自体を知ったのが、前回の第7回が終わった直後だったので、 「よぉし、次回は絶対に参加するぞ!」と心に決めていた、というのが大きいです。 決して十分な時間を割けることができる環境があったわけではない中、 その決心通りに(たいしたものではないにしても)作品を完成させ応募することができたのは、よかったなぁと思っています。

このサービスを作ったきっかけ

もともとライフログっぽいものが好きなのがやっぱり大きいですね。 あとは、公式サイトのAPI一覧眺めていて、単純に「このAPI、おもしろそうだなぁ」と思った。それぐらいです。笑 あ、そもそも自分が「こういうのが欲しいなぁ、あったらなぁ」と思えていたのが 何よりの原動力であったことは、言うまでもないです!

作ってみて思ったこと

いくつか前のエントリでも書いたとおり、Web系ベンチャーのサーバーサイドエンジニアに 転職したわけなんですが、ほんと毎日が学ぶことばっかりで。 「こうして身につけたことを実際に使って、何か作りたい!」、そして「作ったったった!!」、 ・・・なんていうか、自己完結な表現ですけど、超気持ち良かったです。笑

とはいえ、今回作ったこのサービスは大して難しいことをしているわけでもないし (多分転職前の実力でも作れたと思う・・・笑)、 当然これぐらいで満足しているわけではないのですが、 「業務で身につけたものを使って何かを作り、またそこでも学ぶものがあった」、 というこのいいサイクルは、今後も続けていきたいなぁと思いました! (今まで作ったすべてのものについても、  「今の自分が作れば、きっと何倍もイイものが作れる!」っと思えてますし、ね!)

とはいえ、こんどはあまり〆切りに縛られず、のびのび作りたいなぁと感じたのも 事実です。。笑

おまけ

このMashup Award、別にこの開催期間に作られたものでなくても 応募してよさそうな感じだったので、 今年3月に作った「Masterpiece」も、ついでにエントリーしといてみました。

とはいえ、別に賞とかは比較的どうでもよくて(そりゃ評価されればウレシイですが)、 これをきっかけに僕や僕のつくったものに興味を持って下さる方が 一人でも増えてくれたらいいなぁという気持ちです。

さて、次は何を作ろうかなぁ?