[RUBY] [Personal application work memo] How to display a bar graph and a line graph in one graph

What I did this time

We have already created a bar graph with dates on the x-axis and calories on the Y-axis, and we will add a line graph of weight to the Y-axis. スクリーンショット 2020-08-22 午後8.04.20.png

Preparation before graph implementation

Added weight input form

python


.weight
body weight
  = f.number_field :weight, step: '0.1', placeholder: 'Example) 70'
  kg

スクリーンショット 2020-08-21 午後3.48.55.png

Added column to store weight

https://qiita.com/azusanakano/items/a2847e4e582b9a627e3a#%E3%82%AB%E3%83%A9%E3%83%A0%E8%BF%BD%E5%8A%A0 You can do it immediately by referring to this article.

スクリーンショット 2020-08-21 午後3.54.13.png

Added weight column to strong parameters

posts_controller.rb


private
  def post_params
    params.require(:post).permit(:food, :calorie, :protein, :fat, :carbo, :text, :image, :weight).merge(user_id: current_user.id)
  end

Show weight

ruby:_post.html.haml


.weight
- if post.weight.present?
  = post.weight
  kg

Actual page (this is what it looks like when displayed)

スクリーンショット 2020-08-22 午後8.02.51.png

Finally add weight to the graph !!

Now, how do you put this added weight on the graph from here?

What is the current graph like? スクリーンショット 2020-08-22 午後8.04.20.png

At present, only weight is horizontal and calories are vertical. I would like to add a line graph of weight to the vertical here so that I can see the correlation between calories and weight.

↓ A reference article was found rather quickly, and it was surprisingly completed in an hour.

Click here for the completed code

app/controllers/charts_controller.rb


class ChartsController < ApplicationController

  def index
    #calorie
    #Calculate total calories by date
    sum_calorie = current_user.posts.group("date(created_at)").sum(:calorie)
    #Since the total calories for each date is in the form of a hash, get the value, put it in an array and assign it to a variable
    array_calorie = sum_calorie.values

    #Pass data to js side using gon
    gon.data = []
    #Extract the total calories by date one by one with the map method
    #How to use map method → Array variable.map {|Variable name|Specific processing}
    gon.data = array_calorie.map{ |calorie| calorie}

    #Created by date_Get only at column. Stored in the form of an array
    dates_calorie = current_user.posts.group("date(created_at)").select(:created_at)

    gon.date = []
    @dates = dates_calorie.map{ |dates| dates.created_at}
    #Take out and change the date notation one by one in each statement
    @dates.each do |a|
      gon.date << a.strftime("%Y year%m month%d day")
    end


    #Weight ☆ This part was added this time ☆
    gon.weight = current_user.posts.group("date(created_at)").select(:weight).map{ |weight| weight[:weight]}
  end
end

ruby:app/view/charts/index.html.erb


<%#Draw a graph inside the canvas tag%>
<div class="chart-container" style="position: relative; height:50vh; width:50vw">
    <canvas id="myChart"width="400" height="400"></canvas>
</div>

<%#Write js in the html script tag%>
<script>
#Get the DOM of the graph part and draw the graph with the getContext method
var ctx = document.getElementById("myChart").getContext('2d');

var myChart = new Chart(ctx, {
    
    type: 'bar',
    data: {
        #Specify X axis with labels
        labels: gon.date,
        datasets: [{
            type: 'bar', #Calories are bar graph
            label: "Total daily calories",
            #Specify Y axis with data
            data: gon.data,
            backgroundColor: 'rgba(75, 192, 192, 0.2)',
            borderColor: 'rgba(75, 192, 192, 1)',
            borderWidth: 1,
            fill: false
        },
    #This time I added this part----------------------------
        {
            type: 'line', #Weight is a line graph
            label: "body weight",
            #Specify Y axis with data
            data: gon.weight,
            backgroundColor: 'rgba(255, 99, 132, 0.2)',
            borderColor: 'rgb(255, 99, 132)',
            borderWidth: 1.2,
            #If you do not write this, the lower part of the bar will be painted
            fill: false,
        }]
    #------------------------------------------------------
    },
    options: {
        title:  {
            display: true,
            text: "Calorie graph"
        },
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                },
                id: 'y left axis'
            }]
        }
    }
});

</script>

<div class="home">
    <%= link_to 'Return to home', root_path %>
</div>

Click here for the completed graph

スクリーンショット 2020-08-22 午後9.10.30.png

Referenced articles and process to completion

http://www.dcom-web.co.jp/lab/javascript/draw_multi_axis_graph_using_chartjs This page was the first reference.

  1. Instead of passing it with gon suddenly, at first I tried to see if it was displayed with an appropriate number such as [60, 70] referring to the above article.
  2. After confirming that it worked and the graph was displayed safely, I wondered how to transfer the weight from the controller to the view.
  3. I thought it would be difficult to get one weight in a day, but I found that Rails' group method would group them into the one with the lowest id for each group. If you use the group method for each date, you can get the weight with the smallest id among the posts posted that day. https://pikawaka.com/rails/group#group%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E5%9F%BA% E6% 9C% AC% E7% 9A% 84% E3% 81% AA% E4% BD% BF% E3% 81% 84% E6% 96% B9
  4. After that, substitute it for gon and pass it from gon to gon.
  5. Finally, add fill: false, to make a line and finish.

Recommended Posts

[Personal application work memo] How to display a bar graph and a line graph in one graph
How to display a graph in Ruby on Rails (LazyHighChart)
[Personal memo] How to interact with a random number generator in Java
[Android application development] How to display in full screen (notification bar hidden)
How to display a web page in Java
[Personal application work memo] Make a calendar with simple_calendar
How to display a browser preview in VS Code
How to convert A to a and a to A using AND and OR in Java
How to specify character code and line feed code in JAXB
How to set character code and line feed code in Eclipse
How to store a string from ArrayList to String in Java (Personal)
How to develop and register a Sota app in Java
How to write ruby if in one line Summary by beginner
How to increment the value of Map in one line in Java
How to display characters entered in Spring Boot on a browser and reference links [Introduction to Spring Boot / For beginners]
How to test a private method in Java and partially mock that method
How to implement a slideshow using slick in Rails (one by one & multiple by one)
Draw a bar graph and a line graph at the same time with MPAndroidChart
How to display error messages and success messages when registering as a user
Trial and error to display national holidays in Android application development. Part 1
How to migrate a web application created in a local docker environment to AWS
How to display the text entered in text_area in Rails with line breaks
How to insert a video in Rails
[Personal] JUnit5 memorandum memo (work in progress)
How to embed Janus Graph in Java
How to publish a library in jCenter
Display message dialog in java (personal memo)
How to display error messages in Japanese
Let's create a TODO application in Java 9 Create TODO display Sort by date and time + Set due date default to today's date
[Java] [POI] Create a table in Word and start a new line in one cell
A memo to simply create a form using only HTML and CSS in Rails 6
How to ZIP a JAVA CSV file and manage it in a Byte array
(Memo) How to solve dummy output in Ubuntu 20.04
[Rails] How to create a graph using lazy_high_charts
How to run a djUnit task in Ant
How to add a classpath in Spring Boot
How to create a theme in Liferay 7 / DXP
How to implement a like feature in Rails
How to easily create a pull-down in Rails
How to make a follow function in Rails
How to automatically generate a constructor in Eclipse
A memo about the types of Java O/R mappers and how to select them
How to implement a circular profile image in Rails using CarrierWave and R Magick
How to clear all data in a particular table
How to set the display time to Japan time in Rails
How to implement a like feature in Ajax in Rails
How to create a Spring Boot project in IntelliJ
How to make JavaScript work on a specific page
[Personal memo] Make a simple deep copy in Java
How to create a data URI (base64) in Java
Display a loading image in JavaFX and then display another image
How to launch another command in a Ruby program
[How to insert a video in haml with Rails]
How to write a date comparison search in Rails
How to store Rakuten API data in a table
How to mock a super method call in PowerMock
How to generate / verify ID token in Java Memo
How to handle TSV files and CSV files in Ruby
How to convert a file to a byte array in Java
[Rails 6] How to set a background image in Rails [CSS]
[Rails] How to load JavaScript in a specific view