Cuadro de mando de aplicación en tiempo real con Yii2, Node.js, MySQL y Chart.js

C. Configuración en Yii2

  1. Crea una clase «myCurl.php» con la función «CurlToNodejs», para saber cómo crear una función puedes ver en [Yii2] Cómo crear y usar Funciones en Plantillas Básicas y Avanzadas de Yii2.
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. Después creamos una vista «myChart.php» para mostrar los gráficos desde el dashboard. Para usar chart.js puedes verlo en 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>

Mientras que en «SiteController.php» añadimos «actionMychart». En esta función, comprueba si los datos iniciales están disponibles o no. De lo contrario, se hará una consulta a la base de datos como los datos iniciales.

    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. Hasta este paso, ya podemos mostrar los gráficos del cuadro de mandos. Sin embargo, no ha sido capaz de mostrar los cambios de datos. En esta ocasión utilizaremos «Gii» para realizar CRUD. Para más detalles, puedes ver el Generando código con Gii.
  2. Crear un modelo de «Ciudad» con un «Modelo Generador Gii». A partir de este paso se formará un archivo «/models/City.php».
  3. A continuación, hacer con «CRUD Generador Gii» del modelo. A partir de esta etapa, se formarán los siguientes archivos.
nodejs yii2 mysql chartjs 01
  1. El siguiente paso es añadir un script a «CityController.php» que notificará a Node.js los cambios de datos utilizando la función «myCurl» que creamos anteriormente.
  2. Cambia «actionCreate» por esto
    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. Y luego cambia «actionDelete» por algo como esto
    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']
    }

Artículos más recientes