Real-Time Application Dashboard with Yii2, Node.js, MySQL and Chart.js

C. Configuration on Yii2

  1. Create a class “myCurl.php” with the function “CurlToNodejs”, for how to create a function you can see in [Yii2] How to create and use Functions in Yii2 Basic and Advanced Templates
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. After that, we create a view “myChart.php” to display the graphics from the dashboard. For chart use.js you can see it on 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] = [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>

While in “SiteController.php” we add “actionMychart”. In this function, check whether the initial data is available or not. Otherwise, a query will be made to the database as the initial data.

    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. Up to this step, we can already display dashboard graphics. However, it has not been able to display data changes. This time we will use “Gii” to make CRUD. For more details, you can see the Generating Code with Gii.
  2. Create a “City” model with a “Gii Generator Model”. From this step will be formed a file “/models/City.php”.
  3. Then make it with “CRUD Generator Gii” from the model. From this stage, the following files will be formed.
nodejs yii2 mysql chartjs 01
  1. The next step is to add a script to “CityController.php” that will notify the Node.js of the data changes by using the “myCurl” function that we created earlier.
  2. Change “actionCreate” to this
    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. Then change “actionUpdate” to this
    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. And then change “actionDelete” to like this
    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']
    }

Latest Articles