Symfony Advent Calendar 2021 day 12の記事です。
Hi, it’s me again :grin:
木・金とSymfony Worldで英語ばかり読んだり聞いたり書いたりしてきたので脳内英語モードが抜けません 😅
Symfony Worldオンラインは今回で終わりと言われていたにも関わらず、次回2022年6月もオンライン開催があります! call for paper は2/14まで。

さて、Symfony World中にSymfonyUX2.0がリリースされてしまったので 💦 この記事は書いて公開した瞬間に古くなることが確定なのですが…。
SymfonyUX(v1.0)のchart.jsにプラグインを追加してみたのでやり方をご紹介します。

chart.jsのプラグイン

chart.jsにはプラグイン機構があり、グラフに機能を追加することができます。
https://github.com/chartjs/awesome#plugins

symfony-uxのchart.jsにプラグインを追加するために具体的にやったこと

Symfonyプロジェクトに symfony/ux-chartjs の導入までは済んでいる前提で、そこからプラグインを追加するために必要な手順のみ書いていきます。

導入したいchart.jsのプラグインをyarn installする

chart.js自体は composer require symfony/ux-chartjs 実行時にflexにより自動でpackage.jsonに追加されているのですが、今回導入したいプラグインはsymfony-uxが提供しているパッケージではないため、純粋なnodeの依存として個別でyarn installします。

assets/controllersにStimulusのcontroller brandnew_controller を作る

# assets/controllers/brandnew_controller.js

import { Controller } from 'stimulus';

export default class extends Controller {
    connect() {
    }

    disconnect() {
    }
}

twigでsymfony-uxのrender_chartに data-controller: brandnew を渡しておく

- {{ render_chart(chart) }}
+ {{ render_chart(chart, { 'data-controller': 'brandnew' }) }}

brandnew_controllerにchart.jsプラグインの読み込みを追加する

# assets/controllers/brandnew_controller.js

import { Controller } from 'stimulus';
+import chartjsPluginAnnotation from 'chartjs-plugin-annotation';

export default class extends Controller {
    connect() {
+        this.element.addEventListener('chartjs:pre-connect', this._onPreConnect);
    }

    disconnect() {
+        this.element.removeEventListener('chartjs:pre-connect', this._onPreConnect);
    }

+    _onPreConnect(event) {
+        event.detail.options.plugins = {
+            annotation: chartjsPluginAnnotation
+        };
    }
}

render_chartはchart.jsのオプションを渡すとそのままレンダリングしてくれるので、必要なプラグイン用オプションをphpで書く

<?php

# src/Service/CreateChartService.php

        $chart->setOptions([
            'annotation' => [
                'annotations' => [
                    [
                        'drawTime' => 'afterDraw',
                        'type' => 'line',
                        'mode' => 'vertical',
                        'scaleID' => 'x-axis-0',
                        'value' =>  $startedAtIndex,
                        'borderColor' => 'red',
                        'borderWidth' => 2,
                    ],
                ],
            ],
        ]);

まとめ

あまりフロントエンドは得意じゃない私でも意外とかんたんに実装できてしまいました。 Stimulusを怖がらず、これからはもう少し色々触ってみようと思います :grin: