Dashboard Aplikasi Real Time dengan Yii2, Node.js, MySQL dan Chart.js

bardimin pic

Ditulis oleh Bardimin

Tanggal 23 September 2021
Home » Blog » Teknologi » Dashboard Aplikasi Real Time dengan Yii2, Node.js, MySQL dan Chart.js

Dalam artikel ini kita akan membuat sebuah yang bisa menampilkan grafik dari data secara real time. Data yang kita gunakan sebagai simulasi adalah populasi penduduk suatu kota. Jika kita melakukan update data penduduk, menambahkan atau menghapus, tampilan grafik akan berubah secara real time tanpa perlu melakukan refresh dari halaman.

Sebelum kita memulai, kita perlu mempersiapkan:

  1. Webserver sudah terpasang, lihat Cara Konfigurasi Virtual Host XAMPP di Windows 10
    .
  2. Yii2 sudah terpasang, lihat Cara Install Yii2 Advanced via Composer
    .
  3. Node.js sudah terpasang, lihat Membuat aplikasi real time dengan Node.js
    .
  4. Chart.js.

Langkah-Langkah Membuat Dashboard Aplikasi Real Time dengan Yii2, Node.js, MySQL dan Chart.js

A. Membuat tabel dengan MySQL

Buat tabel dengan nama “city”, dan kolom dengan nama “id” dan “population”. Atau lebih mudahnya anda dapat menjalankan sql berikut ini

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

B. Membuat server Node.js

  1. Siapkan Node.js seperti pada Membuat aplikasi real time dengan Node.js.
  2. Pada file “.js”, yang perlu kita buat adalah “API” yang akan melakukan update data pada grafik yang kita buat dengan Chart.js setelah data berhasil di simpan oleh Yii.
  3. Ketika user pertama kali membuka halaman , kita lakukan pengecekan apakah data awal untuk grafik dasboard sudah tersedia, jika belum Yii akan mengirimkan data awal tersebut.
app.post('/status', (req, res) => {
    res.send(isInitData);
});

app.post('/initData', (req, res) => {
    if(!isInitData){
        myData = req.body;
        isInitData=true;
    }
    res.send('success');
});
  1. Selanjutnya kita akan membuat “API” yang akan melakukan update data pada operasi CRUD pada Yii.
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. lengkap dari file 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("emit 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("emit initial data");
        socket.emit('initialData', myData);
    }
});

C. Konfigurasi pada Yii2

  1. Membuat class “myCurl.php” dengan fungsi “CurlToNodejs”, untuk cara membuat fungsi bisa Anda lihat pada [Yii2] Cara membuat dan menggunakan Fungsi pada Yii2 Basic dan Advanced Template
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. Setelah itu, kita membuat view “myChart.php” untuk menampilkan grafik dari dashboard. Untuk penggunaan Chart.js bisa anda lihat pada www.chartjs.org
<?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] = (data[i].id);
               values[i] = (data[i].population);
           }
           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>

Sedangkan pada “SiteController.php” kita tambahkan “actionMychart”. Pada fungsi ini dilakukan pengecekan apakah data awal tersedia atau tidak. Jika tidak akan dilakukan query ke sebagai data awal.

    public function actionMychart()
    {
        $response = Yii::$app->myCurl->CurlToNodejs('http://localhost:3000/status');
        if ($response === 'false') {
            $data = commonmodelsCity::find()
                ->asArray()
                ->all();
            $response1 = Yii::$app->myCurl->CurlToNodejs('http://localhost:3000/initdata', json_encode($data));
        }
        return $this->render('myChart');
    }
  1. Sampai pada langkah ini, kita sudah bisa menampilkan grafik dashboard. Akan tetapi belum bisa menampilkan perubahan data. Kali ini kita akan menggunakan “Gii” untuk membuat CRUD. Untuk lebih jelasnya bisa anda lihat pada Generating Code with Gii
  2. Buat model “City” dengan “Model Generator Gii”. Dari langkah ini akan terbentuk file “/models/City.php”.
  3. Kemudian buat dengan “CRUD Generator Gii” dari model tersebut. Dari tahap ini ini akan terbentuk file sebagai berikut
nodejs yii2 mysql chartjs 01
  1. Langkah selanjutnya adalah kita menambahkan script pada “CityController.php” yang akan memberitahu Node.js akan perubahan data dengan menggunakan fungsi “myCurl” yang kita buat sebelumnya.
  2. Ubah “actionCreate” menjadi seperti ini
    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. Kemudian ubah “actionUpdate” menjadi seperti ini
    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. Dan selanjutnya ubah “actionDelete” menjadi seperti ini
    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. Menjalankan aplikasi

  1. Jalankan server Node.js dengan
node server.js
  1. Jika semua proses sudah benar, Anda akan melihat seperti ini.
nodejs yii2 mysql chartjs

Artikel Terbaru

Teknik Dasar Perawatan Komputer dan Laptop

Teknik Dasar Perawatan Komputer dan Laptop

Anda mungkin tidak menyadarinya, tetapi komputer dan mobil memiliki kesamaan, keduanya membutuhkan perawatan rutin. Jika mobil Anda perlu mengganti oli secara rutin, komputer Anda secara rutin juga harus memperbarui perangkat lunak, menjaga antivirus tetap up to date,...

ChatGPT versi Desktop untuk Windows, Linux dan Mac

ChatGPT versi Desktop untuk Windows, Linux dan Mac

Apakah Anda tahu apa itu ChatGPT? Apakah Anda tahu cara mendapatkan dan menginstal ChatGPT di perangkat Anda? ChatGPT dengan cepat menjadi salah satu penemuan terpenting dalam dunia pemrosesan bahasa alami. Anda dapat menggunakannya untuk menghasilkan tanggapan...

Voltase Pinout Power Supply ATX 24 pin ke Motherboard

Voltase Pinout Power Supply ATX 24 pin ke Motherboard

Power Supply mengubah daya arus bolak-balik (AC) menjadi arus searah (DC) yang dikendalikan tegangan rendah. Beberapa perangkat Power Supply menyertakan pilihan tegangan input manual, sementara yang lain secara otomatis menyesuaikan. Power Supply mengubah tegangan...

Google Chrome – Buka Bookmark ke Tab Baru Secara Default

Google Chrome – Buka Bookmark ke Tab Baru Secara Default

Bookmark adalah pintasan untuk membuka halaman website yang telah anda simpan untuk anda kunjungi lagi nantinya. Pernahkah Anda mengunjungi halaman situs web yang cukup menarik dan anda ingin untuk mengunjunginya lagi nanti. Mengingat alamat halaman website tentu...

Mengenal Folder $WinREAgent dan Cara Menghapusnya di Windows 11

Mengenal Folder $WinREAgent dan Cara Menghapusnya di Windows 11

Setiap proses update dan upgrade Windows akan menghasilkan folder $WinREAgent. Pada proses update dan upgrade Windows akan membuat banyak file dan folder pada saat proses mengunduh dan menginstal pembaharuan tersebut. Lokasi file dan folder yang dibuat secara otomatis...