laraveldaily/laravel-charts

Create charts and reports from Laravel

0.2.3 2023-06-28 10:36 UTC

README

Package to generate Chart.js charts directly from Laravel/Blade, without interacting with JavaScript.

Simple Usage

Laravel Charts - Users by Months

If you want to generate a chart above, grouping users records by the month of created_at value, here's the code.

Controller:

use LaravelDaily\LaravelCharts\Classes\LaravelChart;

// ...

$chart_options = [
    'chart_title' => 'Users by months',
    'report_type' => 'group_by_date',
    'model' => 'App\Models\User',
    'group_by_field' => 'created_at',
    'group_by_period' => 'month',
    'chart_type' => 'bar',
];
$chart1 = new LaravelChart($chart_options);

return view('home', compact('chart1'));

View File

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Dashboard</div>

                <div class="card-body">

                    <h1>{{ $chart1->options['chart_title'] }}</h1>
                    {!! $chart1->renderHtml() !!}

                </div>

            </div>
        </div>
    </div>
</div>
@endsection

@section('javascript')
{!! $chart1->renderChartJsLibrary() !!}
{!! $chart1->renderJs() !!}
@endsection

Installation

composer require laraveldaily/laravel-charts

No additional configuration or other parameters yet.

Usage

You need to create LaravelChart object in your Controller, passing array of options.

$chart = new LaravelChart($options);

Then pass it to the View, as a variable:

return view('dashboard', compact('chart'));

Available Reports and Options

Currently package support three types of charts/reports:

  • group_by_date - amount of records from the same table, grouped by time period - day/week/month/year;
  • group_by_string - amount of records from the same table, grouped by any string field, like name;
  • group_by_relationship - amount of records from the same table, grouped by belongsTo relationship's field

NOTE: From Laravel 8, all its models are placed in a folder called Models (App\Models)

Example with all options

$chart_options = [
    'chart_title' => 'Transactions by dates',
    'chart_type' => 'line',
    'report_type' => 'group_by_date',
    'model' => 'App\Models\Transaction',
    'conditions'            => [
        ['name' => 'Food', 'condition' => 'category_id = 1', 'color' => 'black', 'fill' => true],
        ['name' => 'Transport', 'condition' => 'category_id = 2', 'color' => 'blue', 'fill' => true],
    ],

    'group_by_field' => 'transaction_date',
    'group_by_period' => 'day',

    'aggregate_function' => 'sum',
    'aggregate_field' => 'amount',
    'aggregate_transform' => function($value) {
        return round($value / 100, 2);
    },
    
    'filter_field' => 'transaction_date',
    'filter_days' => 30, // show only transactions for last 30 days
    'filter_period' => 'week', // show only transactions for this week
    'continuous_time' => true, // show continuous timeline including dates without data
];
  • chart_title (required) - just a text title that will be shown as legend;
  • chart_type (required) - possible values: "line", "bar", "pie";
  • report_type (required) - see above, can be group_by_date, group_by_string or group_by_relationship;
  • model (required) - name of Eloquent model, where to take the data from;
  • name (optional) - just a text title that will be shown as title, otherwise the legend is used;
  • conditions (optional, only for line chart type) - array of conditions (name + raw condition + color) for multiple datasets;
  • group_by_field (required) - name of database field that will be used in group_by clause;
  • group_by_period (optional, only for group_by_date report type) - possible values are "day", "week", "month", "year";
  • relationship_name (optional, only for group_by_relationship report type) - the name of model's method that contains belongsTo relationship.
  • aggregate_function (optional) - you can view not only amount of records, but also their SUM() or AVG(). Possible values: "count" (default), "avg", "sum".
  • aggregate_field (optional) - see aggregate_function above, the name of the field to use in SUM() or AVG() functions. Irrelevant for COUNT().
  • aggregate_transform (optional) - callback function for additional transformation of aggregate number
  • filter_field (optional) - show only data filtered by that datetime field (see below)
  • filter_days (optional) - see filter_field above - show only last filter_days days of that field. Example, last 30 days by created_at field.
  • filter_period (optional) - another way to filter by field, show only record from last week / month / year. Possible values are "week", "month", "year".
  • continuous_time (optional) - show all dates on chart, including dates without data.
  • show_blank_data (optional) - show date even if the data is blank based on filter_days.
  • range_date_start (optional) - show data in from a date range by filter_field, this is the start date.
  • range_date_end (optional) - show data in from a date range by filter_field, this is the end date.
  • field_distinct (optional) - field name required, it will apply a distinct(fieldname)
  • style_class (optional) - add class css in canvas
  • date_format (optional) - add the date format, by default: American format Y-m-d
  • where_raw (optional) - Condition in multiple consultation situations
  • chart_height (optional) - add the height in options, default 300px
  • date_format_filter_days (optional) - add the date format for Filter days
  • withoutGlobalScopes (optional) - removes global scope restriction from queried model
  • with_trashed (optional) - includes soft deleted models
  • only_trashed (optional) - only displays soft deleted models
  • top_results (optional, integer) - limit number of results shown, see Issue #49
  • chart_color (optional, value in rgba, like "0,255,255") - defines the color of the chart
  • labels (optional, array with key and value) - defines key value array mapping old and new values
  • hidden (optional, boolean) hides the current dataset. Useful when having multiple datasets in one chart
  • stacked (optional, boolean, only for bar chart) stacks the chart data when dates or strings match instead of showing it next to eachother

Example with relationship

$chart_options = [
    'chart_title' => 'Transactions by user',
    'chart_type' => 'line',
    'report_type' => 'group_by_relationship',
    'model' => 'App\Models\Transaction',

    'relationship_name' => 'user', // represents function user() on Transaction model
    'group_by_field' => 'name', // users.name

    'aggregate_function' => 'sum',
    'aggregate_field' => 'amount',
    
    'filter_field' => 'transaction_date',
    'filter_days' => 30, // show only transactions for last 30 days
    'filter_period' => 'week', // show only transactions for this week
];

Rendering Charts in Blade

After you passed $chart variable, into Blade, you can render it, by doing three actions:

Action 1. Render HTML.

Wherever in your Blade, call this:

{!! $chart1->renderHtml() !!}

It will generate something like this:

<canvas id="myChart"></canvas>

Action 2. Render JavaScript Library

Package is using Chart.js library, so we need to initialize it somewhere in scripts section:

{!! $chart1->renderChartJsLibrary() !!}

It will generate something like this:

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>

Action 3. Render JavaScript of Specific Chart

After Chart.js is loaded, launch this:

{!! $chart1->renderJs() !!}

Using Multiple Charts

You can show multiple charts on the same page, initialize them separately.

Controller:

public function index()
{
    $chart_options = [
        'chart_title' => 'Users by months',
        'report_type' => 'group_by_date',
        'model' => 'App\Models\User',
        'group_by_field' => 'created_at',
        'group_by_period' => 'month',
        'chart_type' => 'bar',
        'filter_field' => 'created_at',
        'filter_days' => 30, // show only last 30 days
    ];

    $chart1 = new LaravelChart($chart_options);


    $chart_options = [
        'chart_title' => 'Users by names',
        'report_type' => 'group_by_string',
        'model' => 'App\Models\User',
        'group_by_field' => 'name',
        'chart_type' => 'pie',
        'filter_field' => 'created_at',
        'filter_period' => 'month', // show users only registered this month
    ];

    $chart2 = new LaravelChart($chart_options);

    $chart_options = [
        'chart_title' => 'Transactions by dates',
        'report_type' => 'group_by_date',
        'model' => 'App\Models\Transaction',
        'group_by_field' => 'transaction_date',
        'group_by_period' => 'day',
        'aggregate_function' => 'sum',
        'aggregate_field' => 'amount',
        'chart_type' => 'line',
    ];

    $chart3 = new LaravelChart($chart_options);

    return view('home', compact('chart1', 'chart2', 'chart3'));
}

View:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">Dashboard</div>

                <div class="card-body">

                    <h1>{{ $chart1->options['chart_title'] }}</h1>
                    {!! $chart1->renderHtml() !!}

                <hr />

                    <h1>{{ $chart2->options['chart_title'] }}</h1>
                    {!! $chart2->renderHtml() !!}

                    <hr />

                    <h1>{{ $chart3->options['chart_title'] }}</h1>
                    {!! $chart3->renderHtml() !!}

                </div>

            </div>
        </div>
    </div>
</div>
@endsection

@section('javascript')
{!! $chart1->renderChartJsLibrary() !!}

{!! $chart1->renderJs() !!}
{!! $chart2->renderJs() !!}
{!! $chart3->renderJs() !!}
@endsection

Laravel Charts - Users by Months

Laravel Charts - Users by Names

Laravel Charts - Transactions by Dates

Multiple Datasets

This is a new feature from v0.1.27. You can provide multiple arrays of settings to the LaravelChart constructor, and they will be drawn on the same chart.

$settings1 = [
    'chart_title'           => 'Users',
    'chart_type'            => 'line',
    'report_type'           => 'group_by_date',
    'model'                 => 'App\Models\User',
    'group_by_field'        => 'created_at',
    'group_by_period'       => 'day',
    'aggregate_function'    => 'count',
    'filter_field'          => 'created_at',
    'filter_days'           => '30',
    'group_by_field_format' => 'Y-m-d H:i:s',
    'column_class'          => 'col-md-12',
    'entries_number'        => '5',
    'translation_key'       => 'user',
    'continuous_time'       => true,
];
$settings2 = [
    'chart_title'           => 'Projects',
    'chart_type'            => 'line',
    'report_type'           => 'group_by_date',
    'model'                 => 'App\Models\Project',
    // ... other values identical to $settings1
];

$chart1 = new LaravelChart($settings1, $settings2);

Multiple Datasets

License

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

More from our LaravelDaily Team