Chart.jsでおしゃれでかっこいいチャートを実装する
この記事で行うこと
チケットの予約情報をチャートで表示します。
使うもの
前提
以下を完了していること。
現場では?
管理画面でよくチャートが使われます。 Chart.jsは導入もシンプルですので人気なライブラリです。
難しいのはチャートに表示させるためのデータを取得する関数や処理です。
実装手順
Chart.jsのインストール
Gemfile
gem 'chart-js-rails'
bundle install
Javascriptを使うのでwebpackerを導入します。 Railsアプリにwebpackerの導入 - さがえもん を見て導入をしてください。
app/assets/javascripts/application.js
//= require bootstrap //= require Chart.min # 追加 //= require_tree .
# 追加
の文字は削除してください。エラーが発生します。
チャートの表示
- チケットの詳細ページを作成
詳細ページへのリンクを追加します。
app/views/tickets/index.html.haml
.col-xs-12 %table.table %thead %tr ・・・ %th # 追加 %tbody - @tickets.each.with_index(1) do |ticket, index| %tr ・・・ %td.text-center= link_to '詳細', ticket, class: 'btn btn-block' # 追加
showページに表示するticketを取得します。
app/controllers/tickets_controller.rb
def show @ticket = Ticket.find(params[:id]) end
チケット詳細ページの要素を追加します。
app/views/tickets/show.html.haml
.col-xs-12 .page-header %h3 チケット概要 %table.table %thead %tr %th チケット名 %th 内容 %th.text-center チケット販売可能枚数 %th.text-center 締切日 %tbody %tr %td= @ticket.title %td= @ticket.body %td.text-center= @ticket.number %td.text-center= @ticket.expired_at .page-header %h3 チケットデータ
- チャートを表示
app/views/tickets/show.html.haml
.page-header %h3 チケットデータ -# 追加(開始位置) .ticket-show-chart-wrapper %canvas{ id: 'chart', width: '900', class: 'chart' } = javascript_pack_tag 'ticket-show-chart' -# 追加(終了位置)
グラフの拡大阻止
.ticket-show-chart-wrapper
でラップしてあげることでグラフが拡大するのを避けられます。
グラフの描画点
canvas
と id: 'chart'
がグラフの描画位置を示します。
** jsの呼び出し
javascript_pack_tag
で対象のグラフを呼び出します。
呼び出すJSコードの設定です。 ajaxでサーバーと通信をしています。 通信対象のアクションはtickets#showです。
app/javascript/packs/ticket-show-chart.js
showScoreChart(); // 関数化 function showScoreChart() { $.ajax({ type: 'GET', url: `/tickets/${$('.page-header').attr('ticket-id')}`, dataType: 'JSON', success: function(data) { // 描画位置の取得 var context = document.getElementById('chart').getContext('2d'); // 背景カラーの用意 var graphColorArray = ['rgba(244, 143, 177, 0.6)', 'rgba(255, 235, 59, 0.6)']; // チャートデータの生成 var myChart = new Chart(context, { // 円グラフを指定 type: 'pie', data: { // チャート上部のラベル labels: data.gender_names, datasets: [{ data: data.genders, backgroundColor: graphColorArray, // グラフカラー pointBackgroundColor: '#ffffff' // 背景カラー }] }, // チャートのオプション設定 options: { responsive: true, // レスポンシブ設定 maintainAspectRatio: false, // アスペクト比の維持設定 } }); } }); };
通信アクションのtickets#showを実装します。 formatを使って、htmlとjsonで返せるようにします。
app/controllers/tickets_controller.rb
def show @ticket = Ticket.find(params[:id]) respond_to do |format| format.html format.json do render json: { gender_names: Users::Profile.genders_i18n.invert.keys, # genderの属性名 ['男性', '女性'] genders: @ticket.deliveries.genders } end end end
@ticket.deliveries.genders
でそのチケットを予約している男女数を配列で取得します。
app/models/delivery.rb
belongs_to :ticket # ------------------------------------------------------------------------------- # ClassMethods # ------------------------------------------------------------------------------- # # 男女数を配列で返す # # @return ex. [10, 20] # def self.genders genders = [] users = User.where(id: pluck(:user_id)) Users::Profile.genders.keys.each { |gender| genders << Users::Profile.where(user: users, gender: gender.to_sym).count } genders end
最後にルーティングを設定して完了です。
config/routes.rb
resources :tickets, only: %i(new create index show)
動作確認
何人かユーザーを作成し、男女に分けてプロフィールを更新しておいてください。
男性グラフにカーソルを合わせると... 女性グラフにカーソルを合わせると...
参考
Chart.js | Open source HTML5 Charts for your website github.com Chart.js · Chart.js 日本語ドキュメント
ソースコード
質疑応答
コメントしてください。 こんなコード見たいというような要望あれば記事にしますのでそちらもコメントかメッセージください。