Install the Bundle
composer require 94noni/highcharts-bundle
Enable in config/bundles.php:
return [
// ...
ObHighchartsBundle::class => ['all' => true],
];
Basic Chart in Twig Create a chart object in a controller:
use Ob\HighchartsBundle\Highcharts\Highchart;
public function showChart(): Response
{
$chart = new Highchart();
$chart->chart->type = 'line';
$chart->title->text = 'Sample Chart';
$series = new \Ob\HighchartsBundle\Highcharts\Series();
$series->name = 'Data';
$series->data = [1, 2, 3, 4, 5];
$chart->series[] = $series;
return $this->render('chart.html.twig', ['chart' => $chart]);
}
Render in Twig
{{ chart.render() }}
// Controller
$chart = new Highchart();
$chart->chart->type = 'line';
$chart->title->text = 'Monthly Visits';
// Fetch data from DB (e.g., Doctrine)
$visits = $entityManager->getRepository(Visit::class)->findVisitsByMonth();
// Configure series
$series = new Series();
$series->name = 'Visits';
$series->data = $visits; // Assumes array of numeric values
$chart->series[] = $series;
return $this->render('dashboard.html.twig', ['chart' => $chart]);
chart() helper in Twig for quick rendering:
{{ chart({
'type': 'column',
'title': { 'text': 'Sales' },
'series': [{
'name': 'Product A',
'data': [10, 20, 30]
}]
}) }}
Highchart::createFromArray().$series->data = $entityManager->getRepository(Product::class)
->getSalesByMonth();
HttpClient to fetch JSON and map to chart data:
$response = $client->request('GET', 'https://api.example.com/data');
$chart->series->data = json_decode($response->getContent(), true);
Highchart for reusable templates:
class BaseChart extends Highchart {
public function __construct() {
$this->chart->type = 'line';
$this->title->text = 'Default Title';
$this->yAxis->title->text = 'Values';
}
}
{{ chart.render({
'options': {
'colors': ['#FF5733', '#33FF57'],
'plotOptions': {
'series': { 'cursor': 'pointer' }
}
}
}) }}
plotOptions:
$chart->plotOptions->series->point->events->click =
'function() { alert(this.category); }';
// Fetch data and update chart
$.get('/api/data', function(data) {
chart.series[0].setData(data);
});
PHP/JS Type Mismatches
data values. Ensure Doctrine queries return integers/floats:
// ❌ Avoid strings
$series->data = ['1', '2', '3']; // Fails silently
// ✅ Correct
$series->data = [1, 2, 3];
$query->select('CAST(value AS DECIMAL(10,2))');
Twig Auto-escaping
title or xAxis labels may break if not escaped:
// ❌ Risky (XSS)
$chart->title->text = $userInput;
// ✅ Safe
$chart->title->text = htmlspecialchars($userInput, ENT_QUOTES);
Highcharts JS Conflicts
$chart->chart->renderTo = 'chart-container-' . uniqid();
Highcharts error #13.Deprecated Methods
Highchart::set() in favor of direct property access:
// ❌ Deprecated
$chart->set('chart.type', 'line');
// ✅ Modern
$chart->chart->type = 'line';
Inspect Raw Config Dump the chart object to verify structure:
dump($chart->toArray());
Browser DevTools
Highcharts error #13 (missing dependency).Symfony Profiler
Enable ObHighchartsBundle's profiler data:
# config/packages/dev/ob_highcharts.yaml
ob_highcharts:
profiler: true
Custom Series Types
Extend Series for domain-specific logic:
class UserActivitySeries extends Series {
public function __construct(array $userActivities) {
$this->name = 'User Activity';
$this->data = array_map(fn($a) => $a->count, $userActivities);
}
}
Highcharts Plugins Load plugins via Twig:
{{ chart.render({
'options': {
'plugins': ['exporting', 'boost']
}
}) }}
{# templates/base.html.twig #}
<script src="https://code.highcharts.com/plugins/exporting.js"></script>
Symfony Messenger Integration Trigger chart updates via messages:
$bus->dispatch(new UpdateChartDataMessage($chartId, $newData));
Webpack Encore Customize Highcharts build:
// webpack.config.js
Encore
.addEntry('highcharts', './vendor/highcharts/highcharts.js')
.copyFiles({
from: './vendor/highcharts/',
to: 'build/highcharts/[path][name].[ext]'
});
Lazy Data Loading
Use series.data as a callback for large datasets:
$series->data = function() use ($repository) {
return $repository->getLargeDataset();
};
Caching Cache chart configurations (not data):
$cache = $cachePool->getItem('chart_config_' . $chartId);
if (!$cache->isHit()) {
$chart = $this->buildChart();
$cache->set($chart->toArray());
} else {
$chart = Highchart::createFromArray($cache->get());
}
Avoid Over-fetching
Use DQL to fetch only needed columns:
$query->select('p.id, p.value');
How can I help you explore Laravel packages today?