[JAVA] [Rails 6] Dessin graphique interactif avec Ajax + chart.js

Cette fois, nous allons implémenter une fonction de graphique simple dans Ruby on Rails en utilisant ajax et chat.js. À titre d'exemple, dessinons le record de croissance de la personne sélectionnée dans le menu déroulant. (Axe horizontal: date d'enregistrement, axe vertical: hauteur) La version Rails est la 6.0.3.3. 身長.gif

Notez s'il vous plaît

définition de table

Nom de colonne fi Description de la colonne Type de données
id ID integer
name Nom string
height la taille float
rec_date Date d'enregistrement de la hauteur date
created_at Date d'inscription datetime
updated_at Date de mise à jour datetime

Cette fois, les données d'enregistrement de hauteur pour deux personnes sont enregistrées dans seeds.rb.

Préparation

Ajouté à Gem

Gemfile


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

Ajouter un paquet avec du fil

command


yarn add jquery chart.js

Être capable de gérer jQuery

config/webpack/environment.js


const { environment } = require('@rails/webpacker')
//Rendre jquery disponible
const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery'
  })
)
module.exports = environment

Chargement du module chart.js

app/javascript/packs/application.js


// chart.Ajouté pour l'utilisation de js
require("chart.js")

Créer un modèle

command


rails generate model Height name:string height:float rec_date:date
rails db:migrate

Création et saisie des données initiales

seeds.rb


Height.create!(
  [
    {
      name: 'Takashi',
      height: 150.3,
      rec_date: "1990-01-03",
    },
    {
      name: 'Takashi',
      height: 168.3,
      rec_date: "1996-03-03",
    },
    {
      name: 'Takashi',
      height: 178.4,
      rec_date: "2003-04-03",
    },
    {
      name: 'neige',
      height: 130.3,
      rec_date: "1987-05-07",
    },
    {
      name: 'neige',
      height: 144.1,
      rec_date: "1995-04-23",
    },
    {
      name: 'neige',
      height: 153.6,
      rec_date: "2000-05-13",
    },
  ]
)

command


rails db:seed

Créer un contrôleur

Préparez une action d'index et une action de recherche dans chart_sample_controller.rb. L'action de recherche est une action pour recevoir une transmission de requête en utilisant $ .ajax () et retourner les données de hauteur correspondant au nom au format json en recherchant dans le modèle.

command


rails generate controller ChartSample index search

À ce stade, nous avons créé les packages, les gemmes, les modèles et les contrôleurs nécessaires. Ensuite, préparez les paramètres et les vues de l'itinéraire.

Paramètres et vues de l'itinéraire

Réglage de l'itinéraire

config/routes.rb


Rails.application.routes.draw do
  get 'chart_sample/index'
  get '/chart_sample/search', to: 'chart_sample#search'
end

Views Le fichier js est lu avec javascript_pack_tag, mais ici le script qui dessine le graphique en utilisant Ajax + chart.js est écrit en jQuery. Le fichier js est décrit dans ʻapp / javascript / packs / chart_sample / chart_user_height.js`.

html:app/view/chart_sample/index.html.erb


<h1>Record de croissance</h1>
<div class="contents">
  <select id="area">
    <option value="0">Veuillez sélectionner</option>
    <option value="1">Takashi</option>
    <option value="2">neige</option>
  </select>
</div>

<div class="canvas">
  <canvas id="myChart" width="400" height="400"></canvas>
</div>

<%= javascript_pack_tag 'chart_sample/chart_user_height' %>

L'écran d'affichage ressemble à ceci: Lorsque c'est fait, sélectionnez le nom dans le menu déroulant → le graphique de l'enregistrement de croissance s'affiche ci-dessous. スクリーンショット 2020-09-30 16.24.35.png

Ajax+chart.js Le code ici est long, je vais donc l'expliquer étape par étape et coller le code source ensemble à la fin.

app/javascript/packs/chart_sample/chart_user_height.js (1)


$(document).on('turbolinks:load', function () {
  $(function () {
    //Chargez votre propre fonction pour l'affichage du graphique
    var chart_func = require("../origin_func.js")
    $('#area').change(function() {
      var selected_name = $('option:selected').text();
      var selected_index = $('option:selected').val();

Ici, afin d'éviter le phénomène que jQuery ne fonctionne pas correctement en raison de la transition de page due à l'influence d'Ajax, etc., turbolinks: load est mis à feu à la fois lors du premier chargement et lors du rechargement. ʻOrigin_func.js` charge une version fonctionnelle de la fonction de dessin de graphique par chart.js. Cela sera expliqué plus tard. L'index de la boîte de sélection de la vue précédente est défini comme «index_sélectionné» et le nom est défini comme «nom_sélectionné».

app/javascript/packs/chart_sample/chart_user_height.js (2)


      if (selected_index > 0) {
        //Envoyer une requête pour la valeur de SelectBox au format json en utilisant ajax
        // messages/Reçu par l'action d'index du contrôleur de recherche
        $.ajax({
          type: 'GET', //Type de demande
          url: '/chart_sample/search', //URL pour envoyer la demande
          data:  { name: selected_name }, //Données à envoyer au serveur
          dataType: 'json' //Type renvoyé par le serveur
        })

Ici, selected_index> 0, c'est-à-dire ce qui est traité lorsque le nom (dans ce cas," Takashi "ou" Yuki ") est sélectionné. Envoyez le nom obtenu en utilisant $ .ajax () au contrôleur. Selon le paramètre d'itinéraire ci-dessus, il sera envoyé à l'action de recherche de chart_sample_controller.rb. Cette section décrit le contenu de l'action search du contrôleur qui a reçu la requête avant la suite de chart_user_height.js.

app/controllers/chart_sample_controller.rb


class ChartSampleController < ApplicationController
  def index
  end

  def search
    #↓ Code de traitement de la recherche(Une liste de résultats de recherche est saisie)
    @height = Height.where('name = (?)', "#{params[:name]}").order(rec_date: "ASC")    

    respond_to do |format|
      #Si le format demandé est le format HTML
      format.html { redirect_to :root }
      #Si le format demandé est le format JSON
      format.json { render json: @height }
    end
  end
end

Dans l'action search, la requête (nom de la personne) envoyée par Ajax plus tôt est stockée dans les paramètres [: name], donc une recherche de correspondance est effectuée dans le modèle Height, et la rec_date du contenu renvoyé par le modèle est recherchée. Trié par ordre chronologique. En effet, l'axe horizontal sera défini sur rec_date plus tard lors de l'affichage du graphique dans chart.js. La requête étant faite au format JSON, format.json est exécuté et les résultats de la recherche sont renvoyés au format JSON. Si c'est difficile à comprendre, essayez de déboguer avec binding.pry etc. et il sera plus facile d'obtenir une image. Revenons au fichier js et regardons le processus de dessin.

app/javascript/packs/chart_sample/chart_user_height.js (3)


        //Recevoir une demande d'ajax
        .done(function (data) {
          var height_val = [];
          var height_name = [];
          var height_date = [];
          // chart.Stocker dans un tableau pour passer à js
          $(data).each(function(index, height) {
            height_name.push(height.name);
            height_val.push(height.height);
            height_date.push(height.rec_date);
          });
          chart_func.bar_chart(document, 'myChart', "la taille", height_date, height_val);
        })
      }
    })
  });
});

Ici, le format JSON reçu du modèle est converti en type tableau afin de le transmettre à chart.js. Par exemple, height_val contient les hauteurs passées de Takashi sous forme de tableau [(height), (height), (height)]. (Je pense qu'il y a une meilleure façon de l'écrire un peu plus clairement ...) Ensuite, transmettez-le à la fonction auto-créée qui lit le tableau contenant les données de date et les données de hauteur. La fonction auto-créée instancie Chart avec chart.js. Les arguments passés à la fonction sont chart_func.bar_chart (document, nom de l'identifiant de la balise canevas, nom de l'étiquette à attacher au graphique (facultatif), tableau de données d'axe horizontal, tableau de données d'axe vertical).

Traitement des représentations par chart.js

app/javascript/packs/origin_func.js


exports.bar_chart = function (document, id_name, label_name, data_x, data_y) {
    var elm = document.getElementById(id_name).getContext('2d');
    //Supprimer l'instance si le graphique est déjà dessiné
    if(myChart.constructor === Chart){
        myChart.destroy();
    };
    //Représentation du graphique à barres
    myChart = new Chart(elm, { 
        type: 'bar',
        data: {
            labels: data_x,
            datasets: [{
                label: label_name,
                data: data_y,
                borderWidth: 1
            }]
        },
        options: {
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            }
        }
    })
};
if(myChart.constructor === Chart){
        myChart.destroy();
    };

Si le canevas est réutilisé, le graphe sera superposé sur le graphe précédent, donc si une instance de Chart a déjà été créée, utilisez Chart.destroy pour décrire la description par l'instruction ʻifici. C'est parce qu'il doit être supprimé. Au moment du chargement,myChart.constructor devient Chart lorsqu'une instance est créée à partir de HTMLCanvasElement. Les autres créent des instances de graphique basées sur les données du tableau. C'est tout pour la mise en œuvre. J'ai expliqué chart_user_height.js` par intermittence, je vais donc le coller ci-dessous.

app/javascript/packs/chart_sample/chart_user_height.js (collectivement)


$(document).on('turbolinks:load', function () {
  $(function () {
    //Chargez votre propre fonction pour l'affichage du graphique
    var chart_func = require("../origin_func.js")
    $('#area').change(function() {
      var selected_name = $('option:selected').text();
      var selected_index = $('option:selected').val();
      if (selected_index > 0) {
        $("h1").css("color", "blue");  
        //Envoyer une requête pour la valeur de SelectBox au format json en utilisant ajax
        // messages/Reçu par l'action d'index du contrôleur de recherche
        $.ajax({
          type: 'GET', //Type de demande
          url: '/chart_sample/search', //URL pour envoyer la demande
          data:  { name: selected_name }, //Données à envoyer au serveur
          dataType: 'json' //Type renvoyé par le serveur
        })
        //Recevoir une demande d'ajax
        .done(function (data) {
          var height_val = [];
          var height_name = [];
          var height_date = [];
          // chart.Stocker dans un tableau pour passer à js
          $(data).each(function(index, height) {
            height_name.push(height.name);
            height_val.push(height.height);
            height_date.push(height.rec_date);
          });
          chart_func.bar_chart(document, 'myChart', "la taille", height_date, height_val);
        })
      }
    })
  });
});

finalement

Si vous avez des questions, n'hésitez pas à commenter. À l'avenir, j'aimerais ajouter une représentation graphique et une fonction de sauvegarde. Merci d'être resté avec nous jusqu'à présent!

Recommended Posts

[Rails 6] Dessin graphique interactif avec Ajax + chart.js
[Rails] Rendre la pagination compatible avec Ajax
Créer un graphique simple avec Rails Utiliser gem-chartkick / groupdate
[Rails 6] Erreur d'exécution avec $ rails s
Manipuler le dispositif avec des rails
Créer des graphiques avec JFreeChart
[Rails] Didacticiel Apprendre avec les rails
[Rails] Test avec RSpec
[Rails] Développement avec MySQL
Prend en charge la multilinguisme avec Rails!