สำหรับ HightCharts นั้นเป็นระบบการทำกราฟที่เป็น JavaScript โดยจะทำงานที่ฝั่ง Client ดังนั้น เราจำเป็นจะต้องสร้างข้อมูลจากฐานข้อมูลให้อยู่ในรูปของ JavaScript เพื่อส่งให้ HightCharts แสดงผล แต่สาหรับการจัดการกับ HightCharts ในบทนี้จะสร้างกราฟจาก Yii2 Extension ที่มีคนได้ทำไว้ในรูปแบบของ PHP แล้ว โดยทำการติดตั้งดังนี้
composer require miloschuman/yii2-highcharts-widget
ทั้งนี้สามารถดูรายละเอียดเพิ่มเติมได้ที่เว็บไซต์
https://github.com/miloschuman/yii2-highcharts
https://packagist.org/packages/miloschuman/yii2-highcharts-widget
โดยมีตัวอย่างของการเขียนโปรแกรมเพื่อแสดงผลข้อมูลดังนี้
use miloschuman\highcharts\Highcharts;
echo Highcharts::widget([
'options' => [
'title' => ['text' => 'Fruit Consumption'],
'xAxis' => [
'categories' => ['Apples', 'Bananas', 'Oranges']
],
'yAxis' => [
'title' => ['text' => 'Fruit eaten']
],
'series' => [
['name' => 'Jane', 'data' => [1, 0, 4]],
['name' => 'John', 'data' => [5, 7, 3]]
]
]
]);
การเตรียมข้อมูลสำหรับทำกราฟ
สำหรับการเตรียมข้อมูลนั้นเราจะนำข้อมูลที่ได้ไปแสดง 2 ส่วนนั่นคือ ส่วนที่เป็นตาราง GridView และส่วนแสดงผลกราฟ
สร้าง ReportController.php
สร้างไฟล์ Controller สำหรับเก็บ Action ในการดึงข้อมูลมาเตรียมเพื่อส่งให้กับ View โดยสร้างที่ controllers/ReportControlller.php จากนั้นเขียนโปรแกรมเพิ่ม Action Report1() ดังนี้
<?php
namespace app\controllers;
use Yii;
use yii\data\ArrayDataProvider;
use yii\web\Controller;
class ReportController extends Controller{
public function actionReport1(){
$connection = Yii::$app->db;
$data = $connection->createCommand('
SELECT year(t.DATETIME_DISCH) as yy,
month(t.DATETIME_DISCH) as mm,
COUNT(t.AN) as cnt
FROM admission t
GROUP BY yy,mm
ORDER BY yy,mm
')->queryAll();
//เตรียมข้อมูลส่งให้กราฟ
foreach($data as $d){
$yy[] = $d['yy'];
$mm[] = $['yy'].'-'.$d['mm'];
$cnt[] = $d['cnt']*1;//นำไปคูณ 1 ป้องกันเป็น string
}
$dataProvider = new ArrayDataProvider([
'allModels'=>$data,
'sort'=>[
'attributes'=>['yy','mm','cnt']
],
]);
return $this->render('report1',[
'dataProvider'=>$dataProvider,
'yy'=>$yy,'mm'=>$mm,'cnt'=>$cnt,
]);
}
}
กราฟแท่ง (Column)
สร้าง View เพื่อแสดงผลกราฟ โดยระบุ Property สำหรับการแสดงผลกราฟในรูปแบบกราฟแท่ง หรือ Column โดยมีการกำหนดการแสดงผล 2 ส่วนคือส่วนแสดงกราฟ และส่วนการแสดง Grid View โดยมีรายละเอียดดังนี้
ส่วนแสดงกราฟ
สำหรับส่วนของการแสดงผลแบบกราฟ นั้นมีการเขียนโปรแกรมดังนี้ จะเห็นว่าส่วนที่เน้นตัวหนาคือส่วนที่แสดงผลแบบกราฟแท่ง 'type' => 'column'
views/report/report1.php
<?php
$this->title = 'จำนวนผู้ป่วยในแยกรายเดือน';
$this->params['breadcrumbs'][] = $this->title;
use yii\grid\GridView;
use miloschuman\highcharts\Highcharts;
?>
<!-- ส่วนแสดงกราฟ -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">
<i class="glyphicon glyphicon-signal"></i>
จำนวนผู้ป่วยในแยกรายเดือน</h3>
</div>
<div class="panel-body">
<?php
echo Highcharts::widget([
'options' => [
'title' => ['text' => 'จำนวนผู้ป่วยในแยกรายเดือน'],
'xAxis' => [
'categories' => $mm
],
'yAxis' => [
'title' => ['text' => 'จำนวน(คน)']
],
'series' => [
[
'type' => 'column',
'name' => 'CNT',
'data' => $cnt,
]
]
]
]);
?>
</div>
</div>
ส่วนแสดง Grid View
ส่วนของ Grid View เป็นส่วนแสดงผลข้อมูลเป็นตาราง โดยมีการกำหนดรายละเอียดให้สามารถเรียงลำดับข้อมูลในคอลัมน์ได้ดังนี้
<!-- ส่วนแสดง Grid View -->
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title"><i class="glyphicon glyphicon-signal"></i> จำนวนผู้ป่วยในแยกรายเดือน</h3>
</div>
<div class="panel-body">
<?php
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'label' => 'ปี',
'attribute' => 'yy'
],
[
'label' => 'เดือน',
'attribute' => 'mm'
],
[
'label' => 'จำนวนผู้ป่วยใน',
'attribute' => 'cnt'
],
]
]);
?>
</div>
</div>
ตัวอย่างการแสดงผลกราฟ
ตัวอย่างการแสดงผล Grid View
กราฟเส้น (Line)
สร้าง view เพื่อแสดงผลกราฟ ด้านล่างของ gridview ของส่วนกราฟแท่ง เพื่อทดสอบ
views/report/report1.php
ส่วนแสดงกราฟ
ส่วนของการแสดงกราฟจะเรียกใช้ Highcharts และกำหนดลักษณะการแสดง 'type' => 'line' ซึ่งจะแสดงผลออกมาเป็นกราฟเส้น
<?php
$this->title = 'จำนวนผู้ป่วยในแยกรายเดือน';
$this->params['breadcrumbs'][] = $this->title;
use yii\grid\GridView;
use miloschuman\highcharts\Highcharts;
?>
<!-- ส่วนแสดงกราฟ -->
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">
<i class="glyphicon glyphicon-signal"></i>
จำนวนผู้ป่วยในแยกรายเดือน</h3>
</div>
<div class="panel-body">
<?php
echo Highcharts::widget([
'options' => [
'title' => ['text' => 'จำนวนผู้ป่วยในแยกรายเดือน'],
'xAxis' => [
'categories' => $mm
],
'yAxis' => [
'title' => ['text' => 'จำนวน(คน)']
],
'series' => [
[
'type' => 'line',
'name' => 'CNT',
'data' => $cnt,
]
]
]
]);
?>
</div>
</div>
ส่วนแสดง Grid View
<!-- ส่วนแสดง Grid View -->
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title"><i class="glyphicon glyphicon-signal"></i> จำนวนผู้ป่วยในแยกรายเดือน</h3>
</div>
<div class="panel-body">
<?php
echo GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'label' => 'ปี',
'attribute' => 'yy'
],
[
'label' => 'เดือน',
'attribute' => 'mm'
],
[
'label' => 'จำนวนผู้ป่วยใน',
'attribute' => 'cnt'
],
]
]);
?>
</div>
</div>
ตัวอย่างการแสดงกราฟ
ตัวอย่างการแสดง Grid View
การสร้าง Drilldown Chart
Drilldown เป็นการแสดงผล Chart ที่สามารถคลิกดูรายละเอียดจาก Chart หลักได้ เช่น จากกราฟที่เราได้ทำมาแสดงผลเป็นรายเดือน หากเราต้องการทราบว่าแต่ละวันในเดือนนั้นมีการเกิดอุบัติเหตุเท่าไรเราก็คลิกไปที่กราฟแต่ละแท่งก็จะแสดงกราฟย่อยให้เห็นเป็นรายวันนั่นเอง
ตัวอย่าง Code ในการทำ Drilldown
โดยใน Chart หลักจะส่งหมายเลข (number) ไปเพื่อเป็นคีย์อ้างอิงในการเรียก Drilldown สังเกตที่ 'drilldown' => $r['number'] อย่าลืมใส่ intval() สำหรับค่าที่เป็นตัวเลขใน Chart
สำหรับค่าที่จะใส่ใน Drilldown นั้นอยู่ใน $sub[] ซึ่งเป็น Array ที่เป็น Set ของข้อมูลโดยต้องมี 3 key ดังต่อไปนี้ id, name และ data
- id คือคีย์ที่จะถูกส่งมาจาก Chart หลัก
- name คือ Label ที่จะแสดงผล
- data คือค่าของข้อมูลที่จะแสดงใน Chart
ดูรายละเอียดของ ReportController ใน actionIndex() ดังต่อไปนี้
<?php
namespace frontend\modules\borrow\controllers;
use yii\data\ArrayDataProvider;
use Yii;
class ReportController extends \yii\web\Controller
{
public function actionIndex()
{
$sql = "SELECT COUNT(bi.id) as total,n.number FROM borrow_item bi
LEFT JOIN number_sim nm ON nm.id = bi.number_sim_id
LEFT JOIN number n ON n.id = nm.number_id
GROUP BY bi.number_sim_id
";
$rows = Yii::$app->db->createCommand($sql)->queryAll();
$graph = [];
foreach($rows as $r){
$graph[] = [
//'type' => 'column',
'name' => $r['number'],
'y' => intval($r['total']),
'drilldown' => $r['number'],
];
}
$y = date('Y');
$sql_sub = "SELECT n.number,
COUNT(IF(MONTH(date_out)=1,bi.id,NULL)) AS m1,
COUNT(IF(MONTH(date_out)=2,bi.id,NULL)) AS m2,
COUNT(IF(MONTH(date_out)=3,bi.id,NULL)) AS m3,
COUNT(IF(MONTH(date_out)=4,bi.id,NULL)) AS m4,
COUNT(IF(MONTH(date_out)=5,bi.id,NULL)) AS m5,
COUNT(IF(MONTH(date_out)=6,bi.id,NULL)) AS m6,
COUNT(IF(MONTH(date_out)=7,bi.id,NULL)) AS m7,
COUNT(IF(MONTH(date_out)=8,bi.id,NULL)) AS m8,
COUNT(IF(MONTH(date_out)=9,bi.id,NULL)) AS m9,
COUNT(IF(MONTH(date_out)=10,bi.id,NULL)) AS m10,
COUNT(IF(MONTH(date_out)=11,bi.id,NULL)) AS m11,
COUNT(IF(MONTH(date_out)=12,bi.id,NULL)) AS m12
FROM borrow_item bi
LEFT JOIN borrow b ON b.id = bi.borrow_id
LEFT JOIN number_sim ns ON ns.id = bi.number_sim_id
LEFT JOIN number n ON n.id = ns.number_id
WHERE YEAR(date_out) = '$y'
GROUP BY bi.number_sim_id";
$row_sub = Yii::$app->db->createCommand($sql_sub)->queryAll();
$sub = [];
foreach($row_sub as $rs){
$sub[] = [
//'type' => 'column',
'id' => $rs['number'],
'name' => $rs['number'],
'data' => [['ม.ค.', intval($rs['m1'])], ['ก.พ.', intval($rs['m2'])], ['มี.ค.', intval($rs['m3'])], ['เม.ย.', intval($rs['m4'])], ['พ.ค.', intval($rs['m5'])], ['มิ.ย.', intval($rs['m6'])], ['ก.ค.', intval($rs['m7'])], ['ส.ค.', intval($rs['m8'])], ['ก.ย.', intval($rs['m9'])], ['ต.ค.', intval($rs['m10'])], ['พ.ย.', intval($rs['m11'])], ['ธ.ค.', intval($rs['m12'])]]
];
}
$dataProvider = new ArrayDataProvider([
'allModels' => $rows,
'sort' => [
'attributes' => [
]
]
]);
return $this->render('index',[
'graph' => $graph,
'drilldown' => $sub,
'dataProvider' => $dataProvider,
]);
}
}
ตัวอย่างไฟล์ views/report/index.php
สำหรับการแสดงผลในไฟล์ view เราจะตั้งค่าการแสดงผลดังนี้
<?php
use miloschuman\highcharts\Highcharts;
?>
<div class="box box-warning box-solid">
<div class="box-header with-border">
<h3 class="box-title">Report1</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<?=Highcharts::widget([
'id' => 'chart1',
'scripts' => [
'highcharts-more',
'highcharts-3d',
'modules/drilldown',
],
'options' => [
'credits' => ['enabled' => false],
'type' => 'column',
]
])?>
<div id="chart1"></div>
</div>
</div>
<?php $this->registerJs("$(function () {
// Create the chart
$('#chart1').highcharts({
chart: {
type: 'column'
},
title: {
text: 'กราฟสรุปหมายเลขที่มีการยืม'
},
subtitle: {
text: 'กราฟแสดงข้อมูลสรุปหมายเลขที่มีการยืม'
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
text: 'จำนวนครั้ง'
}
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{point.y} ครั้ง'
}
}
},
tooltip: {
headerFormat: '<span style=\"font-size:11px\">{series.name}</span><br>',
pointFormat: '<span style=\"color:{point.color}\">{point.name}</span>: <b>{point.y} ครั้ง</b> <br/>'
},
series: [{
name: 'หมายเลข',
colorByPoint: true,
data: ".json_encode($graph)."
}],
drilldown: {
series: ".json_encode($drilldown)."
}
});
});");
ตัวอย่างการแสดงผล
Chart หลัก
Drilldown Chart
ความคิดเห็น