Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Highcharts Bundle Laravel Package

laurentmuller/highcharts-bundle

Laravel bundle for Highcharts: build interactive JavaScript charts from PHP with a fluent, chainable API. Define chart options, series, axes, and styling in Laravel controllers or views, then render responsive Highcharts visualizations without writing raw JavaScript.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Symfony bundle, so the honest first step for a Laravel developer is deciding whether you're porting it or replacing it. If you want to evaluate it anyway:

  1. composer require laurentmuller/highcharts-bundle — expect it to pull in ghunti/highcharts-php (the actual chart-building library) and Symfony components. In a Laravel app you'll get the library but not the auto-wiring, Twig extension, or config tree.
  2. Read, in this order:
    • The bundle's DependencyInjection/ and Resources/config/services.* — this is the only place that shows what services exist (highcharts factory, chart renderer).
    • The highcharts factory class: it exposes newChart(), newStockChart(), newGaugeChart(), etc., returning a Ghunti\HighchartsPHP\Highchart instance.
    • The upstream ghunti/highcharts-php README for the option/series API — that's where the real usage lives.
  3. Add Highcharts JS yourself (npm highcharts + highcharts-vue/manual init, or CDN). The bundle does not ship assets; it only emits configuration and an init script.
  4. First use case: a controller action that builds a column chart and hands it to a Blade view.
// app/Http/Controllers/DashboardController.php
public function index(Highchart $chart) // bind the factory in a provider
{
    $chart->setTitle(['text' => 'Revenue by month']);
    $chart->xAxis->categories = ['Jan', 'Feb', 'Mar'];
    $chart->addSeries(['name' => '2024', 'data' => [12, 19, 8]]);

    return view('dashboard', ['chartScript' => $chart->render()]);
}
{{-- resources/views/dashboard.blade.php --}}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="revenue"></div>
{!! $chartScript !!}

Implementation Patterns

Wrap the factory in a service provider. Laravel won't load the Symfony bundle, so register the pieces you need manually:

// app/Providers/HighchartsServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Ghunti\HighchartsPHP\Highchart::class, fn () => new \Ghunti\HighchartsPHP\Highchart());
}

If you want to keep the bundle's highcharts factory behavior, copy its ~20 lines of factory into a HighchartsFactory class rather than fighting the container.

Prefer the JSON/API pattern over server-rendered scripts. The most Laravel-idiomatic use is a dedicated endpoint returning option arrays, with the chart built client-side. This keeps {!! !!} escaping out of your views, survives Livewire/Inertia, and lets you cache chart data independently:

public function revenue(): JsonResponse
{
    return response()->json([
        'title' => ['text' => 'Revenue by month'],
        'xAxis' => ['categories' => ['Jan', 'Feb', 'Mar']],
        'series' => [['name' => '2024', 'type' => 'column', 'data' => [12, 19, 8]]],
    ]);
}
fetch('/api/reports/revenue')
  .then(r => r.json())
  .then(opts => Highcharts.chart('revenue', opts));

Blade component for the container + init. Encapsulate the <div id> and script tag so pages don't diverge:

{{-- resources/views/components/chart.blade.php --}}
@props(['id', 'options'])
<div id="{{ $id }}"></div>
@push('scripts')
<script>Highcharts.chart(@json($id), {{ Illuminate\Support\Js::from($options) }});</script>
@endpush

Theme/config presets. The bundle's Symfony config YAML (global Chart defaults, global credits, lang) has no Laravel equivalent. Translate those keys into a config/highcharts.php file and merge with array_replace_recursive at render time — this gives you a per-environment default and is the one bundle concept worth keeping.

Testing. Assert on the option array / JSON, never on the rendered HTML string. The generated script tag is brittle and changes with Highcharts minor versions.

Gotchas and Tips

  • It will not "just work" in Laravel. No bundle auto-discovery, no Twig extension, no highcharts_render_chart() Blade function. Every one of those is a manual port. Budget a half-day for the first chart and treat the bundle as a reference implementation, not a dependency.
  • Zero stars, zero dependents, score 0.03. This is effectively a personal project. There are no security advisories, no downstream users to surface breakage, and no maintenance guarantee. Pin the version with composer.lock and have an exit plan (the option arrays are portable — dropping the dependency later is mostly copy-paste).
  • PHP version constraints. Symfony bundles of this vintage often cap at PHP 7.x/8.0–8.1. Check composer.json require before you try installing on 8.3; you may need --ignore-platform-reqs, which is a smell.
  • Escaping. render() returns a <script> block. In Blade you must use {!! !!}. Prefer Illuminate\Support\Js::from() for any user-influenced values, and never let request data reach setTitle() unescaped.
  • JS callbacks can't be JSON-encoded. Things like tooltip.formatter, plotOptions.series.point.events.click, and xAxis.labels.formatter need raw JS functions. The upstream library has quirks here (__raw__-style markers or string functions); if you use @json/Js::from you'll get "function () {...}" as a string and the chart renders without the callback. Use Js::from() only for values, and hand-place function blocks in Blade.
  • Highcharts JS version drift. The library targets older Highcharts (v5–v7 era). Modern Highcharts 11/12 changed module paths (highcharts/modules/exporting vs exporting.src), Highcharts.chart() is fine but Highcharts.stockChart/Gantt need explicit module imports, and credits display rules changed. If you're on v11+, assume the bundle's output needs adjustments.
  • Debugging: dump the option array, not the HTML. dd(json_encode($chart->getOptions(), JSON_PRETTY_PRINT)) (or the equivalent accessor) tells you instantly whether a blank chart is a server-side options bug or a client-side load-order bug. Blank chart + no console error almost always means Highcharts JS loaded after your init script.
  • Extension points worth keeping: the factory methods (newStockChart, newGaugeChart) are thin and easy to replicate; the series/options passthrough is the actually valuable part. Skip the Symfony config tree, Twig extension, and asset assumptions entirely.
  • Consider the alternatives before committing. For a Laravel app, ConsoleTVs/Charts (though stale), Livewire chart components, or just the raw option-array + Highcharts.chart() pattern above are lower-risk and give you full control over Highcharts version and callback handling.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections