概要
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
大まかな処理の流れ
- コントローラにて、モデルから取得したDBデータをビューに渡す
- ビューにて
script
タグの属性としてDBデータを保持し、外部ファイル(.js)を呼び出す - 外部ファイル(.js)にて図を作成し、
canvas
要素に描画する
詳細な手順
1. コントローラにて、モデルから取得したDBデータをビューに渡す
図表に示すデータとして、次のようなレコードを products テーブルに用意しました。
モデルとコントローラの内容は次の通りです。
- モデル
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の内容は省略します)。
おわりに
やっとExcelに追いついた気がする。。データから作るならExcelの方が早いけど、用意されたデータを使い回すならWeb技術も活用できるのではなかろうか。
参考
こちらの記事のおかげで流れがわかりました。
phpから外部のjsに値渡し – Qiita
chart.js の棒グラフに関するドキュメントはこちらです。
Bar · Chart.js documentation