Memes that made me laugh 67

https://1.bp.blogspot.com/-mJ2fzWrlOig/YPTfrYaEHMI/AAAAAAAAtJA/egR3PlT-tWkaZWvvbpl0MsmB9Q8mLU8lACPcBGAsYHg/w349-h400/Meme%2B-%2Bghosts%2Band%2Bsheets.png

 

Gathered around the Intertubes over the past seven days.  Click any image for a larger view.

(Learn more about the seax)

More next week.

Peter

Bayou Renaissance Man

How to Create Your Own Helper Functions in Laravel

https://ashallendesign.ams3.digitaloceanspaces.com/public/blog/25/how-to-create-your-own-helper-functions-in-laravel.png

Introduction

Helper functions can be extremely useful in your Laravel projects. They can help to simplify your code in your projects in a clean and easy way. Laravel comes with many helper functions out-the-box such as dd(), abort() and session(). But as your projects start to grow, you’ll likely find that you’ll want to add your own.

In this article, we’re going to look at how we can create and use our own custom PHP helper functions in our Laravel projects.

Creating the Helper Function

To add our own helper functions, we need to start by creating a new PHP file to place them in. So, let’s create a helpers.php file inside our app folder. As a side note, this location is down to personal preference really. Another common place I’ve seen the file placed is inside an app/Helpers/helpers.php file. So, it’s down to you to choose a directory that you feel works best for you.

Now, that we’ve got our file, we can add our helper function to it. As a basic example for this article, we’re going to be creating a super-simple function that converts minutes to hours.

Let’s add the function to our helpers.php file like so:

<?php
  
if (! function_exists('seconds_to_hours')) {
    function seconds_to_hours(int $seconds): float
    {
        return $seconds / 3600;
    }
}

As you can see in the example above, the function itself is really simple. However, one thing that you might notice is that the function name is written in snake case (e.g. seconds_to_hours) rather than camel case (e.g. secondsToHours) like you’d usually see with method names on a class. You aren’t necessarily fixed to using snake case for defining the function name, but you’ll find that all of the Laravel helper functions are written this way. So, I’d probably advise to use the format just so that you can follow the typical standard and format that’s expected. This is totally up to you though.

Another thing that you might have noticed is that we have wrapped the function name inside an ‘if’ statement. This is to stop us from accidentally redeclaring any helpers with the same name that have already been registered. For example, let’s say that we were using a package that already had a seconds_to_hours() function registered, this would prevent us from registering our own function with the same name. To get around this, we could just simply change the name of our own function to avoid any clashes.

It’s also really important to remember when creating helper functions that they are only supposed to be used as helpers. They aren’t really meant to be used to perform any business logic, but rather to help you tidy up your code. Of course, you can add complex logic to them, but if this is something you’re looking to do, I’d probably advise thinking about if the code would be a better fit in another place such as a service class, action class or trait.

Registering the Helper Function

Now that we’ve created our helper file, we need to register it so that we can use our new function. To do this, we can update our composer.json file so that our file is loaded at runtime on each request and is available for using. This is possible because Laravel includes the Composer class loader in the public/index.php file.

In your composer.json file, you should have a section that looks like this:

"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Database\\Factories\\": "database/factories/",
        "Database\\Seeders\\": "database/seeders/"
    }
},

In this section, we just need to add the following lines to let Composer know that you want to load your file:

"files": [
    "app/helpers.php"
],

The autoload section of your composer.json file should now look like this:

"autoload": {
    "files": [
        "app/helpers.php"
    ],
    "psr-4": {
        "App\\": "app/",
        "Database\\Factories\\": "database/factories/",
        "Database\\Seeders\\": "database/seeders/"
    }
},

Now that we’ve manually updated the composer.json file, we’ll need to run the following command to dump our autload file and create a new one:

composer dump-autoload

Using the Helper Function

Congratulations! Your helper function should now be all set up and ready to use. To use it, you can simply use:

seconds_to_hours(331);

Because it’s been registered as a global function, this means you can use it in a variety of places such as your controllers, service classes and even other helper functions. The part that I love about helper functions most though is being able to use them in your Blade views. For example, let’s imagine that we had a TimeServiceClass that contained a secondsToHours() method that did the same as our new function. If we were to use the service class in our Blade view, we might have to do something like this:


As you can imagine, if this was used in multiple places across a page, it could probably start to make your view a bit messy.

Taking It Further

Now that we’ve seen how we can register and use the helpers, we will look at how we can take it one step further. Over time, as your Laravel projects grow, you might find that you have a large amount of helpers that are all in one file. As you can imagine, the file might start to look a bit unorganised. So, we might want to think about splitting our functions out into separate files.

For the sake of the article, let’s imagine that we have many helpers in our app/helpers.php file; some related to money, some related to time and some related to user settings. We could start by splitting those functions out into separate files such as: app/Helpers/money.php, app/Helpers/time.php and app/Helpers/settings.php. This means that we can now delete our app/helpers.php file because we don’t need it anymore.

After that, we can update our composer.json file in a similar way to before so that it nows loads our 3 new files:

"autoload": {
    "files": [
        "app/Helpers/money.php",
        "app/Helpers/settings.php",
        "app/Helpers/time.php",
    ],
    "psr-4": {
        "App\\": "app/",
        "Database\\Factories\\": "database/factories/",
        "Database\\Seeders\\": "database/seeders/"
    }
},

We’ll need to remember to dump the Composer autoload file again by running the following command:

composer dump-autoload

You should now be able to continue using your functions and have the benefit of them being split into logically-separated files.

Conclusion

Hopefully this article has shown you how to create and register your own PHP helper functions for your Laravel projects. Remember not to use them to perform complex business logic and to see them more as a way of tidying up little bits of code.

If you’ve enjoyed reading this post and found it useful, feel free to sign up for my newsletter below so that you can get notified each time I publish a new article.

Keep on building awesome stuff! 🚀

Laravel News Links

How to Deploy Your Laravel Website to Heroku for Free

https://postsrc.com/storage/6rLgsRfVYk79nEdllmhcANPLmilf6HmE80aXJFSt.jpg

In this post, you’ll learn how to deploy your Laravel website to production for free with Heroku. The steps are very simple and straight forward so let’s get started.

Heroku Homepage

What is Heroku?

Heroku is a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud. Everything from the server instance, database, caching, monitoring, and all of those features will be handled by Heroku so the developer can focus on developing the website.

1 – Register an Account

In order to get started with Heroku, you will have to

register for an account

it’s free so let’s get into it.

2 – Create a New Heroku App

Once you have access to your account, you can create a new app from the dashboard.

Heroku Dashboard

Upon pressing the “create new app” button you will have to provide the necessary details. Fill in the app name, and the region which is closer to you, and finally define the pipeline like below.

Heroku Create New App

Now that the application has been created you will see the dashboard page which contains the details of the application. You can have a look through it but let’s focus on the “deployment method” first.

Heroku Application Details

2.5 – Initialise new Laravel Project

For this example, a new Laravel 8 project will be created and the only addition that you have to add is “Procfile” which is a configuration that’s necessary to instruct Heroku build. Do note that the file name itself is “Procfile” with no extension and it has to be saved in the project root.

// Procfile
web: vendor/bin/heroku-php-nginx /public

The above profile will be using “nginx” as the webserver, but if you prefer to use “apache” webserver then you can define it like below.

// Procfile
web: vendor/bin/heroku-php-apache2 /public

3 – Connect With the Deployment Provider
The provider is the place where the application source code is hosted and how this works is that every time a new update is made to the application and it’s pushed (“git push”) to GitHub or any other online repository, Heroku will get notified and perform its build process and then deploy the application to production. By default, Heroku has 3 providers and they are the:

  • Heroku Git
  • GitHub
  • Container Registry 

In this post, the “Github” method will be used so it’s necessary to “Connect to Github” to provide Heroku access to the repository.

Heroku Connect to Provider

Once it’s connected to GitHub, you can connect to the specific repository for the application to be initialised for deployment.

Heroku Connect to Github Repo

Do note that by default the branch that will be used is the “main” branch and from the settings like on the screenshot below, you can “enable automatic deploys” for a faster push to deployment.

Heroku Deployment Branch

4 – Define Environment Configs

Before deploying the branch, the environment configuration has to be set up from the “Settings” tab. You can reveal the “config vars” but by default will be empty.

Heroku Application Settings Page

Fill in the necessary config variable as the “key” and “value” pair a line at a time. The least necessary config to have is the APP_DEBUG, APP_ENV and APP_KEY.

Heroku Configuration Variable

By now it should be ready to be deployed to production so head back to the “deploy” tab.

5 – Trigger the Manually Deploy Button

From the “manual deploy” section, press the “deploy branch” and let the build process run, it will take few seconds and once it’s ready, you can view it from the link provided or just click the “view” button.


Heroku Manual Deploy

6 – Preview in Browser

Finally, you can preview the application in production and it should look like below. If you have come across any errors, do enable the APP_DEBUG to “true” and APP_ENV to “local”, this way the errors will appear when you access the link.

Heroku Preview Deployment

This URL is fully accessible to the public but do note that if your website doesn’t receive any traffic within 30 mins then the instance/heroku will be in a sleep/hibernate mode so it will take few seconds for the website to load.

By now you should be able to deploy your Laravel app to production with Heroku for free and in the next tutorial, you’ll learn how to set up a database on Heroku. If you found this tutorial to be helpful do share it with your friends, cheers and happy coding 🍻

Other Heroku Related Post

Laravel News Links

When Did Moderna Know About COVID-19?

https://img.patriotpost.us/01FAMYTW6MAXVH23RGK7XV57WH.jpeg?w=1200&h=600

If a report disseminated by a UK website called The Daily Expose is accurate, the world may have a major scandal on its hands.

“A confidentiality agreement shows potential coronavirus vaccine candidates were transferred from Moderna to the University of North Carolina in 2019, nineteen days prior to the emergence of the alleged Covid-19 causing virus in Wuhan, China,” the website reports.

The Expose produced the agreement itself, which can be viewed here. Page 105 is titled “Material Transfer Agreement” between the providers, named as the National Institute of Allergy and Infectious Diseases, National Institutes of Health (“NIAID”) and Moderna TX Inc. (“Moderna”), and the recipient is named as the University of North Carolina at Chapel Hill. The agreement states the providers will give the university “mRNA coronavirus vaccine candidates developed and jointly owned by the NIAID and Moderna.”

The agreement further states the research material may not be used on human subjects or used for “commercial purposes such as screening, production or sale, for which a commercialization license may be required.” The recipients who signed the agreement are Professor Ralph Baric, PhD, and Jaqueline Quay, Director of Licensing & Innovation Support, OTC. The providers are NIAID investigator Barney Graham, MD, PhD; technology transfer specialist Amy Petrik, PhD; Moderna investigator Sunny Himansu, PhD; and Moderna Deputy General Counsel Shaun Ryan. The dates accompanying the recipients’ signatures are December 12, 2019, and December 16, 2019, respectively. The dates under the providers’ first two signatures remain blank, while the second two are both dated December 17, 2019.

“All of these signatures were made prior to any knowledge of the alleged emergence of the novel coronavirus,” The Daily Expose reminds us. “It wasn’t until December 31st 2019 that the World Health Organisation (WHO) became aware of an alleged cluster of viral pneumonia cases in Wuhan, China. But even at this point they had not determined that an alleged new coronavirus was to blame, instead stating the pneumonia was of ‘unknown cause.’”

Its gets even more “curious” than that. Science News published an article titled, “New SARS-like virus can jump directly from bats to humans, no treatment available,” noting that researchers from Chapel Hill discovered “a new bat SARS-like virus that can jump directly from its bat hosts to humans without mutation.”

The senior author of that paper? The same Dr. Ralph Baric who signed the transfer agreement — and the same Dr. Baric who worked with Dr. Shi Zhengli, a.k.a. “bat lady,” at the Wuhan Institute of Virology (WIV) on coronavirus gain-of-function research.

The year Science News published that article? 2015.

A timeline of the pandemic provided by the World Health Organization (WHO) reveals that it requested information “on the reported cluster of atypical pneumonia cases in Wuhan from the Chinese authorities” on January 1. However, it took until January 9 before WHO revealed that “Chinese authorities have determined that the outbreak is caused by a novel coronavirus.”

Thus, the question becomes obvious: Why was an mRNA vaccine developed by Moderna transferred to the University of North Carolina at Chapel Hill nearly a month earlier?

A 2018 article published by CNBC might provide a clue. It reveals that “Wall Street newcomer” Moderna took a beating on its initial public offering, falling nearly 20%. Nonetheless, self-anointed stock guru Jim Cramer remained optimistic. “It’s got an exciting concept; you can argue that messenger-RNA-based medicine could revolutionize health care,” he asserted.

Three years later, the company has generated $1.94 billion in revenue during the first quarter. Its COVID-19 vaccine generated $1.73 billion of that revenue, and the company predicts the vaccine will generate $19.2 billion in revenue by year’s end. “Twelve months ago in Q1 2020, Moderna had never run a phase 3 clinical study, never got a product authorized by a regulator, and never made 100 million doses in a single quarter,” boasted company CEO Stéphane Bancel. “I am very proud of what the Moderna team has achieved.”

Americans might less enthused. For more than a year, anyone who even suggested COVID-19 originated anywhere other than nature was dismissed as a conspiracy theorist. Will those same howls of derision be aimed at anyone who dares to wonder why the development of a vaccine for a virus preceded public knowledge of that virus?

Still more “curious”? A cancer study published in November 2019 revealed the presence of SARS-CoV-2 RBD-specific antibodies in 11.6% of its patients. Since antibodies take time to develop, it’s possible some patients had active infections as early as August 2019. “This study shows an unexpected very early circulation of SARS-CoV-2 among asymptomatic individuals in Italy several months before the first patient was identified, and clarifies the onset and spread of the coronavirus disease 2019 (COVID-19) pandemic,” it stated. “Finding SARS-CoV-2 antibodies in asymptomatic people before the COVID-19 outbreak in Italy may reshape the history of pandemic.”

Unless history is obliterated by propaganda. It is no secret that an increasingly authoritarian Biden administration and its media echo chamber are all in on getting every American vaccinated, whether they want it or not. It is also no secret that those who even dare to suggest there are viable alternatives to the vaccines — alternatives that would abrogate the “emergency use authorization” under which all vaccines are being administered — are being dismissed as quacks and/or demonetized.

Yet reality continues to intrude. According to the Vaccine Adverse Events Reporting System (VAERS), as of July 7, 2021, there have been a reported 438,440 adverse reactions to vaccines, including 9,048 deaths. And while the media remain determined to frame vaccine resistance in terms of “enlightened” blue states vs. “backward” red states, the Kaiser Family Foundation reveals that as of July 8, the two cohorts with the lowest vaccination rates nationwide are blacks (34%) and Hispanics (39%). By contrast, 47% of whites and 62% of Asians have been vaccinated.

At the very least, the above data elicit concern, and also reveal that millions of Americans remain highly skeptical of what they are being told. That skepticism will undoubtedly be amplified by the latest revelation that the Johnson & Johnson vaccine will have a new warning added to its label noting that the shot is linked to a “rare side effect” known as Guillain-Barré syndrome, a malady that occurs when the immune system attacks the body’s nerves.

Yet that skepticism will pale by comparison to the disgust and anger Americans will feel if it turns out the public was kept in the dark about a deadly virus until a large drug company could set itself up to make maximum profits.

The Daily Expose wonders if the National Institute of Allergy and Infectious Diseases would like to explain itself in a court of law. As for an American public subjected to more than a year of often dubious admonitions to “follow the science” — even when that science and the censorship it engendered “evolved” 180 degrees away from its original proclamations — perhaps one of the oldest and most cynical explanations of all is far more apropos:

Follow the money.

The Patriot Post — Current Articles

A Small Piece of Paper Might Be All You Need to Fix Joy-Con Drift on the Nintendo Switch

https://i.kinja-img.com/gawker-media/image/upload/c_fill,f_auto,fl_progressive,g_center,h_675,pg_1,q_80,w_1200/2e4731e332fb202897ce7ad32f668fc7.gif

If you’re one of the thousands of gamers plagued by Joy-Con drift—an issue where the analog sticks on the Nintendo Switch’s controllers register movements even when they’re not being touched—and are frustrated that Nintendo still hasn’t come up with a permanent solution, the fix could be as simple as a tiny millimeter-thick piece of paper.

It’s been four years since the Switch was first released and even units purchased over the past year have started developing the issue known as Joy-Con drift. It’s uncertain why Nintendo hasn’t identified the source of the problem and permanently fixed the hardware (many who’ve sent Joy-Cons to Nintendo for repair report the drifting issue returning months later) but the company is now facing multiple class-action lawsuits around the world as a result of the persistent issue.

There are several theories as to why Joy-Con drift happens, but the most common is that dust and dirt can get into the joystick mechanism, build up, and prevent small metal contacts from touching graphite pads that register the movements of the analog stick. Opening the Joy-Cons and cleaning these contacts remedies the drift, as does occasionally just blasting compressed air into the controller, but the fixes are usually only temporary, and most of the time the Joy-Con drift returns.

That’s what ‘Victorstk’ of the YouTube channel ‘VK’s Channel’ found, so they decided to dig deeper, watching endless videos of both Joy-Con repairs and cleanings, but also videos of the joysticks used on other devices like the portable PSP and PS Vita being repaired. They eventually determined a second issue responsible for Joy-Con drift: over time the metal clamps that hold all of the joystick’s components together loosen, creating a gap between those aforementioned metal contacts and graphite pads, reducing contact and resulting in irregular behavior.

By simply squeezing the middle of the Joy-Con, which applied pressure to and compressed the joystick components ensuring solid contact again between the parts inside, the drifting issue miraculously disappeared. As a more permanent fix, Victorstk simply inserted a thin piece of paper—about a millimeter thick—inside the Joy-Con. The paper compresses all of the joystick’s components back together again. Surprisingly, two months later, a Joy-Con that consistently exhibited drift issues has worked perfectly, Victorstk says.

G/O Media may get a commission

Is this a solution that will work for everyone? It’s hard to say. If a consistent build-up of dust and dirt on the contacts inside the Joy-Con is the cause of the problem, no amount of added pressure is going to keep particles out. But it does seem like Victorstk is onto something, and if more Switch users find this simple trick remedies Joy-Con drifting issues, then we might finally have a permanent solution that could be trivial for Nintendo to implement on future hardware.

Gizmodo

Charts.css Laravel

https://repository-images.githubusercontent.com/371677807/7c8e7880-dd86-11eb-97da-6a5ad34b45b5

Banner

Laravel component to create gorgeous Charts.css charts.

Latest Version on Packagist
GitHub Tests Action Status
GitHub Code Style Action Status
Total Downloads

This package will help you generate CSS only charts based on the Charts.css library.

Installation

You can install the package via composer:

composer require maartenpaauw/laravel-charts-css

Usage

Here’s how you can create a chart:

php artisan make:chart MedalsChart

This will generate a chart component within the View/Components namespace.

<?php

namespace App\View\Components;

use Maartenpaauw\Chartscss\Chart;
use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

class MedalsChart extends Chart
{
    protected function id(): string
    {
        return 'medals-chart';
    }

    protected function heading(): string
    {
        return __('Medals Chart');
    }

    protected function datasets(): DatasetsContract
    {
        return new Datasets(
            new Axes('Country', ['Gold', 'Silver', 'Bronze']),
            new Dataset([
                new Entry(new Value(46)),
                new Entry(new Value(37)),
                new Entry(new Value(38)),
            ], new Label('USA')),
            new Dataset([
                new Entry(new Value(27)),
                new Entry(new Value(23)),
                new Entry(new Value(17)),
            ], new Label('GBR')),
            new Dataset([
                new Entry(new Value(26)),
                new Entry(new Value(18)),
                new Entry(new Value(26)),
            ], new Label('CHN')),
        );
    }
}

To display your chart it is as easily as adding the following blade component:

Make sure you import the css library as well. There is a helper component available for it!

<x-charts-css-stylesheet cdn="unpkg" />

Advanced

See all Charts.css documentation examples within the src/Examples directory or read all the advanced documentation below to learn more.

Tooltips

It is possible to configure a tooltip for each entry like this:

use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Tooltip\Tooltip;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

// ...

protected function datasets(): DatasetsContract
{
    return new Datasets(
        new Axes('Type', 'Amount'),
        new Dataset([
            new Entry(
                new Value(46),
                new Label('Gold'),
                new Tooltip('46 gold medals!'), // <--
            ),
            new Entry(
                new Value(37),
                new Label('Silver'),
                new Tooltip('37 silver medals!'), // <--
            ),
            new Entry(
                new Value(38),
                new Label('Bronze'),
                new Tooltip('38 bronze medals!'), // <--
            ),
        ]),
    );
}

Single dataset

The default generated chart component shows you how you can provide multiple datasets.
If you only want to show a single dataset, you still need to wrap in within a datasets instance.
This is because axes must be provided. The only difference is you need to provide the data axis via the entry
and give a global description via the axes.

use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

// ...

protected function datasets(): DatasetsContract
{
    return new Datasets(
        new Axes('Type', 'Amount'),
        new Dataset([
            new Entry(new Value(46), new Label('Gold')),
            new Entry(new Value(37), new Label('Silver')),
            new Entry(new Value(38), new Label('Bronze')),
        ]),
    );
}

Hiding a specific label

use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

// ...

protected function datasets(): DatasetsContract
{
    return new Datasets(
        new Axes('Type', 'Amount'),
        new Dataset([
            (new Entry(new Value(46), new Label('Gold')))
                ->hideLabel(), // <--
            new Entry(new Value(37), new Label('Silver')),
            new Entry(new Value(38), new Label('Bronze')),
        ]),
    );
}

You can hide an entry’s label by calling the hideLabel() method on a dataset.

Alignment of a specific label

use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

// ...

protected function datasets(): DatasetsContract
{
    return new Datasets(
        new Axes('Type', 'Amount'),
        new Dataset([
            (new Entry(new Value(46), new Label('Gold')))
                ->alignLabel('end'), // <--
            new Entry(new Value(37), new Label('Silver')),
            new Entry(new Value(38), new Label('Bronze')),
        ]),
    );
}

You can align an entry’s label by calling the alignLabel() method on a dataset with start, center or end as parameter.

Multiple datasets

Hiding a specific label

use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

// ...

protected function datasets(): DatasetsContract
{
    return new Datasets(
        new Axes('Country', ['Gold', 'Silver', 'Bronze']),
        (new Dataset([
            new Entry(new Value(46)),
            new Entry(new Value(37)),
            new Entry(new Value(38)),
        ], new Label('USA')))
            ->hideLabel(), // <--
        new Dataset([
            new Entry(new Value(27)),
            new Entry(new Value(23)),
            new Entry(new Value(17)),
        ], new Label('GBR')),
    );
}

You can hide a dataset’s label by calling the hideLabel() method on a dataset.

Hiding a specific label

use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

// ...

protected function datasets(): DatasetsContract
{
    return new Datasets(
        new Axes('Country', ['Gold', 'Silver', 'Bronze']),
        (new Dataset([
            new Entry(new Value(46)),
            new Entry(new Value(37)),
            new Entry(new Value(38)),
        ], new Label('USA')))
            ->alignLabel('end'), // <--
        new Dataset([
            new Entry(new Value(27)),
            new Entry(new Value(23)),
            new Entry(new Value(17)),
        ], new Label('GBR')),
    );
}

You can align a dataset’s label by calling the alignLabel() method on a dataset with start, center or end as parameter.

Stylesheet

Warning! Make sure you insert this component within your base layout template where your chart is not directly used.
Otherwise a custom defined colorscheme won’t be pushed to the CSS stack.

<x-charts-css-stylesheet cdn="unpkg" />

Charts.css host the production CSS file on two difference CDN’s: jsdelivr and unpkg.
You can import the stylesheet by adding the following component to the head within your blade file.

If you add your CSS by using a different way, for example a package manager, you can leave out the cdn attribute.
Then this component will only be used to render the colorscheme definitions.

Type

use Maartenpaauw\Chartscss\AreaChart;

class MyChart extends AreaChart
{
    // ...
}

At the moment there is support for 4 types of charts:

By default, each generated chart is a Column chart. If you want to change the chart type you can overwrite the type
method, or you can inherit the AreaChart, BarChart or LineChart class instead of the Chart class.

When using an area or line chart, you must determine the start of the chart by calling the start method on the first
entry like this:

use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

// ...

protected function datasets(): DatasetsContract
{
    return new Datasets(
        new Axes('Type', 'Amount'),
        new Dataset([
            (new Entry(new Value(46), new Label('Gold')))
                ->start(10),
            new Entry(new Value(37), new Label('Silver')),
            new Entry(new Value(38), new Label('Bronze')),
        ]),
    );
}

Legend

use Maartenpaauw\Chartscss\Legend\Legend;

// ...

protected function legend(): Legend
{
    return parent::legend()
        ->withLabel('Gold')
        ->withLabels(['Silver', 'Bronze'])
        ->inline()
        ->ordered()
        ->squares();
}

By default, no legend is being generated and shown. You can change this behaviour by simply overwriting the legend() method.
By calling the withLabel() or withLabels() method on a Legend instance you can add a label.
By default, the legend is displayed vertically. You can change it to horizontally by chaining the inline() method.

The labels do not have any style by default. You can change the shape by calling one of the following methods:

  • circles()
  • ellipses()
  • lines()
  • rectangles()
  • rhombuses()
  • squares()

By default the HTML tag ul is used to display the legend on the screen. If you prefer an ol HTML tag chain the
ordered() method.

Colorscheme

Warning! Do not forget to add the <x-charts-css-stylesheet /> to your layout’s head.

use Maartenpaauw\Chartscss\Appearance\Colorscheme\Color;
use Maartenpaauw\Chartscss\Appearance\Colorscheme\ColorschemeContract;

// ...

protected function colorscheme(): ColorschemeContract
{
    return parent::colorscheme()
        ->add(new Color('#FF0000'))
        ->add(new Color('#00FF00'))
        ->add(new Color('#0000FF'));
}

The framework has a set of 10 default color repeating themselves.
You can change it by overwriting the colorscheme() method.

If you only add one color, all the data entries will get the same color.
You can add up to 10 colors by calling the add() method on the colorscheme.

use Maartenpaauw\Chartscss\Appearance\Colorscheme\Color;
use Maartenpaauw\Chartscss\Appearance\Colorscheme\ColorschemeContract;

// ...

protected function colorscheme(): ColorschemeContract
{
    return new Colorscheme([
        new Color('#FF0000'),
        new Color('#00FF00'),
        new Color('#0000FF'),
    ]);
}

It is also possible to return a new instance of Colorscheme and given an array with colors as the first constructor parameter.

Specific color for one entry

use Maartenpaauw\Chartscss\Appearance\Colorscheme\Color;
use Maartenpaauw\Chartscss\Data\Axes\Axes;
use Maartenpaauw\Chartscss\Data\Datasets\Dataset;
use Maartenpaauw\Chartscss\Data\Datasets\Datasets;
use Maartenpaauw\Chartscss\Data\Datasets\DatasetsContract;
use Maartenpaauw\Chartscss\Data\Entries\Entry;
use Maartenpaauw\Chartscss\Data\Entries\Value\Value;
use Maartenpaauw\Chartscss\Data\Label\Label;

// ...

protected function datasets(): DatasetsContract
{
    return new Datasets(
        new Axes('Type', 'Amount'),
        new Dataset([
            (new Entry(new Value(46), new Label('Gold')))
                ->color(new Color('#FFD700')), // <--
            new Entry(new Value(37), new Label('Silver')),
            new Entry(new Value(38), new Label('Bronze')),
        ]),
    );
}

Want to change a specific data entry’s color? This can be done by chaining the color method.

Modifications

By overwriting the modifications() method you can add multiple modifications.

Out of the box the ShowHeading modification will be applied when the heading is present
and the modifications Multiple and ShowLabels are applied when there are multiple datasets configured.

All modifications can be found within the Maartenpaauw\Chartscss\Appearance namespace.

Data(sets) spacing

use Maartenpaauw\Chartscss\Appearance\DatasetsSpacing;
use Maartenpaauw\Chartscss\Appearance\DataSpacing;
use Maartenpaauw\Chartscss\Appearance\Modifications;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new DataSpacing(10))
        ->add(new DatasetsSpacing(20));
}

By adding DatasetsSpacing or DataSpacing you can configure the space between the data entries. Both constructors accept a number between 1 and 20 defining the amount of space.

Hide data

use Maartenpaauw\Chartscss\Appearance\HideData;
use Maartenpaauw\Chartscss\Appearance\Modifications;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new HideData());
}

The HideData modification will hide the display value of each entry.
The value will still be printed to the screen, but it is hidden by CSS.
This will respect screenreaders.

Show data on hover

use Maartenpaauw\Chartscss\Appearance\Modifications;
use Maartenpaauw\Chartscss\Appearance\ShowDataOnHover;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new ShowDataOnHover());
}

The ShowDataOnHover modification will hide the data the same way as the HideData modification.
The big difference is it will show the data when you hover it.

Label alignment

use Maartenpaauw\Chartscss\Appearance\LabelsAlignCenter;
use Maartenpaauw\Chartscss\Appearance\LabelsAlignEnd;
use Maartenpaauw\Chartscss\Appearance\LabelsAlignStart;
use Maartenpaauw\Chartscss\Appearance\Modifications;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new LabelsAlignStart())
        ->add(new LabelsAlignCenter())
        ->add(new LabelsAlignEnd());
}

You can configure the label alignment by adding one of the following modifications: LabelsAlignStart, LabelsAlignCenter or LabelsAlignRight.

Multiple

use Maartenpaauw\Chartscss\Appearance\Modifications;
use Maartenpaauw\Chartscss\Appearance\Multiple;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new Multiple());
}

When displaying multiple datasets the modification Multiple needs to be added.
Out of the box it is automatically added if there are multiple datasets.

Reverse

use Maartenpaauw\Chartscss\Appearance\Modifications;
use Maartenpaauw\Chartscss\Appearance\ReverseData;
use Maartenpaauw\Chartscss\Appearance\ReverseDatasets;
use Maartenpaauw\Chartscss\Appearance\ReverseOrientation;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new ReverseData())
        ->add(new ReverseDatasets())
        ->add(new ReverseOrientation());
}

If you want to reverse the data, datasets or the orientation you can add the modifications:
ReverseData, ReverseDatasets or/and ReverseOrientation.

Axes

use Maartenpaauw\Chartscss\Appearance\Modifications;
use Maartenpaauw\Chartscss\Appearance\ShowDataAxes;
use Maartenpaauw\Chartscss\Appearance\ShowPrimaryAxis;
use Maartenpaauw\Chartscss\Appearance\ShowSecondaryAxes;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new ShowDataAxes())
        ->add(new ShowPrimaryAxis())
        ->add(new ShowSecondaryAxes());
}

By default, no axes are shown. You can show the primary axis by adding the ShowPrimaryAxis.
Same goes for the ShowDataAxes.

To display the secondary axes you can add the ShowSecondaryAxes modification.
The constructor accepts the amount of axes (with a limit of 10) as the first parameter.

Show heading

use Maartenpaauw\Chartscss\Appearance\Modifications;
use Maartenpaauw\Chartscss\Appearance\ShowHeading;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new ShowHeading());
}

The heading (table caption) will always be printed to the screen to respect screenreaders,
but it will be hidden with CSS by default. If you want to display the heading you need to add the ShowHeading modification.
This modification will be added automatically when the heading is present.

Show labels

use Maartenpaauw\Chartscss\Appearance\Modifications;
use Maartenpaauw\Chartscss\Appearance\ShowLabels;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new ShowLabels());
}

The labels will always be printed to the screen to respect screenreaders,
but they are hidden with CSS by default. If you want to display the labels you need to add the ShowLabels modification.

Stacked

use Maartenpaauw\Chartscss\Appearance\Modifications;
use Maartenpaauw\Chartscss\Appearance\Stacked;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new Stacked());
}

If you want to stack multiple datasets you can add the Stacked modification.

Did I miss adding a modification?

use Maartenpaauw\Chartscss\Appearance\CustomModification;
use Maartenpaauw\Chartscss\Appearance\Modifications;

// ...

protected function modifications(): Modifications
{
    return parent::modifications()
        ->add(new CustomModification('foo'));
}

Feel free to create a pull request or submitting an issue.
In the meanwhile you can add it easily by adding a CustomModification.

Configuration

As mentioned before, the configuration is pretty smart. It adds a ShowHeading modification if a heading is present,
adds the modifications Multiple when multiple datasets are present, it adds the ShowLabels modification when there
are dataset or entry labels defined, and it uses the configured data axes as legend labels when none has been specified.

This is done by wrapping the configuration within a SmartConfiguration decorator. If you do not want this behaviour
you can overwrite the configuration method and build the configuration by yourself.

use Maartenpaauw\Chartscss\Configuration\Configuration;
use Maartenpaauw\Chartscss\Configuration\ConfigurationContract;

// ...

protected function configuration(): ConfigurationContract
{
    return new Configuration(
        $this->identity(),
        $this->legend(),
        $this->modifications(),
        $this->colorscheme(),
    );
}

Wrapper div

If a legend is configured the chart will be wrapped in a div. If you want to change the HTML tag you can overwrite the
tag() method.

// ...

protected function tag(): string
{
    return 'article';
}

Testing

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

Laravel News Links