[JAVA] [Rails 6] Interaktive Grafikzeichnung mit Ajax + chart.js

Dieses Mal werden wir eine einfache Diagrammfunktion in Ruby on Rails mithilfe von ajax und chat.js implementieren. Zeichnen wir als Beispiel den Wachstumsrekord der im Pulldown-Menü ausgewählten Person. (Horizontale Achse: Aufnahmedatum, vertikale Achse: Höhe) Die Rails-Version ist 6.0.3.3. 身長.gif

bitte beachten Sie

Tabellendefinition

Spaltenname fi Spaltenbeschreibung Datentyp
id ID integer
name Name string
height Höhe float
rec_date Datum der Höhenaufzeichnung date
created_at Registrierungsdatum datetime
updated_at Aktualisierungsdatum datetime

Dieses Mal werden die Höhenaufzeichnungsdaten für zwei Personen in "seeds.rb" registriert.

Vorbereitung

Gem hinzugefügt

Gemfile


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

Packung mit Garn hinzufügen

command


yarn add jquery chart.js

In der Lage sein, mit jQuery umzugehen

config/webpack/environment.js


const { environment } = require('@rails/webpacker')
//Stellen Sie jquery zur Verfügung
const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery'
  })
)
module.exports = environment

Laden des Moduls chart.js

app/javascript/packs/application.js


// chart.Hinzugefügt für js Verwendung
require("chart.js")

Modell erstellen

command


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

Erstellung & Eingabe von Anfangsdaten

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: 'Schnee',
      height: 130.3,
      rec_date: "1987-05-07",
    },
    {
      name: 'Schnee',
      height: 144.1,
      rec_date: "1995-04-23",
    },
    {
      name: 'Schnee',
      height: 153.6,
      rec_date: "2000-05-13",
    },
  ]
)

command


rails db:seed

Controller erstellen

Bereiten Sie eine Indexaktion und eine Suchaktion in chart_sample_controller.rb vor. Die Suchaktion ist eine Aktion, die eine Anforderungsübertragung mit "$ .ajax ()" empfängt und die Daten der Höhe, die dem Namen im JSON-Format entspricht, durch Suchen im Modell zurückgibt.

command


rails generate controller ChartSample index search

Zu diesem Zeitpunkt haben wir die erforderlichen Pakete, Edelsteine, Modelle und Controller erstellt. Bereiten Sie als Nächstes die Routeneinstellungen und Ansichten vor.

Routeneinstellungen und Ansichten

Routeneinstellung

config/routes.rb


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

Views Die js-Datei wird mit javascript_pack_tag gelesen, aber hier wird das Skript, das das Diagramm mit Ajax + chart.js zeichnet, in jQuery geschrieben. Die js-Datei wird in app / javascript / packs / chart_sample / chart_user_height.js beschrieben.

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


<h1>Wachstumsrekord</h1>
<div class="contents">
  <select id="area">
    <option value="0">Bitte auswählen</option>
    <option value="1">Takashi</option>
    <option value="2">Schnee</option>
  </select>
</div>

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

<%= javascript_pack_tag 'chart_sample/chart_user_height' %>

Der Ansichtsbildschirm sieht folgendermaßen aus: Wenn Sie fertig sind, wählen Sie den Namen aus dem Pulldown-Menü aus → Das Wachstumsdiagramm wird unten angezeigt. スクリーンショット 2020-09-30 16.24.35.png

Ajax+chart.js Der Code hier ist lang, daher werde ich ihn Schritt für Schritt erklären und den Quellcode am Ende zusammenfügen.

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


$(document).on('turbolinks:load', function () {
  $(function () {
    //Laden Sie Ihre eigene Funktion für die Diagrammanzeige
    var chart_func = require("../origin_func.js")
    $('#area').change(function() {
      var selected_name = $('option:selected').text();
      var selected_index = $('option:selected').val();

Um zu verhindern, dass jQuery aufgrund eines Seitenübergangs aufgrund des Einflusses von Ajax usw. nicht ordnungsgemäß funktioniert, wird hier "turbolinks: load" sowohl beim erstmaligen Laden als auch beim erneuten Laden ausgelöst. origin_func.js lädt eine funktionale Version der Diagrammzeichnungsfunktion von chart.js. Dies wird später erklärt. Der Index des Auswahlfelds der vorherigen Ansicht ist als "selected_index" definiert, und der Name ist als "selected_name" definiert.

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


      if (selected_index > 0) {
        //Senden Sie eine Anfrage für den Wert von SelectBox im JSON-Format mit Ajax
        // messages/Wird von der Indexaktion des Suchcontrollers empfangen
        $.ajax({
          type: 'GET', //Anfragetyp
          url: '/chart_sample/search', //URL zum Senden der Anfrage
          data:  { name: selected_name }, //Daten, die an den Server gesendet werden sollen
          dataType: 'json' //Typ vom Server zurückgegeben
        })

Hier wird selected_index> 0, dh was verarbeitet wird, wenn der Name (diesmal" Takashi "oder" Yuki ") ausgewählt wird. Senden Sie den mit $ .ajax () erhaltenen Namen an den Controller. Gemäß der obigen Routeneinstellung wird es an die Suchaktion von "chart_sample_controller.rb" gesendet. Dieser Abschnitt beschreibt den Inhalt der Suchaktion des Controllers, der die Anforderung vor der Fortsetzung von "chart_user_height.js" erhalten hat.

app/controllers/chart_sample_controller.rb


class ChartSampleController < ApplicationController
  def index
  end

  def search
    #↓ Verarbeitungscode suchen(Eine Liste der Suchergebnisse wird eingegeben)
    @height = Height.where('name = (?)', "#{params[:name]}").order(rec_date: "ASC")    

    respond_to do |format|
      #Wenn das angeforderte Format das HTML-Format ist
      format.html { redirect_to :root }
      #Wenn das angeforderte Format das JSON-Format ist
      format.json { render json: @height }
    end
  end
end

In der Aktion "Suchen" wird die zuvor von Ajax gesendete Anforderung (Name der Person) in params [: name] gespeichert, sodass eine Übereinstimmungssuche im Modell "Höhe" durchgeführt wird und das "rec_date" des vom Modell zurückgegebenen Inhalts durchsucht wird. In chronologischer Reihenfolge sortiert. Dies dient dazu, die horizontale Achse später auf "rec_date" zu setzen, wenn das Diagramm mit chart.js angezeigt wird. Da die Anforderung im JSON-Format erfolgt, wird format.json ausgeführt und die Suchergebnisse werden im JSON-Format zurückgegeben. Wenn es schwer zu verstehen ist, versuchen Sie das Debuggen mit binding.pry usw. und es wird einfacher sein, ein Bild zu erhalten. Kehren wir noch einmal zur js-Datei zurück und schauen uns den Zeichenprozess an.

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


        //Erhalten Sie eine Anfrage von Ajax
        .done(function (data) {
          var height_val = [];
          var height_name = [];
          var height_date = [];
          // chart.In einem Array speichern, um es an js zu übergeben
          $(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', "Höhe", height_date, height_val);
        })
      }
    })
  });
});

Hier wird das vom Modell empfangene JSON-Format in einen Array-Typ konvertiert, um es an chart.js zu übergeben. Zum Beispiel enthält height_val die vergangenen Höhen von Takashi als Array [(Höhe), (Höhe), (Höhe)]. (Ich denke, es gibt einen besseren Weg, es etwas klarer zu schreiben ...) Übergeben Sie es dann an die selbst erstellte Funktion, die das Array mit den Datums- und Höhendaten liest. Die selbst erstellte Funktion instanziiert Chart mit chart.js. Die an die Funktion übergebenen Argumente sind chart_func.bar_chart (Dokument, Name der Canvas-Tag-ID, Name des Labels, der an das Diagramm angehängt werden soll (optional), Datenarray für horizontale Achsen, Datenarray für vertikale Achsen).

Darstellungsverarbeitung durch 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');
    //Löschen Sie die Instanz, wenn das Diagramm bereits gezeichnet ist
    if(myChart.constructor === Chart){
        myChart.destroy();
    };
    //Darstellung des Balkendiagramms
    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();
    };

In der Beschreibung mit der Anweisung "if" wird das Diagramm bei Wiederverwendung der Zeichenfläche mit dem vorherigen Diagramm überlappend beschrieben. Wenn also bereits eine Instanz von "Chart" erstellt wurde, sollte die Instanz "Chart.destroy" sein. Dies liegt daran, dass es gelöscht werden muss. Zum Zeitpunkt des Ladens wird "myChart.constructor" zu "Chart", wenn eine Instanz aus "HTMLCanvasElement" erstellt wird. Der Rest erstellt Diagramminstanzen basierend auf den Array-Daten. Das ist alles für die Implementierung. Ich habe chart_user_height.js zeitweise erklärt, also werde ich es unten einfügen.

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


$(document).on('turbolinks:load', function () {
  $(function () {
    //Laden Sie Ihre eigene Funktion für die Diagrammanzeige
    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");  
        //Senden Sie eine Anfrage für den Wert von SelectBox im JSON-Format mit Ajax
        // messages/Wird von der Indexaktion des Suchcontrollers empfangen
        $.ajax({
          type: 'GET', //Anfragetyp
          url: '/chart_sample/search', //URL zum Senden der Anfrage
          data:  { name: selected_name }, //Daten, die an den Server gesendet werden sollen
          dataType: 'json' //Typ vom Server zurückgegeben
        })
        //Erhalten Sie eine Anfrage von Ajax
        .done(function (data) {
          var height_val = [];
          var height_name = [];
          var height_date = [];
          // chart.In einem Array speichern, um es an js zu übergeben
          $(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', "Höhe", height_date, height_val);
        })
      }
    })
  });
});

Schließlich

Wenn Sie Fragen haben, können Sie diese gerne kommentieren. In Zukunft möchte ich eine Diagrammdarstellung und eine Speicherfunktion hinzufügen. Vielen Dank, dass Sie bisher bei uns geblieben sind!

Recommended Posts

[Rails 6] Interaktive Grafikzeichnung mit Ajax + chart.js
[Rails] Pagenation mit Ajax kompatibel machen
Einfaches Diagramm mit Rails ausgeben Verwenden Sie gem-chartkick / groupdate
[Rails 6] Laufzeitfehler mit $ Rails s
Gerät mit Schienen handhaben
Erstellen Sie Diagramme mit JFreeChart
[Rails] Lernen mit Rails Tutorial
[Schienen] Test mit RSpec
[Rails] Entwicklung mit MySQL
Unterstützt Mehrsprachigkeit mit Rails!