FuelPHPでDBのデータから作った図表を表示する

概要

DBのデータから図表を作成して表示するWebページを、FuelPHPで作成しました。自分用のメモとして記事に残します。

前提知識

  • FuelPHPにおけるMVCの基本操作
  • SQL、html、javaScriptの基礎
  • JSON形式

環境

  • フレームワーク:FuelPHP 1.8.2
  • DB:MySQL(MAMP)
  • サーバ側の言語:PHP 7.2.1
  • フロント側の言語:html, css, javaScript(jQuery)
  • グラフ描画用ライブラリ:chart.js 2.8.0

大まかな処理の流れ

  1. コントローラにて、モデルから取得したDBデータをビューに渡す
  2. ビューにてscriptタグの属性としてDBデータを保持し、外部ファイル(.js)を呼び出す
  3. 外部ファイル(.js)にて図を作成し、canvas要素に描画する

詳細な手順

1. コントローラにて、モデルから取得したDBデータをビューに渡す

図表に示すデータとして、次のようなレコードを products テーブルに用意しました。

f:id:ishii-akihiro:20191021150906p:plain

モデルとコントローラの内容は次の通りです。

  • モデル
    APPPATH/classes/model/product.php
<?php
class Model_Product extends Model
{
public static function select_products()
{
//DBから製品情報を取得
$rst = DB::select()->from('products')->execute()->as_array();
return $rst;
}
}
  • コントローラ
    APPPATH/classes/controller/home.php
<?php
class Controller_Home extends Controller
{
public function action_index()
{
//モデルから製品情報を取得
$products = Model_Product::select_products();
//ビューを作成
$view = View::forge('index');
$view->set('products', $products);
return $view;
}
}

2. ビューにてscriptタグの属性としてDBデータを保持し、外部ファイル(.js)を呼び出す

コントローラから渡されたDBデータは$productに格納されており、表にはそのまま使用します。
一方、図はjavaScriptで作成するため、$productのデータを外部ファイル(main.js)に渡す必要があります。bodyタグの最後で外部ファイルを呼び出す際に、そのscriptタグを特定するidと、データを格納した属性を付与します。
ただし、scriptタグの属性に付与するためには、データを配列から文字列に変換する必要があります。javaScriptで再び配列にしやすくするため、JSON形式にしておきます。
外部ファイル(main.js)の他に、jQueryとchart.jsを呼び出しています。今回はいずれもCDNを参照することにしています。

  • ビュー
    APPPATH/views/index.php
<!DOCTYPE html>
<htmllang="ja">
<head>
 <metacharset="UTF-8">
 <title>商品情報</title>
 <?php echo Asset::css('style.css'); ?>
</head>
<body>
<!-- DB情報を表に示す -->
<section>
<h2></h2>
<table>
<thead>
<tr>
<th>商品名</th>
<th>値段(円)</th>
</tr>
</thead>
<tbody>
<?php foreach($products as $key => $val): ?>
<tr>
<td><?php echo $val['name']; ?></td>
<td><?php echo $val['price']; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</section>
<!-- DB情報を図に示す -->
<section>
<h2></h2>
<divclass="canvas-wrapper">
<canvasid="price"></canvas>
</div>
</section>
<!-- jQuery cdn -->
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- chart.js cdn -->
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<!-- 自作スクリプトファイル -->
<?php echo Asset::js('main.js', array('id'=>'script_id','products'=>json_encode($products))); ?>
</body>
</html>

3. 外部ファイル(.js)にて図を作成し、canvas要素に描画する

ビューの最後に記載したscriptタグを指定し、属性に保持したデータを取得します。
文字列から配列に変換し、図に示すラベルとデータをそれぞれ別の配列に格納します。今回は、ラベルには商品名を、データには値段を使います。下記のコードで、ラベル用のnamesには[“にんじん”, “レタス”, “いちご”, “ぶどう”]が、データ用のpricesには[100, 200, 600, 400]が格納されます。

  • javaScript
    public/assets/js/main.js
$(function(){
//ビューからjson形式の文字列を取得
$script_tag = $('#script_id');
var json_string = $script_tag.attr('products');
//配列に変換
var json_array = JSON.parse(json_string);
//グラフに使用するデータを抽出した配列を作成
var names = [];
var prices = [];
$.each(json_array, function(index, val){
names.push(val['name']);
prices.push(val['price']);
})
// canvas にグラフを表示
var ctx = document.getElementById('price').getContext('2d');
var chart_line = new Chart(ctx, {
type: 'bar',
data: {
labels: names,
datasets: [
{
label: '値段(円)',
data: prices
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
min: 0,
max: 1000
}
}]
}
}
});
});

結果

こんな感じで描画できました(cssの内容は省略します)。

f:id:ishii-akihiro:20191021153229p:plain

おわりに

やっとExcelに追いついた気がする。。データから作るならExcelの方が早いけど、用意されたデータを使い回すならWeb技術も活用できるのではなかろうか。

参考

こちらの記事のおかげで流れがわかりました。
phpから外部のjsに値渡し – Qiita

chart.js の棒グラフに関するドキュメントはこちらです。
Bar · Chart.js documentation

タイトルとURLをコピーしました