mitoteam/jpgraph
Composer wrapper for JpGraph 4.4.3 with PHP 5.5–8.5 support. Install via composer and call MtJpGraph::load() to autoload the JpGraph core and modules (bar, line, etc.), with optional Extended Mode, then use standard JpGraph classes like Graph.
Install the Package:
composer require mitoteam/jpgraph
This installs the wrapper package with JpGraph 4.4.3 (PHP 8.5-compatible).
Load the Library: In your Laravel controller, service, or blade file:
use mitoteam\jpgraph\MtJpGraph;
// Load required modules (e.g., 'bar' for bar charts)
MtJpGraph::load('bar');
Generate a Basic Chart:
$graph = new Graph(600, 400);
$graph->SetMargin(40, 30, 20, 40);
$graph->SetShadow();
$graph->SetColor('white');
// Add a title
$graph->title->Set('Sample Bar Chart');
$graph->title->SetFont(FF_FONT1, FS_BOLD);
// Create a bar plot
$bplot = new BarPlot();
$data = array(10, 20, 15, 30, 25);
$bplot->SetData($data);
$graph->Add($bplot);
// Output the chart (e.g., save to file or send as response)
$graph->Stroke('sample_chart.png');
Output the Chart in Laravel:
$path = storage_path('app/public/charts/sample_chart.png');
$graph->Stroke($path);
return response()->file($path);
<img src="{{ asset('storage/charts/sample_chart.png') }}" alt="Chart">
return response()->streamDownload(function () use ($graph) {
$graph->Stroke('php://output');
}, 'chart.png');
Generate a bar chart for monthly sales data fetched from a Laravel model:
use App\Models\Sale;
use mitoteam\jpgraph\MtJpGraph;
public function generateSalesReport()
{
MtJpGraph::load('bar');
$sales = Sale::query()
->selectRaw('MONTH(created_at) as month, SUM(amount) as total')
->groupBy('month')
->orderBy('month')
->pluck('total', 'month')
->toArray();
$graph = new Graph(800, 500);
$graph->SetMargin(50, 30, 40, 50);
$graph->title->Set('Monthly Sales Report');
$graph->xaxis->SetTickLabels(array_keys($sales));
$bplot = new BarPlot($sales);
$bplot->SetColor('orange');
$graph->Add($bplot);
$path = storage_path('app/public/reports/sales_' . now()->format('Y-m-d') . '.png');
$graph->Stroke($path);
return response()->file($path);
}
Load only the modules you need to reduce memory usage and startup time:
// For a line chart
MtJpGraph::load('line');
// For a pie chart
MtJpGraph::load('pie');
// For multiple charts in one request
MtJpGraph::load(['line', 'bar'], false); // Disable Extended Mode if not needed
Laravel Service Provider Integration:
Register the loader in AppServiceProvider to auto-load modules for specific routes:
public function boot()
{
$this->app->afterResolving('router', function ($router) {
$router->withMiddleware(function ($router) {
$router->group(['middleware' => 'jpgraph'], function () {
// Routes that require JpGraph
});
});
});
}
// Add middleware in `app/Http/Kernel.php`:
protected $middlewareGroups = [
'jpgraph' => [
\App\Http\Middleware\LoadJpGraph::class,
],
];
Use dependency injection to generate charts on-demand:
use mitoteam\jpgraph\MtJpGraph;
use JpGraph\Graph;
class ChartController extends Controller
{
public function __construct()
{
MtJpGraph::load('line'); // Load once in constructor
}
public function showTrends()
{
$data = $this->fetchTrendData();
$graph = $this->createGraph($data);
return $this->outputChart($graph);
}
protected function createGraph(array $data): Graph
{
$graph = new Graph(800, 400);
$graph->SetScale('textlin');
$graph->title->Set('Trends Over Time');
$lineplot = new LinePlot($data);
$lineplot->SetColor('blue');
$graph->Add($lineplot);
return $graph;
}
protected function outputChart(Graph $graph)
{
return response()->streamDownload(function () use ($graph) {
$graph->Stroke('php://output');
}, 'trends.png');
}
}
Create a ChartService to encapsulate logic:
namespace App\Services;
use mitoteam\jpgraph\MtJpGraph;
use JpGraph\Graph;
class ChartService
{
public function __construct()
{
MtJpGraph::load(['line', 'bar', 'pie']);
}
public function createLineChart(array $data, string $title): Graph
{
$graph = new Graph(800, 400);
$graph->title->Set($title);
$graph->SetScale('textlin');
$lineplot = new LinePlot($data);
$lineplot->SetColor('green');
$graph->Add($lineplot);
return $graph;
}
public function createPieChart(array $data, string $title): Graph
{
$graph = new PieGraph(500, 400);
$graph->title->Set($title);
$graph->pie->SetCenter(0.5, 0.5);
$pieplot = new PiePlot();
$pieplot->SetData($data);
$graph->Add($pieplot);
return $graph;
}
}
Usage in Controller:
public function showDashboard()
{
$service = app(ChartService::class);
$lineData = [10, 20, 15, 30, 25];
$pieData = ['Apples' => 40, 'Oranges' => 35, 'Bananas' => 25];
$lineGraph = $service->createLineChart($lineData, 'Monthly Sales');
$pieGraph = $service->createPieChart($pieData, 'Fruit Distribution');
// Output both charts...
}
Override default settings (e.g., fonts, cache paths) before loading:
// In AppServiceProvider::boot()
define('TTF_DIR', base_path('fonts')); // Custom font directory
define('CACHE_FILE_GROUP', 'laravel_jpgraph');
define('CACHE_FILE_PREFIX', 'jpgraph_');
MtJpGraph::load(['line', 'bar'], true); // Enable Extended Mode
Generate charts asynchronously for long-running reports:
// Dispatch a job
GenerateChartJob::dispatch($reportId, $chartType, $data);
// Job class
public function handle()
{
MtJpGraph::load($this->chartType);
$graph = $this->createChart($this->data);
$path = $this->saveChart($graph);
// Update database or notify user
Report::find($this->reportId)->update(['chart_path' => $path]);
}
Mock JpGraph in tests by patching the MtJpGraph class:
use mitoteam\jpgraph\MtJpGraph;
beforeEach(function () {
MtJpGraph::setSkipExceptionHandler(true); // Disable for tests
$this->partialMock(MtJpGraph::class, 'load');
});
it('generates a chart', function () {
$this->mocked(MtJpGraph::class)->shouldReceive('load')->once()->with('bar');
$this->get('/charts/sales')->assertOk();
});
Module Loading Order:
line requires basic). Load all required modules explicitly:
MtJpGraph::load(['basic', 'line']); // Not just 'line'
['basic', 'line'] instead of relying on implicit loading.Font Path Issues:
How can I help you explore Laravel packages today?