Echtzeit-Anwendungs-Dashboard mit Yii2, Node.js, MySQL und Chart.js

In diesem Artikel werden wir ein Dashboard erstellen, das Grafiken aus Daten in Echtzeit anzeigen kann. Die Daten, die wir als Simulationen verwenden, sind die Einwohner einer Stadt. Wenn Sie Ihre Einwohnerdaten aktualisieren, hinzufügen oder löschen, wird sich die Grafik in Echtzeit ändern, ohne dass die Seite aktualisiert werden muss.

Bevor wir beginnen, müssen wir uns vorbereiten:

  1. Webserver installiert ist, siehe Wie man den virtuellen Host XAMPP in Windows 10 konfiguriert
    .
  2. Yii2 installiert ist, siehe Wie man Yii2 Advanced über Composer installiert
    .
  3. Node.js ist bereits installiert, siehe Erstellen von Echtzeitanwendungen mit Nodes.js
    .
  4. Chart.js.

Schritte zur Erstellung einer Echtzeit-Anwendung Dashboard mit Yii2, Node.js, MySQL und Chart.js

A. Erstellen Sie eine Tabelle mit MySQL

Erstellen Sie Tabellen mit dem Namen „city“ und Spalten mit den Namen „id“ und „population“. Oder es ist einfacher, die folgenden SQL-Skripte auszuführen.

CREATE TABLE 'city' (
  'id' CHAR(16) NOT NULL PRIMARY KEY,
  'population' INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

B. Erstellen Sie einen Node server.js

  1. Einrichten eines Node server.js wie in Erstellung von Echtzeitanwendungen mit Nodes.js.
  2. In der Datei „server.js“ müssen wir eine „API“ erstellen, die die Daten im Diagramm aktualisiert, das wir mit Chart.js erstellen, nachdem die Daten erfolgreich von Yii gespeichert wurden.
  3. Wenn der Benutzer die Dashboard-Seite zum ersten Mal öffnet, prüfen wir, ob die Anfangsdaten für das Dashboard-Diagramm verfügbar sind. Wenn nicht, sendet Yii die Anfangsdaten.
app.post('/status', (req, res) => {
    res.send(isInitData);
});

app.post('/initData', (req, res) => {
    if(!isInitData){
        myData = req.body;
        isInitData=true;
    }
    res.send('success');
});
  1. Als Nächstes werden wir eine „API“ erstellen, die die Daten über rohe Operationen auf Yii aktualisieren wird.
app.post('/newData', (req, res) => {
    switch (req.body.actions){
        case "create":
            myData.push({id: req.body.id, population: req.body. population});
            break;
        case "update":
            let i = myData.findIndex(label => label.id === req.body.id);
            myData [i] ={id: req.body.id, population: req.body. population};
            break;
        case "delete":
            let l = myData.findIndex(label => label.id === req.body.id);
            myData.splice(l,1);
            break;
    }
    io.emit('newData', {id: req.body.id, population: req.body. population, actions:req.body.actions});
    res.send('success');
});
  1. Vollständiges Skript der Datei server.js
var app = require("express")();
var bodyParser = require('body-parser')
var http = require('http'). Server(app);
var io = require("socket.io")(http,{cors: {origin:"*"}});

var myData = [] ;
var isInitData=false;

http.listen(3000, function () {
    console.log("Listening on 3000");
});

app.use(bodyParser.json({type: 'application/json' }));

app.post('/status', (req, res) => {
    res.send(isInitData);
});

app.post('/initData', (req, res) => {
    if(!isInitData){
        myData = req.body;
        isInitData=true;
    }
    res.send('success');
});

app.post('/newData', (req, res) => {
    switch (req.body.actions){
        case "create":
            myData.push({id: req.body.id, population: req.body. population});
            break;
        case "update":
            let i = myData.findIndex(label => label.id === req.body.id);
            myData [i] ={id: req.body.id, population: req.body. population};
            break;
        case "delete":
            let l = myData.findIndex(label => label.id === req.body.id);
            myData.splice(l,1);
            break;
    }
    io.emit('newData', {id: req.body.id, population: req.body. population, actions:req.body.actions});
    console.log("issuer new data "+req.body.id+" :"+req.body.actions);
    res.send('success');
});

io.on("connection", (socket) => {
    console.log("A user is connected");
    if(isInitData){
        console.log("initial data issuer");
        socket.emit('initialData', myData);
    }
});

C. Konfiguration auf Yii2

  1. Erstellen Sie eine Klasse „myCurl.php“ mit der Funktion „CurlToNodejs. Wie Sie eine Funktion erstellen, können Sie in [Yii2] How to create and use Functions in Yii2 Basic and Advanced Templates nachlesen
class myCurl extends Component
{
    public function CurlToNodejs($url.$postdata=null)
    {
        $header = ['Content-type: application/json'] ;
        $curl = curl_init();
        curl_setopt ($curl, CURLOPT_URL, $url)
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
        $response = curl_exec($curl);
        return $response;
    }
}
  1. Danach erstellen wir eine Ansicht „myChart.php“, um die Grafiken aus dem Dashboard anzuzeigen. Die Grafik use.js können Sie auf www.chartjs.org sehen.
<?php
/* @var $this yiiwebView */
$this->title = 'My Chart Application';
$script = < JS
	$(document).ready(function(){
	//Chart.js Configuration
	    const data = {
            datasets: [{
                label: 'My First Dataset',
                borderWidth: 1
            }]
        };
	    
	    const ctx = document.getElementById('myChart');
	    const myChart = new Chart(ctx, {
	        type: 'bar',
	        data: data,  
	    });	    
	   
	   function UpdateChart(chart, label, data) {
            chart.data.labels=label;
            chart.data.datasets.forEach((dataset) => {
                dataset.data=data;
            });
            chart.update();
       }
	   
Socket.io Configuration
	   const socket = io.connect( 'http://localhost:3000');
       var labels = [] ;
       var values = [] ;
       socket.on('initialData', function(data){
           for (let i = 0; i < data.length; i++){
               labels [i] = [i] (.id data);
               values [i] = [i] (.population data);
           }
           UpdateChart(myChart,labels,values);
       });
        socket.on('newData', function(data){
            switch (data.actions){
                case "create":
                    const i = labels.length;
                    labels [i] = data.id;
                    values [i] = data.population;    
                    break;
                case "update":
                    const l = labels.findIndex(label=>label===data.id);
                    values [l] = data.population;
                    break;
                case "delete":
                    const x = labels.findIndex(label=>label===data.id);
                    if (x > -1) {
                        labels.splice(x, 1);
                        values.splice(x, 1);
                    }
                    break;                   
            }
            UpdateChart(myChart,labels,values);
        });
     
});
JS;
$this->registerJs($script);
$this->registerJsFile("https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.2.0/socket.io.js",); ['position' => yiiwebView::POS_HEAD]
$this->registerJsFile('https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js', ['position' => yiiwebView::POS_HEAD] );
?><div class="site-index">
    <div class="body-content">
        <div id="container" style="width: 75%;">
            <canvas id="myChart"></canvas>
        </div>
    </div>
</div>

In „SiteController.php“ fügen wir „actionMychart“ hinzu. In dieser Funktion wird geprüft, ob die Ausgangsdaten vorhanden sind oder nicht. Andernfalls wird eine Abfrage an die Datenbank als Ausgangsdaten gemacht werden.

    public function actionMychart()
    {
        $response = Yii::$app->myCurl->CurlToNodejs('http://localhost:3000/status');
        if ($response === 'false') {
            $data = commonmodelsCity::find()
                ->asArray()
                ->all();
            $response 1 = Yii::$app->myCurl->CurlToNodejs('http://localhost:3000/initdata', json_encode($data));
        }
        return $this->render('myChart');
    }
  1. Bis zu diesem Schritt können wir bereits Dashboard-Grafiken anzeigen. Es war jedoch nicht in der Lage, Datenänderungen anzuzeigen. Dieses Mal werden wir „Gii“ verwenden, um CRUD zu machen. Weitere Einzelheiten finden Sie in der Erzeugung von Code mit Gii.
  2. Erstellen Sie ein „City“-Modell mit einem „Gii Generator Model“. Aus diesem Schritt wird eine Datei „/models/City.php“ erstellt.
  3. Dann machen Sie es mit „CRUD Generator Gii“ aus dem Modell. Aus dieser Phase werden die folgenden Dateien gebildet.
nodejs yii2 mysql chartjs 01
  1. Der nächste Schritt ist das Hinzufügen eines Skripts zu „CityController.php“, das Node.js über die Datenänderungen informiert, indem es die Funktion „myCurl“ verwendet, die wir zuvor erstellt haben.
  2. Ändern Sie „actionCreate“ wie folgt
    public function actionCreate()
    {
        $model = new City();
        if ($this->request->isPost) {
            if ($model->load($this->request->post()) && $model->save()) {
                $post=Yii::$app->request->post('City');
                $data = ["id" => $post['id'] , "population" = > $post ['population'] "actions"=> "create"];
                Yii::$app->myCurl->CurlToNodejs('http://localhost:3000/newData',json_encode($data));
                return $this->redirect; ['view', 'id' => $model->id]
            }
        } else {
            $model->loadDefaultValues();
        }
        return $this->render('create', [
            'model' = > $model,
        ]);
    }
  1. Dann ändern Sie „actionUpdate“ wie folgt
    public function actionUpdate($id)
    {
        $model = $this->FindModel($id);
        if ($this->request->isPost && $model->load($this->request->post()) && $model->save()) {
            $post=Yii::$app->request->post('City');
            $data= , ["id" => $post['id'] "population" = > $post ['population'] "actions"=>"update"];
            Yii::$app->myCurl->CurlToNodejs('http://localhost:3000/newData',json_encode($data));
            return $this->redirect; ['view', 'id' => $model->id]
        }
        return $this->render('update', [
            'model' = > $model,
        ]);
    }
  1. Und dann ändern Sie „actionDelete“ wie folgt
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();
        $data = ["id" => $id, "population" =>"","actions"=>"delete"] ;
        Yii::$app->myCurl->CurlToNodejs('http://localhost:3000/newData',json_encode($data));
        return $this->redirect; ['index']
    }

D. Ausführen einer App

  1. Führen Sie den Node server.js mit
node server.js
  1. Wenn alle Prozesse richtig sind, werden Sie es so sehen.
nodejs yii2 mysql chartjs

VERWANDTE ARTIKEL

Neueste Artikel