ZAICOでは、Android・iOS・Rubyエンジニアを絶賛募集中です! 詳しくは、採用ページをご覧ください。
はじめに
こんにちは!
スナです!
普段は主にzaicoのAndroidアプリ開発を担当してます!
(参考:web系エンジニアがAndroid開発をやってみて衝撃を受けた9つのこと))
で、本日はFedExで私がやったことの紹介をしたいと思います。
FedExはいわゆる社内ハッカソンのことです。
ZAICO社の働き方を支える取組みやツールのご紹介に詳しい説明がありますが、つまり通常業務から離れて、好きなことの開発を1週間じっくり行えるイベントです。
数ヶ月に1度開催されており、今回は5/24(月)〜5/28(金)に開催されました。
ちなみに自分は今回で2回目の参加です。
前回は「Flutterでzaicoアプリを開発してみた」をやりました。
せっかくなのでその時の話も今度記事にしてみようと思います。
で、今回は「在庫数量のグラフ化」をテーマに選んでみました。
理由はグラフが好きだからです。
在庫数量に限ったことじゃないですが、グラフで見ると新しい発見があったりして面白いですよね。
Androidアプリの開発
で、僕はAndroid開発担当なので、まずはAndroidアプリの開発を行うことにしました。
色々とチャート関連のライブラリを調べてみた結果、以下がデファクトスタンダードのようで、自分も利用することにしました。
基本的には【スマホアプリでグラフ】MPAndroidChartまとめの記事の通りに実装すれば大丈夫でした。
そして最終的に完成したグラフがこちらです。
なかなかいい感じですね!
工夫した点について書いておきます。
まず、変更履歴を1日に複数回行っていた時に、その変更たちを集約する必要がありました。
コードはこんな感じになりました。
/** * historiesを日付単位で一意にする * 1日の中で複数回の変更履歴がある場合は最後の変更履歴を採用する */ private Map<Long, InventoryHistory> uniqueByDate(List<InventoryHistory> historiesOldOrder) { Map<Long, InventoryHistory> historiesMap = new HashMap<>(); for (int i = 0; i < historiesOldOrder.size(); i++) { Calendar data = Calendar.getInstance(); data.setTimeInMillis(historiesOldOrder.get(i).getupdatedDatetimeByUser() * 1000); MiscUtils.truncateHour(data); // 最後の要素 if (i == historiesOldOrder.size() - 1) { historiesMap.put(data.getTime().getTime(), historiesOldOrder.get(i)); break; } Calendar nextData = Calendar.getInstance(); nextData.setTimeInMillis(historiesOldOrder.get(i + 1).getupdatedDatetimeByUser() * 1000); MiscUtils.truncateHour(data); // 次のデータが同じ日付だったらスルーする if (data.getTime().getTime() >= nextData.getTime().getTime()) continue; historiesMap.put(data.getTime().getTime(), historiesOldOrder.get(i)); } return historiesMap; }
あと変更がなかった日でも前日と同じ在庫数量を入れることで時系列グラフとして表示できるようにしました。
コードはこんな感じになりました。
while (calendar.compareTo(today) <= 0) { xDateList.add(calendar.getTime()); if (historiesMap.containsKey(calendar.getTime().getTime())) { float quantity = 0; if (historiesMap.get(calendar.getTime().getTime()).getQuantity() != null) { quantity = historiesMap.get(calendar.getTime().getTime()).getQuantity().floatValue(); } xQuantityList.add(quantity); preQuantity = quantity; } else { xQuantityList.add(preQuantity); } calendar.add(Calendar.DAY_OF_MONTH, 1); }
あんまりキレイなコードじゃない気もしますがFedEx期間は一旦動くことを優先します。
(もちろんFedEx期間が終わった後にコードレビューします!)
Webアプリの開発
チャートライブラリのおかげで思ったより早く終わった(およそ3日間)ので、Webアプリの開発も行ってみました。
Web開発のチャート関連ライブラリを調べてみると、Androidとは違って群雄割拠のようです。
最近はHighchartsというライブラリが勢いがありそうでしたが、商用利用が有料だったので今回は見送り。
代わりにChart.jsを利用することにしました。
こちらは無料だし、日本語の情報量が多くて嬉しい。
早速ですが、完成図がこちら。
うん、いい感じですね!
やっぱりグラフで見ると、「そろそろ在庫がなくなりそう!」というのが一目で分かって良いですね!
ちなみに先ほど載せた「1日の変更履歴を集約するコード」はJavaScriptだとこんな感じになりました。
function uniqueByDate(histories) { let historiesByDay = {} for (const history of histories) { const datetime = history.content.inventory_snapshot.updated_datetime_by_user.substr(0, 10) historiesByDay[datetime] = history.content.inventory_snapshot.quantity } return historiesByDay }
JavaScriptの方がスッキリしていいですね。
という訳でWebアプリとAndroidアプリにおいて、在庫数量をグラフ化してみました。
(iOSアプリもそのうちやらないとな、、)
おわりに
ただ、実はまだこれで終わりではなく。
在庫数量をグラフ化しただけだと、まだ以下の問題点があります。
1日の中で入庫と出庫が両方存在する場合、それぞれの数を表現できない。
上記グラフだと入庫と出庫の数を合算しているため、例えば以下の2つの違いを表現できないのです。
- 入庫100個と出庫101個
- 入庫0個と出庫1個
また、仮に在庫数量が1万個などかなり大きい数の場合、変更の大きさが分かりにくくなります。
上記の課題を解決するために、2軸グラフにして、入庫と出庫の数量もグラフに表現する必要があります。
1軸グラフと比べて開発の難易度は上がりそうですが、少し難しいくらいの方が開発のモチベーションは上がりますね!
できるだけ早く開発を完了し、お客様に新機能をお届けできるよう頑張ります!
お楽しみに〜!