[Eve Online 3rd party app] Market Tree Viewの実装 [EOPES制作記]

MarketTreeViewのイメージ
Ruby on Rails

Eve Online 3rd party app のEOPES を作り始めてから約3ヶ月が経ちました。
うまく動かなかったり、どう実装していいのかわからないことだらけでした。

そんな経験からどうやって実装したか、これに悩まされた等 EOPESの製作記を書いていこうと思います。

なお、EOPESとは何か?はこちらからどうぞ。
また、ソースコードも公開しました。EOPESソースコード

さて、今回はRails4 でEve Online の Market Tree Viewを作った時のことを書いていこうと思います。

まずやりたかったことは次の部分のことです。

MarketTreeViewのイメージ

Itemをグループ分けして表示して、▼部分押していくと、下のグループやグループに属するアイテムがでてくるやつです。
とってもよくありそうなやつですね。
実装をメモ書きベースでかいていきます。
(途中途中飛ばしています。最後にコミットログの場所を記載するので、抜けてる部分はそこで補完ということで…)

まずは、プラグイン探しということでいろいろみてみましたが、今回はjstreeというプラグインを使うことにしました。

1.まずは公式サイトよりダウンロード

2.次のファイルを配置

  • vendor/assets/javascripts/jstree.min.js
  • vendor/assets/stylesheets/32px.png
  • vendor/assets/stylesheets/40px.png
  • vendor/assets/stylesheets/jstree.css
  • vendor/assets/stylesheets/throbber.gif

なお、style.css は jstree.cssにリネームしています。

3. app/assets/javascripts/application.js 追記

//= require jstree.min

4. app/assets/stylesheets/application.css 追記

*= require jstree

※ちなみにここではまりました。jstree.min.css を使いたかったので require jstree.min と最初書いたが、なぜか動かず。
しばらく悩み途中の.をなくしたらなぜか動いた。。。 原因はよくわからないが、とりあえず.なしの名前のものを使った。

5. indexを作って次の記載を追加(market_explorer/index.html.erb)

<div id="jstree_categories">
</div>

6. jstreeを呼ぶ(app/assets/javascripts/market_explorer.js)

$(document).ready(function () {
    $('#jstree_categories').jstree({
        'core': {
            'data': {
                'url': function (node) {
                    return '/market_explorer/market_groups';
                }
            }
        },
    });
});

7. controller側の実装

さて、マーケットグループの情報ですが、Eve Online DB の invMarketGroupsに入っています。
また、アイテムの情報は Eve Online DB の invTypeに入ってます。

invMarketGroupには
marketGroupID:自分のID
parentGroupID:親のID (一番上の場合は null がはいってます)
marketGroupName:マーケットグループ名
があります。

また、invTypeにも
typeID : アイテムのID
groupID : マーケットグループID (invMarketGroupのmarketGroupIDと紐付いている)
typeName : アイテム名
があります。

これらの情報を元に次のような感じで情報をとってきました。

class MarketExplorerController < ApplicationController

  #MarketGroup取得 取得
  def market_groups
    root_items = InvMarketGroup.all
    @items = []
    root_items.each do |item|
      v = Hash::new()
      v['id'] = item.marketGroupID
      v['parent'] = item.parentGroupID.nil? ? '#' : item.parentGroupID
      v['text'] = item.marketGroupName
      v['icon'] = false
      @items << v
    end

    #Item取得
    inv_types = InvType.where.not(:marketGroupID => nil)
    inv_types.each do |item|
      v = Hash::new()
      v['id'] = item.typeID + 100000 #idがかぶらないように100000足す
      v['parent'] = item.marketGroupID
      v['text'] = item.typeName
      v['icon'] = false
      v['url'] = "/"
      @items << v
    end
    render json: @items
  end

上記ハマった点は、
・parentGroupIDがnullの時は#に置き換えています。置き換えないと動かなかった。
・Itemをセットするときに ItemのTypeIDとMarketGroupのmarketGroupIDがかぶってしまい動かなかったので、Itemは100000足して被らないようにしています。あとで、使うときは-100000しないといけないけど。。ただ、Item(つまりTreeの末端)のときは100000以上と後々判断に使えるので便利。

ホントはやりたかったこと
・icon は false を設定しているが、各グループのIconを表示したかった。ただ、Eve Image ServerでURLベースでグループのIconを持ってこれなかったため断念。(Itemは提供されているけど、GroupはURLベースではなかった)
・Eve Online の Iconはすべて落とせるので、ローカルに配置して参照すればよい と考えたが、容量が大きいのと、jstreeでローカルIconを表示する方法がいまいちわからず。(無理なのかな。。。絶対できるはずなのでいつかリベンジする)

今回やりたかったことは上記でできた。

あとはItem押したら、イベント起こしてマーケット情報表示するとか 細かい部分 (☓ボタンとか、searchさせるようにとか)作って完成した。

スクリーンショット 2015-04-14 0.53.54

さて、完成と思ったら、Production環境でAssetがうまく表示されない というのはまた別のお話。

上記ソースの 完全版はpull request #5で見られます。

参考文献
Railsでawesome_nested_setとjsTreeでインタラクティブにツリー構造を操作する

コメントはまだありません

コメントを残す

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

AWS
Docker
ECS+ALBの動的ポートマッピングでダウンタイムのないデプロイを試してみた

はじめに 少し前に個人で作成しているWebサービスのインフラにDockerを使い始めました。 複数台 …

スクリーンショット 2016-08-16 0.43.10
AngularJS
クライアントAngularJS サーバーサイドRails5 におけるOmniauth 認証を試してみる

去年にEOPESを公開してから1年半。 初めての外部公開サービスだったが、ソースは結構ごり押し部分も …

スクリーンショット 2016-01-09 20.02.08
Ruby on Rails
Capistrano3を利用してBitbucketプライベートリポジトリにあるRailsアプリをデプロイしてみた

Railsアプリを配置する際、毎回手作業で頑張って配置してきたが、そろそろ自動デプロイを・・・ とい …