Installation
composer require dgc/chart-bundle
Add to AppKernel.php:
new DGC\ChartBundle\DGCChartBundle(),
Include Dependencies
Add to your base template (base.html.twig or similar):
{% include '@DGCChart/Includes/lib_daterangepicker.html.twig' %}
{% include '@DGCChart/Includes/lib_echarts.html.twig' %}
{% include '@DGCChart/Includes/lib_morris.html.twig' %}
First Chart (SQL Example)
In a controller (e.g., TestController):
use DGC\ChartBundle\Aggregator\SqlAggregator;
public function indexAction()
{
$aggregator = $this->get('dgc_chart.factory.aggregator')->createSqlAggregator();
$query = $aggregator
->setDatabaseConnection($this->get('doctrine.dbal.default_connection'))
->select('COUNT(*) as count')
->from('your_table')
->groupBy('category_column')
->build();
$results = $query->fetchAll();
return $this->render('test/index.html.twig', [
'chartData' => $results,
]);
}
Render Chart in Twig
{{ render_chart({
'type': 'bar',
'data': chartData,
'options': {
'title': { text: 'Sample Chart' }
}
}) }}
Aggregator Factory Use dependency injection to fetch the aggregator:
$sqlAggregator = $this->get('dgc_chart.factory.aggregator')->createSqlAggregator();
$mongoAggregator = $this->get('dgc_chart.factory.aggregator')->createMongoAggregator();
Query Chaining Chain methods for SQL queries:
$query = $aggregator
->select('SUM(amount) as total')
->from('orders')
->where('created_at BETWEEN ? AND ?', [$startDate, $endDate])
->groupBy('YEAR(created_at)')
->orderBy('YEAR(created_at)')
->limit(10);
MongoDB Support For MongoDB (Doctrine ODM):
$mongoAggregator = $this->get('dgc_chart.factory.aggregator')->createMongoAggregator();
$query = $mongoAggregator
->match(['status' => 'active'])
->group(['_id' => '$category', 'count' => ['$sum' => 1]])
->build();
Dynamic Date Ranges
Integrate with daterangepicker for user-driven date ranges:
<input type="text" name="date-range" class="form-control" />
<script>
$(function() {
$('input[name="date-range"]').daterangepicker();
});
</script>
Pass selected dates to the controller and use them in queries.
Twig Extensions
Use the render_chart Twig function for consistency:
{{ render_chart({
'type': 'line',
'data': chartData,
'library': 'echarts', // or 'morris'
'options': {
'xAxis': { type: 'category' },
'yAxis': { type: 'value' }
}
}) }}
Reusable Chart Components
Create base templates for common chart types (e.g., chart_bar.html.twig):
{% extends 'base.html.twig' %}
{% block body %}
{{ render_chart({
'type': 'bar',
'data': data,
'options': {
'title': { text: title }
}
}) }}
{% endblock %}
API-Driven Charts
Fetch chart data via API endpoints (e.g., GET /api/charts/sales) and render client-side:
$.get('/api/charts/sales', function(data) {
renderChart(data, 'echarts');
});
Caching Strategies Cache query results or rendered charts:
// Cache query results for 1 hour
$results = $this->get('dgc_chart.factory.aggregator')->createSqlAggregator()
->setDatabaseConnection($this->get('doctrine.dbal.default_connection'))
->select('...')
->cache(true, 3600)
->build()
->fetchAll();
Connection Configuration
doctrine.dbal.ext_connection or doctrine.odm.mongodb.default_connection is properly configured.$aggregator->setDatabaseConnection($this->get('your_custom_connection'));
Library Dependencies
echarts, morris.js, daterangepicker). Ensure CORS and CDN availability if using self-hosted assets.Query Building Quirks
$lookup) may require manual string interpolation:
$aggregator->addStage('{$lookup: {from: "orders", localField: "_id", foreignField: "user_id", as: "orders"}}');
Twig Rendering Issues
render_chart fails, verify:
data variable is properly passed to Twig.library option matches available libraries (echarts or morris).Query Logs Enable Doctrine DBAL logging to debug SQL queries:
# config/packages/dev/doctrine.yaml
doctrine:
dbal:
logging: true
profiling: true
Aggregator Debugging Dump the raw query before execution:
$query = $aggregator->build();
dump($query->getSQL()); // For SQL
// or
dump($query->getMongoQuery()); // For MongoDB
Chart Data Validation
Validate chartData structure before rendering:
{% if chartData is iterable %}
{{ render_chart({...}) }}
{% else %}
<p>No data available.</p>
{% endif %}
Custom Chart Libraries Extend the bundle to support additional libraries (e.g., Chart.js):
render_chart_js.Query Builder Extensions Add custom methods to the aggregator:
// In a service or compiler pass
$aggregator->addMethod('customGroup', function($field) {
return $this->addRaw("GROUP BY CONCAT(YEAR({$field}), '-', MONTH({$field}))");
});
Dynamic Chart Types Use Twig macros to create dynamic chart templates:
{% macro renderDynamicChart(type, data) %}
{% if type == 'pie' %}
{{ render_chart({
'type': 'pie',
'data': data,
'library': 'echarts'
}) }}
{% elseif type == 'line' %}
{{ render_chart({
'type': 'line',
'data': data,
'library': 'morris'
}) }}
{% endif %}
{% endmacro %}
Event Listeners Hook into chart rendering events (e.g., post-render JavaScript execution):
// In a service
$eventDispatcher->addListener('dgc_chart.post_render', function($event) {
$event->addScript("console.log('Chart rendered:', $event->getChartId());");
});
Default Library
Override the default chart library in config/packages/dgc_chart.yaml:
dgc_chart:
default_library: morris # or 'echarts'
Asset Management For production, replace CDN includes with local assets:
{% block javascripts %}
{{ parent() }}
<script src="{{ asset('bundles/dgcchart/js/echarts.min.js') }}"></script>
{% end
How can I help you explore Laravel packages today?