WordPressの記事にレーダーチャートを埋め込むみたいなことをしました。
レーダーチャートとはこんな感じのグラフですね。
PHP(WordPress関数)はあまりやらないので、次に似たような実装をする自分のためにもノウハウを残します、、笑
グラフには動的なグラフの描画で人気のChart.jsを使用しているので、レーダーチャート以外のグラフでも応用が可能です。
似たようなことでお困りの方がいればぜひ参考にしてみてください。
また、ACFを使用しない実装であれば下記の記事も参考になりますので、良ければ。
【Chart.js】ワードプレスの記事にグラフを入れる方法!(コピペでOK)
Contents
バージョン
WordPress 4.9.10
Chart.js 2.8.0
Advanced Custom Fields PRO 5.8.5
グラフのUIを作成
まずはグラフの見た目を作成していきます。
CDNを読み込む
今回Chart.jsはCDNを利用するのでhead
で読み込みます。
ロード時間が気になるのでscriptタグにasync属性を追加しました。
<!doctype html>
<head>
...略
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" async></script>
</head>
チャートのデータを作成
bodyの終了タグの直前にscriptタグを挿入して仮のグラフデータを生成します。
グラフタイプをradar以外にするとデータの書き方も若干変わるので、Chart.js公式などを見て入れていきます。設定はお好みで。
<script>
var radarChart = document.getElementById("radarChart").getContext('2d');
var chart = new Chart(radarChart, {
type: 'radar',
data: {
labels: ['項目1', '項目2', '項目3'],
datasets: [{
data: [4.0, 5, 3.2],
backgroundColor: 'RGBA(181,217,253, 0.5)',
borderColor: 'RGBA(72,128,247, 1)',
borderWidth: 1,
pointBackgroundColor: 'RGB(72,128,247)'
}]
},
options: {
legend: {
display: false,
},
scale:{
ticks:{
suggestedMin: 0,
suggestedMax: 5,
stepSize: 1,
callback: function(value, index, values){
return value
}
}
}
},
});
</script>
</body>
この設定で、HTML側の任意の場所に下記のコードを追加するとグラフが表示されるようになります。
<canvas id="radarChart"></canvas>
グラフ表示はとても簡単ですね。
Advanced Custom Fields PROの設定
続いてAdvanced Custom Fields PRO(以下ACF PRO)の設定をしていきます。
ACFで入力する意図としては下記を目的としています。
- JSのコードが分からない人でも分かりやすく入力できる。
- 運用ミスが減る
また、今回は『記事ごとに項目数を限定しない』という実装要件があったため、繰り返しフィールドが利用できるACF PROを利用しています。
項目数が記事ごとに固定で良いのであればPRO版でなくても十分です。
ACF PRO(またはACF)のインストール等はしてある前提で進めます。まだの方はインストールしておいてください。
では設定していきましょう。
フィールドの設定
PRO版の設定です。
WordPress管理画面サイドバーのカスタムフィールドから入り、新規追加でフィールドを下記のように設定します。
設定項目 | 設定値 | 備考 |
---|---|---|
フィールドラベル | チャート | 投稿画面のフィールドタイトル。 |
フィールド名 | chart | |
フィールドタイプ | 繰り返しフィールド | |
サブフィールド | 下記別表を参照 | 項目と点数の二つを登録。 |
Collapsed | 項目名 | サブフィールド入力後に選択可能。 |
レイアウト | 表 | 入力画面の見た目。お好みで。 |
繰り返しフィールドにすることでサブフィールド(繰り返す内容)を設定できるので項目名と点数で二つ設定します。
サブフィールド①(項目名)
下記以外の項目に関してはお好みで入力してください。
サブフィールド設定項目 | サブフィールド設定値 | 備考 |
---|---|---|
フィールドラベル | 項目名 | 必須 |
フィールド名 | label | 必須 |
フィールドタイプ | テキスト | 必須 |
サブフィールド②(点数)
入力側で意図しないデータを入れられないように、点数には最小値と最大値も入れておきます。
ステップサイズを小数点にすることで0.1刻みで点数入力ができます。
下記以外の項目に関してはお好みで入力してください。
サブフィールド設定項目 | サブフィールド設定値 | 備考 |
---|---|---|
フィールドラベル | 点数 | 必須 |
フィールド名 | point | 必須 |
フィールドタイプ | 数値 | 必須 |
デフォルト値 | 3.0 | 任意 |
最小値 | 0 | 任意 |
最大値 | 5.0 | 任意 |
ステップサイズ | 0.1 | 任意 |
公開設定
フィールドの表示位置のルールは投稿ページに表示させたいので下記とします。
『投稿タイプ』『等しい』『投稿』
最終的にこんな感じになっていればOKです。公開ボタンを押して確定させます。
カスタムフィールドの設定を公開すると投稿ページの下部に下記のような入力フィールドが出現して、自分で設定した内容に沿ってグラフ用のデータを複数個設定できるようになりました。
入力したデータからグラフを表示させる
実際に入力したデータをグラフに反映させる作業を行います。
データを入力して公開する
投稿ページにてグラフ用のデータを入力、エディタにグラフを表示させるためのタグを入力して投稿を公開します。
<canvas id="radarChart"></canvas>
公開したらブラウザ側で仮データのグラフが表示されていることを確認します。
PHPでデータを取得する
投稿ページで入力したデータを直接JavaScriptで受け取ることができないので、一旦PHPで取得してからJavaScriptに渡します。
段階を踏んでコードを書いていくので、まずはPHPで取得することろから。
Chart.js用に追加したscriptタグ(bodyの終了タグの直前)の上にPHPのコードを追加していきます。
<?php if(get_field('chart')): ?>
<!-- レーダーチャート データ取得 -->
<?php
$chartLabels = array();
$chartPoints = array();
while(the_repeater_field('chart')) {
array_push($chartLabels, get_sub_field('label'));
array_push($chartPoints, get_sub_field('point'));
}
?>
<!-- // レーダーチャート データ取得 -->
<script>
var radarChart = document.getElementById("radarChart").getContext('2d');
...略
</script>
<?php endif; ?>
</body>
簡単にコードの説明をします。
<?php if(get_field('chart')): ?>
<?php ... ?>
<script>...</script>
<?php endif; ?>
投稿画面でグラフデータの入力がない場合には処理させないようにしたいので、if文でデータの取得処理とJavaScriptの処理を囲っています。
<?php
$chartLabels = array();
$chartPoints = array();
while(the_repeater_field('chart')) {
array_push($chartLabels, get_sub_field('label'));
array_push($chartPoints, get_sub_field('point'));
}
?>
ここでACFのデータを取得してJS側に渡すための配列データを作成しています。the_repeater_field()
で配列になっている繰り返しフィールドの値を取得できます。また、点数はACFの設定で数値のバリデーションをしていますが、念のため intval()
で数値化します。intval()
を使用すると小数点を無視して整数になってしまうのでやめました。
PHPで取得したデータをJavaScriptに渡す
PHPでデータを取得できたのでJavaScriptに渡す処理を書きます。
<?php if(get_field('chart')): ?>
<!-- レーダーチャート データ取得 -->
<?php
$chartLabels = array();
$chartPoints = array();
while(the_repeater_field('chart')) {
array_push($chartLabels, get_sub_field('label'));
array_push($chartPoints, get_sub_field('point'));
}
$jsonLabelArray = json_encode($chartLabels); // 追加
$jsonPointArray = json_encode($chartPoints); // 追加
?>
<!-- // レーダーチャート データ取得 -->
<script>
var $labelArray = <?php echo $jsonLabelArray; ?>; // 追加
var $pointArray = <?php echo $jsonPointArray; ?>; // 追加
var radarChart = document.getElementById("radarChart").getContext('2d');
var chart = new Chart(radarChart, {
type: 'radar',
data: {
labels: $labelArray, // 修正
datasets: [{
data: $pointArray, // 修正
backgroundColor: 'RGBA(181,217,253, 0.5)',
borderColor: 'RGBA(72,128,247, 1)',
borderWidth: 1,
pointBackgroundColor: 'RGB(72,128,247)'
}]
},
...略
</script>
<?php endif; ?>
こちらも説明していきます。
まずはPHP側で追加したコード2行です。
PHP側の処理で作成した配列をjsonデータに置き換えました。
$jsonLabelArray = json_encode($chartLabels);
$jsonPointArray = json_encode($chartPoints);
続いてこの置換されたデータをJavaScriptで受け取ります。
var $labelArray = <?php echo $jsonLabelArray; ?>;
var $pointArray = <?php echo $jsonPointArray; ?>;
そしてこの変数をグラフのデータに入れます。
type: 'radar',
data: {
labels: $labelArray,
datasets: [{
data: $pointArray,
backgroundColor: 'RGBA(181,217,253, 0.5)',
borderColor: 'RGBA(72,128,247, 1)',
borderWidth: 1,
pointBackgroundColor: 'RGB(72,128,247)'
}]
},
これでデータの連携ができました。
問題なければ入力したデータでグラフが表示されているはずです。やったね!
ショートコード化する
ついでなのでショートコード化もしようと思います。
ショートコードはfunctions.php
に処理を追加します。
function chart_shortcode_func( $atts ) {
return '<div class="chart"><canvas id="radarChart"></canvas></div>';
}
add_shortcode( 'chart', 'chart_shortcode_func' );
これでエディタ内で下記のように呼び出すことができるようになりました。
[chart]
// ブラウザでの表示
<div class="chart"><canvas id="radarChart"></canvas></div>
関数を含めたい
phpやWordPressの関数をショートコードに含めることも可能です。
function chart_shortcode_func( $atts ) {
$a = shortcode_atts(array(
'value' => 3,
), $atts);
return '<dl class="chartWrapper">
<dt class="chartHeader">総合評価:
<span id="js-fill-star" class="stars">
<img src="' . (1 <= esc_attr($a['value']) ? esc_url(get_theme_file_uri()) . '/icons/icon_star_filled.png' : esc_url(get_theme_file_uri()) . '/icons/icon_star.png') . '" alt="star">
<img src="' . (2 <= esc_attr($a['value']) ? esc_url(get_theme_file_uri()) . '/icons/icon_star_filled.png' : esc_url(get_theme_file_uri()) . '/icons/icon_star.png') . '" alt="star">
<img src="' . (3 <= esc_attr($a['value']) ? esc_url(get_theme_file_uri()) . '/icons/icon_star_filled.png' : esc_url(get_theme_file_uri()) . '/icons/icon_star.png') . '" alt="star">
<img src="' . (4 <= esc_attr($a['value']) ? esc_url(get_theme_file_uri()) . '/icons/icon_star_filled.png' : esc_url(get_theme_file_uri()) . '/icons/icon_star.png') . '" alt="star">
<img src="' . (5 <= esc_attr($a['value']) ? esc_url(get_theme_file_uri()) . '/icons/icon_star_filled.png' : esc_url(get_theme_file_uri()) . '/icons/icon_star.png') . '" alt="star">
</span>
<b class="number">' . esc_attr(number_format($a['value'], 1)) . '</b>
</dt>
<dd class="chartBody"><canvas id="radarChart"></canvas></dd>
</dl>';
}
add_shortcode( 'chart', 'chart_shortcode_func' );
果たしてこれがパフォーマンス的に良いかどうかは置いておいて・・与えられたパラメータから三項演算子を使用して動的に画像を変更した例です。
valueの値によって色付き星マークの画像を動的に表示するグラフのショートコードができました。
[chart value="3.5"]
while文を使用したい
繰り返しフィールドなどで入力したデータの数だけ一部のHTMLを生成したい、ということも出てきます。
データの数だけliの要素を生成したい、みたいな感じですね。
こんな感じで書けます。
function hoge_shortcode_func( $atts ) {
$code = '';
$code .= '<ul>';
while (the_repeater_field('chart')) {
$code .= '<li><dl><dt>' . get_sub_field('label') . '</dt><dd>【<img src="' . esc_url(get_theme_file_uri()) . '/icons/icon_star_filled.png" alt="star">' . number_format(get_sub_field('point'), 1) . '】</dd></dl></li>';
}
$code .= '</ul>';
return $code;
}
add_shortcode( 'hoge', 'evaluation_shortcode_func' );
変数$code
に.=
でHTMLを付け足して返り値としています。
こちらのショートコードはこのようになります。(見やすいように改行しています。)
[hoge]
// ブラウザでの表示
<ul>
<li>
<dl>
<dt>データ</dt>
<dd>【<img src="https://〜/icons/icon_star_filled.png" alt="star">3.0】</dd>
</dl>
</li>
<!-- データの数だけ li を出力 -->
<li></li>
...
</ul>
やり方分からなくて結構ハマったのは秘密です。
ついでにクイックタグ化する
クイックタグとはWordPressのv4以下でテキストエディタに搭載されていたボタンです。
WordPress v5.0.0からはエディタが変わったので最近始めたばかりの人はあまり見かけることはないと思いますが、企業ではまだまだv4以下のところで運用している企業も少なくはないです。
こちらもfunctions.phpに書いていきます。
function chart_quicktags() {
if ( wp_script_is( 'quicktags' ) ) {
?>
<script type="text/javascript">
QTags.addButton( 'chart', 'レーダーチャート', '[chart]', '');
</script>
<?php
}
}
add_action( 'admin_print_footer_scripts', 'chart_quicktags' );
これでテキストエディタのボタンに『レーダーチャート』というボタンが配置されました。
ボタンをクリックすると[chart]
というショートコードが挿入されます。
これで完成です!
ちなみにビジュアルエディタのほうにボタンを追加するとなると別の方法になりますのでお気をつけて。
参考にしたサイト
- Chart.jsでグラフを描画してみた
- 【Chart.js】ワードプレスの記事にグラフを入れる方法!(コピペでOK)
- Advanced Custom Fieldsの基本的な使い方!入力欄を追加し出力する方法【WordPressプラグイン】
- 【WordPress】ACFのアドオン「繰り返しフィールド」の導入から出力まで!
- Custom Field Suiteループのショートコードを作成
- PHPで配列に要素を追加する方法
- PHPからJavaScriptへ配列を受け渡す方法を現役エンジニアが解説【初心者向け】
- WordPress ショートコードの作成とエディタへのボタン追加