Symfony UX로 COVID-19 데이터 시각화 생성

  • Creating the Project
  • Lauching the Local Web Server
  • Installing Webpack Encore
  • Installing UX Chart.js
  • Creating the Covid-19 Http Client
  • Creating the Covid Controller
  • Rendering the Chart



  • 12월 초, Symfony는 Symfony를 위한 새로운 JavaScript 에코시스템인 Symfony UX를 발표하면서 기조연설을 시작했습니다.

    Symfony UX is a series of tools to create a bridge between Symfony and the JavaScript ecosystem.



    이니셔티브에 대한 전체 개요를 보려면 Symfony World 재생, 특히 Fabien’s keynoteTitouan’s talk 을 시청할 수도 있습니다.

    현재 Symfony는 다음을 제공합니다5 packages.
  • UX Chart.js
  • UX Cropper.js
  • UX 드롭존
  • UX 지연 이미지
  • UX 스왑

  • 이 튜토리얼에서는 일부 COVID-19 데이터를 UX Chart.js 라이브러리로 그래프화하여 Chart.js 패키지를 소개합니다. 이를 위해 free Covid-19 API 에서 국가별 총 사례 및 사망 수를 표시하는 선형 차트를 만듭니다.



    프로젝트 생성

    First of all, we need to set up and configure a project:

    $ symfony new covid --full
    $ cd covid/
    

    로컬 웹 서버 실행

    Start a local web server executing the command:

    $ symfony server:start
    
    For the tutorial, we will suppose that the webserver is listening to http://localhost:8000 .

    웹팩 앙코르 설치

    As we will use a JavaScript library, we need to manage JavaScript in Symfony using Webpack:

    $ symfony composer req symfony/webpack-encore-bundle
    $ yarn install
    
    Symfony now integrates Stimulus 프로젝트 내에서 JavaScript 코드를 구성합니다. assets/ 디렉토리를 살펴보면 새로운 JavaScript 디렉토리 구조를 볼 수 있습니다.
  • controllers/ : 응용 프로그램의 자극 제어기를 포함합니다. app.js ,
  • 에 자동으로 등록됩니다.
  • controllers.json : 설치된 Symfony UX 패키지에서 제공하는 Stimulus 컨트롤러를 참조합니다.

  • UX Chart.js 설치

    Let's install our first UX package:

    $ symfony composer req symfony/ux-chartjs
    

    Symfony Flex has just added a reference to the Javascript code of UX-Chart.js in the package.json :

    {
        "devDependencies": {
            "@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/Resources/assets"
        },
    }
    

    Symfony Flex also added a reference to the Stimulus controller of UX-Chart.js in the assets/controllers.json :

    {
        "controllers": {
            "@symfony/ux-chartjs": {
                "chart": {
                    "enabled": true,
                    "webpackMode": "eager"
                }
            }
        },
        "entrypoints": []
    }
    

    Because of these changes, we now need to install the new JavaScript dependencies and compile the new files:

    $ yarn install
    $ yarn encore dev
    

    Now, the UX package is ready.

    Covid-19 Http 클라이언트 생성

    Thanks to a free Covid-19 API ( https://api.covid19api.com ), 다음 끝점을 사용하여 국가별 총 사례 및 사망 수를 가져올 수 있습니다.

    GET https://api.covid19api.com/total/country/$country
    


    $country 는 https://api.covid19api.com/countries 의 슬러그여야 합니다.

    Symfony는 API를 사용하기 위한 구성 요소HttpClient를 제공합니다. 요청된 URL을 기반으로 클라이언트를 자동 구성하려면 범위가 지정된 클라이언트를 추가합니다.

    # config/packages/framework.yaml
    framework:
       http_client:
            scoped_clients:
                covid:
                    base_uri: https://api.covid19api.com
    

    covid 클라이언트에는 covid라는 고유한 서비스가 있습니다.

    날짜별로 국가 및 그룹별로 총 사례 및 사망 수를 가져올 책임이 있는 CovidHttpClient 서비스를 만듭니다.

    <?php
    
    namespace App\HttpClient;
    
    use Symfony\Contracts\HttpClient\HttpClientInterface;
    
    /**
     * Class CovidHttpClient
     * @package App\Client
     */
    class CovidHttpClient
    {
        /**
         * @var HttpClientInterface
         */
        private $httpClient;
    
        /**
         * CovidHttpClient constructor.
         *
         * @param HttpClientInterface $covid
         */
        public function __construct(HttpClientInterface $covid)
        {
            $this->httpClient = $covid;
        }
    
        /**
         * Get total number of cases and deaths by the given country.
         * 
         * @param string $country
         * 
         * @return array
         */
        public function getTotalByCountry(string $country): array
        {
            $response = $this->httpClient->request('GET', "/total/country/$country");
            $data = json_decode($response->getContent(), true);
    
            $total = [];
    
            foreach ($data as $dailyData) {
                $date = (new \DateTime($dailyData['Date']))->format('Y-m-d');
                $total[$date] = $dailyData;
            }
    
            return $total;
        }
    }
    

    $covid 유형으로 인수 HttpClientInterface가 있으므로 autowiring은 covid 서비스를 클래스에 주입합니다.

    이제 차트를 만들 준비가 되었습니다.

    Covid 컨트롤러 만들기

    Create the controller using the Maker bundle:

    symfony console make:controller CovidController
    

    The command creates a CovidController class under the src/Controller/ directory and a template file to templates/covid/index.html.twig .

    In the CovidController , implement the index() method:

    • Fetch the total number of cases and deaths by country using the CovidHttpClient service and group all by status;
    • Create a Chart object by using the ChartBuilderInterface builder;
    • Set the data (labels & datasets) to the Chart object;
    • Finally, pass the Chart object to the Twig template covid/index.html.twig .
    <?php
    
    namespace App\Controller;
    
    use App\HttpClient\CovidHttpClient;
    use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
    use Symfony\Component\HttpFoundation\Response;
    use Symfony\Component\Routing\Annotation\Route;
    use Symfony\UX\Chartjs\Builder\ChartBuilderInterface;
    use Symfony\UX\Chartjs\Model\Chart;
    
    class CovidController extends AbstractController
    {
        /**
         * @Route("/{country}", name="covid")
         */
        public function index(CovidHttpClient $covidClient, ChartBuilderInterface $chartBuilder, $country = 'france'): Response
        {
            $total = $covidClient->getTotalByCountry($country);
            $totalByStatus = [];
            foreach ($total as $dailyTotal) {
                $totalByStatus['confirmed'][] = $dailyTotal['Confirmed'];
                $totalByStatus['deaths'][] = $dailyTotal['Deaths'];
                $totalByStatus['recovered'][] = $dailyTotal['Recovered'];
                $totalByStatus['active'][] = $dailyTotal['Active'];
            }
    
            $chart = $chartBuilder->createChart(Chart::TYPE_LINE);
            $chart
                ->setData([
                    'labels' => array_keys($total),
                    'datasets' => [
                        [
                            'label' => 'Confirmed',
                            'backgroundColor' => 'rgb(120, 161, 187, 0.5)',
                            'data' => $totalByStatus['confirmed']
                        ],
                        [
                            'label' => 'Death',
                            'backgroundColor' => 'rgb(219, 80, 74, 0.5)',
                            'data' => $totalByStatus['deaths']
                        ],
                        [
                            'label' => 'Recovered',
                            'backgroundColor' => 'rgb(147, 196, 139, 0.5)',
                            'data' => $totalByStatus['recovered']
                        ],
                        [
                            'label' => 'Active',
                            'backgroundColor' => 'rgb(252, 191, 73, 0.5)',
                            'data' => $totalByStatus['active']
                        ]
                    ]
                ]);
    
            return $this->render('covid/index.html.twig', [
                'chart' => $chart,
                'country' => $country
            ]);
        }
    }
    
    You can read Chart.js documentation 모든 옵션을 검색합니다.

    차트 렌더링

    The last step is to update the templates/covid/index.html.twig file:

    {% extends 'base.html.twig' %}
    
    {% block body %}
        <h1>Total number of cases and deaths in {{ country|capitalize }}</h1>
        {{ render_chart(chart) }}
    {% endblock %}
    
    It's done! Go to the homepage by specifying the country parameter. The list of countries is available on https://api.covid19api.com/countries .
    여기 몇 가지 예가 있어요.
  • http://localhost:8000/australia
  • http://localhost:8000/france
  • http://localhost:8000/united-states
  • 좋은 웹페이지 즐겨찾기