consoletvs/charts
ConsoleTVs Charts is a Laravel/PHP package for building interactive charts from your data. Generate chart objects with a clean API, integrate with popular JS libraries, and render responsive visualizations in Blade views for dashboards, reports, and admin panels.
## Getting Started
### Minimal Setup
1. **Installation**
```bash
composer require consoletvs/charts
Publish the config file (if needed):
php artisan vendor:publish --provider="ConsoleTVs\Charts\ChartsServiceProvider"
First Chart in Blade
{!! Charts::create('users-chart', 'line')
->title('User Growth')
->elementLabel('Users')
->colors(['#4CAF50'])
->dataset('Users', [10, 20, 30, 40])
->responsive(true)
!!}
Quick Eloquent Integration
$users = User::selectRaw('count(*) as count, created_at')
->whereYear('created_at', now()->year)
->groupBy('month(created_at)')
->get();
{!! Charts::create('monthly-users', 'line')
->title('Monthly Users')
->elementLabel('Users')
->dataset('Users', $users->pluck('count')->toArray())
->labels($users->pluck('created_at')->toArray())
->responsive(true)
!!}
config/charts.php (for default settings like chart engines, paths, etc.)chartjs, highcharts) in config/charts.php under engines.// Grouped bar chart from Eloquent
$orders = Order::selectRaw('status, count(*) as total')
->groupBy('status')
->get();
{!! Charts::create('order-status', 'bar')
->title('Order Status Distribution')
->elementLabel('Orders')
->dataset('Status', $orders->pluck('total')->toArray())
->labels($orders->pluck('status')->toArray())
->colors(['#FF5733', '#33FF57', '#3357FF'])
->responsive(true)
!!}
$revenue = collect([
['month' => 'Jan', 'amount' => 1000],
['month' => 'Feb', 'amount' => 1500],
]);
{!! Charts::create('revenue-trend', 'line')
->title('Monthly Revenue')
->elementLabel('USD')
->dataset('Revenue', $revenue->pluck('amount')->toArray())
->labels($revenue->pluck('month')->toArray())
->options(['responsive' => true, 'maintainAspectRatio' => false])
!!}
$users = User::selectRaw('count(*) as users, gender')
->groupBy('gender')
->get();
$admins = Admin::selectRaw('count(*) as admins, gender')
->groupBy('gender')
->get();
{!! Charts::create('gender-distribution', 'pie')
->title('Gender Breakdown')
->type('doughnut')
->dataset('Users', $users->pluck('users')->toArray())
->dataset('Admins', $admins->pluck('admins')->toArray())
->labels(['Male', 'Female', 'Other'])
->colors(['#FF6384', '#36A2EB', '#FFCE56'])
!!}
{!! Charts::create('sales-overview', 'line')
->title('Sales Overview')
->options([
'responsive' => true,
'plugins' => [
'legend' => ['position' => 'top'],
'tooltip' => ['mode' => 'index'],
],
'scales' => [
'y' => ['beginAtZero' => false],
],
])
!!}
Create a Blade component (resources/views/components/chart.blade.php):
@props(['chartId', 'type', 'title', 'data'])
{!! Charts::create($chartId, $type)
->title($title)
->elementLabel('Value')
->dataset('Data', $data['values'])
->labels($data['labels'] ?? [])
->options($data['options'] ?? [])
->responsive(true)
!!}
Usage:
<x-chart
chartId="revenue-chart"
type="line"
title="Revenue Trend"
:data="[
'values' => [100, 200, 300],
'labels' => ['Q1', 'Q2', 'Q3'],
]"
/>
Use @chart directive for cleaner Blade syntax:
@chart('users-chart', 'line')
->title('User Growth')
->dataset('Users', [10, 20, 30])
@endchart
Return charts directly from API routes (e.g., for SPAs):
return response()->json([
'chart' => Charts::create('api-chart', 'bar')
->dataset('Data', [1, 2, 3])
->getData(),
]);
Cache chart data or rendered HTML for performance:
// Cache the chart data for 1 hour
$chartData = Cache::remember('chart-users', 3600, function () {
return Charts::create('cached-chart', 'line')
->dataset('Users', User::count())
->getData();
});
Mock chart data in tests:
$mockChart = Mockery::mock('overload', Charts::class);
$mockChart->shouldReceive('create')
->andReturnSelf();
$mockChart->shouldReceive('getData')
->andReturn(['data' => 'mocked']);
chartjs) doesn’t match the expected output.default engine in config/charts.php and ensure the driver is installed (e.g., npm install chart.js for chartjs).labels() and dataset lengths don’t match.->labels() and dataset arrays are the same length.// Wrong: Labels and data lengths differ
->labels(['Jan', 'Feb']) // 2 items
->dataset('Sales', [100, 200, 300]) // 3 items
// Correct: Matching lengths
->labels(['Jan', 'Feb', 'Mar'])
->dataset('Sales', [100, 200, 300])
->responsive(true) and ensure the container has a defined height (e.g., style="height: 400px").selectRaw queries might return unexpected data types (e.g., Carbon objects in labels).->labels($users->pluck('created_at')->map(fn($date) => $date->format('Y-m'))->toArray())
'engines' => [
'chartjs' => [
'path' => resource_path('js/chart.js'),
// Custom options
],
],
Use ->getData() to debug the chart configuration before rendering:
$chart = Charts::create('debug-chart', 'line')
->dataset('Data', [1, 2, 3]);
dd($chart->getData()); // Inspect the raw config
View the source of the rendered chart to verify scripts and styles are loaded:
<!-- Look for these in the output -->
<script src="/vendor/chartjs/chart.min.js"></script>
<canvas id="users-chart" ...></canvas>
How can I help you explore Laravel packages today?