[Rails] chart.js에서 Rails 앱에 게시물 추이 그래프 그리기 [chart.js]

소개



이번에 Ruby on Rails의 학습을 시작했습니다. 아직 초학자이지만, 매일의 배움이나 눈치채고, 에러와의 싸움을 여기에 기록해 가고 싶습니다. 요청, 지적도 기다리고 있습니다!

기사 개요



앱에서 취급되는 데이터를 시각화할 수 있다면, chart.js를 사용하여 Rails 앱에 그래프를 그려 보겠습니다.
1. chart.js의 도입 순서
 2. 기사 투고수의 추이 그래프를 그려 본다

chart.js란?



JavaScript로 구현된 그래프를 Rails 앱에 통합할 수 있는 라이브러리입니다.
공식
htps //w w. 찬 rtjs. 오 rg / cs / st /

1. chart.js의 도입 순서



Gemfile에 기술한다.

Gemfile
gem 'chart-js-rails', '~> 0.1.4'

그리고 터미널에서 bundle install을 실행한다.
% bundle install

package.json에 다음과 같이 추가.

package.json
{
  # 省略
  "dependencies": {
    #省略
    "chart.js": "^2.7.1" # ←ここに追記
  }
}

그리고 터미널에서 yarn install을 실행.
% yarn install

2. 기사 투고수 추이 그래프를 그려 본다



여기에서는, 어느 Article 모델의 투고수 추이에 대해서, Articles 컨트롤러로 데이터를 가공해 articles#index에 그래프 묘화 하는 것을 목표로 합니다.
가로축이 날짜, 세로축이 투고수입니다. 덧붙여 일시 데이터를 취급하는 "groupdate"gem은 도입 완료로서 진행합니다.

우선, 그래프 묘화의 기본 구성은 아래와 같습니다. 공식 페이지 의 샘플 참조.

app/views/articles/index.html.erb
<canvas id="myChart" width="200" height="100"> </canvas>

<script> 
    var ctx = document.getElementById("myChart").getContext('2d');
    var myChart = new Chart(ctx, {
        type: 'bar',                      # 'bar'でグラフタイプを縦棒グラフに指定 
        data: {
            labels: <%= @chartlabels %>,  # 横軸にとるデータ(今回は投稿日付)を埋め込む
            datasets: [{
                label: "投稿数",
                data: <%= @chartdatas %>, # 縦軸にとるデータ(今回は投稿数)を埋め込む
                backgroundColor: 'rgba(255, 80, 120, 1.0)',
                borderColor: 'rgba(255, 80, 120, 1.0)',
                fill: false
            }]
        },
    });
</script>

그래프에 건네주는 데이터를 articles_controller로 준비합시다. 인스턴스 변수를 정의합니다.

app/controllers/articles_controller
class ArticlesController < ApplicationController
  def index
    @articles = Article.all

    @article_by_day = @articles.group_by_day(:created_at).size
    # groupdateのgroup_by_dayメソッドで投稿日(created_at)に基づくグルーピングして個数計上。 
    # => {Wed, 05 May 2021=>23, Thu, 06 May 2021=>20, Fri, 07 May 2021=>3, Sat, 08 May 2021=>0, Sun, 09 May 2021=>12, Mon, 10 May 2021=>2}

    @chartlabels = @article_by_day.map(&:first).to_json.html_safe
    # 投稿日付の配列を格納。文字列を含んでいると正しく表示されないので.to_json.html_safeでjsonに変換。
    # => "[\"2021-05-05\",\"2021-05-06\",\"2021-05-07\",\"2021-05-08\",\"2021-05-09\",\"2021-05-10\"]"

    @chartdatas = @article_by_day.map(&:second)
    # 日別投稿数の配列を格納。
    # => [23, 20, 3, 0, 12, 2]
  end
end

Rails 앱을 기동해/index에 액세스하면 세로 막대 그래프가 그려지고 있다.


다음으로, 누계 투고수를 꺾은선 그래프로 해, 방금 전의 그래프에 거듭해 보겠습니다.

app/views/articles/index.html.erb
<canvas id="myChart" width="200" height="100"> </canvas>

<script> 
    var ctx = document.getElementById("myChart").getContext('2d');
    var myChart = new Chart(ctx, {
        type: 'bar',                      
        data: {
            labels: <%= @chartlabels %>,  
            datasets: [{
                label: "日別投稿数",
                data: <%= @chartdatas %>, 
                backgroundColor: 'rgba(255, 80, 120, 1.0)',
                borderColor: 'rgba(255, 80, 120, 1.0)',
                fill: false
            },{ //ここから追記
                label: "累積投稿数",
                data: <%= @cumulative %>, // 縦軸にとる累積投稿数データを埋め込む
                backgroundColor: 'rgba(255, 80, 120, 0.2)',
                borderColor: 'rgba(255, 80, 120, 1.0)',
                type: 'line', // 'line'でグラフタイプを折線グラフに指定
            }]
        },
    });
</script>

누적 게시물 데이터를 배열로 하여 인스턴스 변수로 준비합니다.

app/controllers/articles_controller
class ArticlesController < ApplicationController
  def index
    @articles = Article.all

    @article_by_day = @articles.group_by_day(:created_at).size

    @chartlabels = @article_by_day.map(&:first).to_json.html_safe

    @chartdatas = @article_by_day.map(&:second)

    # ここから追記
    @cumulative = []
    sum=0
    @chartdatas.each do |a|
      sum = sum + a
      @cumulative<<sum
    end
  end
end

앱을 시작하고/index에 액세스하면 선 그래프도 표시되었습니다.



요약



chart.js를 활용해, 기사 투고수 추이 그래프를 세로 막대+꺾은선 그래프로 표현할 수 있었습니다. 데이터베이스에서 가공한 데이터를 그래프로 표현할 수 있으므로, 앱의 관리자 기능, 가시화 등 폭넓게 활용할 수 있을 것 같습니다. 커스터마이즈도 유연하게 할 수 있을 것 같기 때문에, 향후도 기사로 취급하고 싶습니다.
Ruby에서의 데이터 가공(더 간결하게 할 수 있을 것 같다)과 JavaScript 기술의 좋은 트레이닝도 되었습니다.

좋은 웹페이지 즐겨찾기