symfony / ux

Symfony UX initiative: a JavaScript ecosystem for Symfony
https://ux.symfony.com/
MIT License
812 stars 295 forks source link

chart.js@3.9.1 not rendering in Symfony 7.1.* #2005

Closed iXscite closed 1 month ago

iXscite commented 1 month ago

I built the following framework:

*symfony new iXsFactory --version="7.1." --webapp // This command is automatically adding @hotwired/stimulus, @symfony/stimulus-bundle and @hotwired/Turbo composer require symfony/ux-chartjs php bin/console importmap:require bootstrap // This command is automatically adding @bootstrap, @popperjs/core and bootstrap/dist/css/bootstrap.min.css php bin/console importmap:require jquery ... composer require easycorp/easyadmin-bundle** ...

In this framework I designed the following dashboard controller:

#[Route('/people', name: 'app_people')]
public function index(ChartBuilderInterface $chartBuilder = null): Response
{
   assert(null !== $chartBuilder);
   $latestQuestions = $this->questionRepository
      ->findLatest();
   $topVoted = $this->questionRepository
      ->findTopVoted();
   return $this->render('people/index.html.twig',[
      'latestQuestions' => $latestQuestions,
      'topVoted' => $topVoted,
      'chart' => $this->createChart($chartBuilder),            
   ]);
}

which created the following element:

\

Unfortunately the element is not shown (it did with Symfony 6.1 using the symfony/webpack-encore bundle). Application-specific stimulus-controllers like the "Hello"-controller do work.

I've tried a lot but without any success and now unfortunately I need support.

smnandre commented 1 month ago

Two questions to narrow down the possibilities

iXscite commented 1 month ago

Thank you very much for your response and I am very sorry not having provided any information on this.

The header of the base template considers:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
        {% block head_stylesheets %}
            <link rel="stylesheet" href="/bundles/easyadmin/app.19616e33.css">
        {% endblock %}
        {% block javascripts %}
            {% block importmap %}{{ importmap('app') }}{% endblock %}
        {% endblock %}
    </head>
   <body>
      ...
   </body>
</html>

The import map looks like:

<?php

return [
    'app' => [
        'path' => './assets/app.js',
        'entrypoint' => true,
    ],
    '@hotwired/stimulus' => [
        'version' => '3.2.2',
    ],
    '@symfony/stimulus-bundle' => [
        'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js',
    ],
    '@hotwired/turbo' => [
        'version' => '7.3.0',
    ],
    'chart.js' => [
        'version' => '3.9.1',
    ],
    'bootstrap' => [
        'version' => '5.3.3',
    ],
    '@popperjs/core' => [
        'version' => '2.11.8',
    ],
    'bootstrap/dist/css/bootstrap.min.css' => [
        'version' => '5.3.3',
        'type' => 'css',
    ],
    'jquery' => [
        'version' => '3.7.1',
    ],
    'js-confetti' => [
        'version' => '0.12.0',
    ],
    '@fortawesome/fontawesome-free/css/all.css' => [
        'version' => '6.6.0',
        'type' => 'css',
    ],
    '@fontsource-variable/roboto-condensed/index.min.css' => [
        'version' => '5.0.3',
        'type' => 'css',
    ],
];

The console just tells:

[Intervention]Images loaded lazily and replaced with placeholders. Load events are deferred. See https://go.microsoft.com/fwlink/?linkid=2048113

So my answers would be:

Yes Yes No

My app.js in assets looks like:

// start the Stimulus application
import './bootstrap.js';

// imports relative to assets/ (./)
import './styles/app.css';
import './styles/dialog.css';

// Bare imports (as stated in importmap.php run automated)
/*
import 'bootstrap/dist/css/bootstrap.min.css';
import '@fortawesome/fontawesome-free/css/all.css';
import '@fontsource-variable/roboto-condensed/index.min.css';
*/
iXscite commented 1 month ago

I am sorry I forgot the header of the element displayed:

<head>
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="robots" content="noindex, nofollow, noarchive, nosnippet, noodp, noimageindex, notranslate, nocache">
   <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
   <meta name="generator" content="EasyAdmin">
   <title>
     Dashboard
   </title>
   <link rel="stylesheet" href="/bundles/easyadmin/app.19616e33.css">
   <link rel="shortcut icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⬛</text></svg>">
   <script src="/bundles/easyadmin/app.18be9a54.js"></script>
</head>
smnandre commented 1 month ago

It looks to me your importmap is not loaded in the Dashboard of EasyAdmin ... if you move your controller outside EasyAdmin, does it work ?

iXscite commented 1 month ago

Thank you, will check that tommorow!

smnandre commented 1 month ago

I just checked this

symfony new iXsFactory --version="7.1.*" --webapp
cd iXsFactory
composer require symfony/ux-chartjs
symfony server:start

Created a IndexController (src/Controller/IndexController.php)

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\UX\Chartjs\Builder\ChartBuilderInterface;
use Symfony\UX\Chartjs\Model\Chart;

class IndexController extends AbstractController
{
    #[Route('/', name: 'app_index')]
    public function index(ChartBuilderInterface $chartBuilder): Response
    {
        $chart = $chartBuilder->createChart(Chart::TYPE_LINE)
            ->setData([
                'labels' => ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
                'datasets' => [
                    [
                        'label' => 'Month',
                        'data' => [1, 2, 3, 4, 5, 6, 7],
                    ],
                ],
            ]);

        return $this->render('index.html.twig', [
            'chart' => $chart,
        ]);
    }
}

And a Twig template (templates/index.html.twig)

{% extends 'base.html.twig' %}

{% block body %}

    {{ render_chart(chart) }}

{% endblock %}

And it works as expected

Capture d’écran 2024-07-24 à 21 13 32

So this is probably something to do with the way your template is rendered in your EasyAdmin i think.

You will probably find more qualified people to help you in the EasyAdminBundle repository :)

iXscite commented 1 month ago

Thank you so much for all your support! I will follow your link and maybe Javiere Guiluz has read our thoughts and can help me ...

smnandre commented 1 month ago

Ok, it seems you need to add some configuration into your dashboard controller

https://symfony.com/bundles/EasyAdminBundle/4.x/design.html#adding-custom-web-assets

    public function configureAssets(): Assets
    {
        return Assets::new()
            ->addAssetMapperEntry('app')
            ;
    }

This should be enough

smnandre commented 1 month ago
<?php

namespace App\Controller\Admin;

use EasyCorp\Bundle\EasyAdminBundle\Config\Assets;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\UX\Chartjs\Builder\ChartBuilderInterface;
use Symfony\UX\Chartjs\Model\Chart;

class DashboardController extends AbstractDashboardController
{
     public function __construct(
        private ChartBuilderInterface $chartBuilder,
    ) {
    }

    #[Route('/admin', name: 'admin')]
    public function index(): Response
    {
        $chart = $this->chartBuilder->createChart(Chart::TYPE_LINE)
            ->setData([
                'labels' => ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
                'datasets' => [
                    [
                        'label' => 'Month',
                        'data' => [1, 2, 3, 4, 5, 6, 7],
                    ],
                ],
            ]);
        return $this->render('my_dashboard.html.twig', [
            'chart' => $chart,
        ]);
    }

    public function configureAssets(): Assets
    {
        return Assets::new()
            ->addAssetMapperEntry('app')
            ;
    }
}
{# templates/admin/my_dashboard.html.twig #}
{% extends '@EasyAdmin/layout.html.twig' %}

{% block main %}

    {{ render_chart(chart) }}

{% endblock %}
iXscite commented 1 month ago

I tried things like

public function configureAssets(): Assets
{
   return parent::configureAssets()
      ->addAssetMapperEntry('app');
}

or

public function configureAssets(): Assets
{
   return parent::configureAssets()
      ->addAssetMapperEntry(Asset::new('app'));
}

or

public function configureAssets(): Assets
{
   return parent::configureAssets()
      ->addAssetMapperEntry(Asset::new('app')->preload());
}

or

public function configureAssets(): Assets
{
   return parent::configureAssets()
      ->addAssetMapperEntry(Asset::new('@hotwired/stimulus'))
      ->addAssetMapperEntry(Asset::new('@symfony/stimulus-bundle'))
      ->addAssetMapperEntry(Asset::new('chart.js'));
}

or your proposal but none of them are working. Interestingly the \<head> section, which I have posted above, does not change at all. Whatever I am trying, I am not getting any additional \<link> or \<script> tags.

iXscite commented 1 month ago

Dear Andre,Thank you very much for your support. As you might have seen your proposal did'nt work for some reason. According to your advice I have opened another issue in the easyadminbundle repository tpday and I hope  someone knows this problem.Again, thank you,JensAm 24.07.2024 22:30 schrieb Simon André @.***>: Ok, it seems you need to add some configuration into your dashboard controller https://symfony.com/bundles/EasyAdminBundle/4.x/design.html#adding-custom-web-assets public function configureAssets(): Assets { return Assets::new() ->addAssetMapperEntry('app') ; } This should be enough

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>