Lazy as F! Isn’t About D.R.Y but B.A.F When Creating ChartJS
Tags: webdev, php, htmx, devjournal
Published: 2024-04-01 12:56:52

Hello Punk! I am again… Yes the **Software Freestyle Engineer**! Too handsome and stupid from the first time you think who am I.

> *What I want to share about the title above “Lazy as F! Isn’t About D.R.Y but B.A.F When Creating ChartJS”?*
> 

Let me tell to you…

## What The D.R.Y?

Yes! As you expect! Thank you very much…

## What The B.A.F Mean?

***Boring As F!*** Thank you very much again. I think I am too handsome for doing the kinda stuff over and over in ChartJS! So, I creating component (yes, if you think kind of React-things) like using HTML. For efficiency:

```php
<?php
// Filename: /home/darkterminal/workspace/fck-htmx/app/config/ChartJS.php

namespace App\config\helpers;

class ChartJS
{
    private $type;
    private $data;
    private $options;

    public function __construct($type, $customOptions = [])
    {
        $this->type = $type;
        $this->data = [
            'labels' => [],
            'datasets' => []
        ];

        $defaultOptions = [
            'responsive' => true,
            'plugins' => [
                'title' => [
                    'display' => true,
                    'text' => 'Chart.js ' . ucfirst($type) . ' Chart'
                ]
            ]
        ];
        $this->options = array_replace_recursive($defaultOptions, $customOptions);
    }

    public function addLabel($label)
    {
        $this->data['labels'][] = $label;
        return $this;
    }

    public function addDataset($label, $data, $backgroundColor, $borderColor, $additionalOptions = [])
    {
        $dataset = [
            'label' => $label,
            'data' => $data,
            'backgroundColor' => $backgroundColor,
            'borderColor' => $borderColor
        ];

        $dataset = array_merge($dataset, $additionalOptions);

        $this->data['datasets'][] = $dataset;
        return $this;
    }

    public function setOptions($options)
    {
        $this->options = array_merge_recursive($this->options, $options);
        return $this;
    }

    public function getChartConfig()
    {
        return [
            'type' => $this->type,
            'data' => $this->data,
            'options' => $this->options
        ];
    }

    public function create(array $chartConfig, string $canvasName = 'myChart')
    {
        $html = '<div class="w-full">
                <canvas id="' . $canvasName . '"></canvas>
            </div>
            <script type="module">
                import {
                    Chart,
                    registerables
                } from \'https://cdn.jsdelivr.net/npm/chart.js@4.4.2/+esm\';
                Chart.register(...registerables);
                const ctx = document.getElementById(\'' . $canvasName . '\');

                if (ctx) {
                    new Chart(ctx, ' . json_encode($chartConfig) . ');
                } else {
                    console.error(\'Canvas element with ID: ' . $canvasName . ' not found.\');
                }
            </script>';

        return $html;
    }
}

```

I am a simple man and to the point! So, I created this `ChartJS Class` to wrap up the boring stuff and avoid switching between PHP and JavaScript over and over again. You know what I mean, right? Just say “Yes!” please…

I am a Software Engineer specializing in freestyle development, building web applications using PHP and HTMX. Therefore, I need to focus on writing less JavaScript code and shifting my state mindset to the server.

## The Class Usage

Instead of writing a bunch of JSON, I just need to write in my own preferred language (*it's not a language, some people say from the background*). Yes, PHP! That's part of Hypermedia, so I write using it.

![PHP Hypertext Preprocessor](https://i.imgur.com/sOBHwCK.png)

```php
<?php
// Filename: /home/darkterminal/workspace/fck-htmx/views/components/dashboard/partials/ritail.chart.php

use App\config\helpers\ChartJS;

$overrideOptions = [
    'responsive' => true,
    'plugins' => [
        'legend' => [
            'display' => false
        ],
        'title' => [
            'display' => false,
            'text' => 'Ritail Chart'
        ]
    ]
];

$chartJS = new ChartJS('line', $overrideOptions);

$chartConfig = $chartJS->addLabel('January')
    ->addLabel('February')
    ->addLabel('March')
    ->addDataset('Dataset 1', [65, 59, 80], 'rgba(75, 192, 192, 0.2)', 'rgb(75, 192, 192)')
    ->addDataset('Dataset 2', [28, 48, 40], 'rgba(54, 162, 235, 0.2)', 'rgb(54, 162, 235)')
    ->setOptions([
        'scales' => [
            'y' => [
                'beginAtZero' => true
            ]
        ],
        'elements' => [
            'line' => [
                'tension' => 0.4
            ]
        ]
    ])
    ->getChartConfig();

$chartHTML = $chartJS->create($chartConfig, 'ritailChart');

echo $chartHTML;

```

Did you see that!?

- Defined the options overrides (optional)
- Create `ChartJS` instance and define the chart type
- Add all what you need, Label, Datasets, chart configs
- and generate that code, add an id to draw the chart

That's it! You're welcome…