saad-tazi/g-chart-bundle
A PHP/Symfony bundle for integrating Google Charts into your app. Define datasets and chart options in PHP, then render interactive visualizations through Google's charting API, simplifying chart setup and reducing manual JavaScript.
Reality check first: this is a Symfony 2 bundle, not a Laravel package. There is no service provider, no facade, no config/gchart.php. If you are evaluating it from a Laravel codebase you are looking at it for the idea and possibly for the chart-config PHP classes, not for a drop-in install. Plan on either (a) porting the small chart-builder classes into app/Support/Charts, or (b) skipping it entirely and calling Google Charts from a Blade partial — which is what most people end up doing anyway.
In a Symfony 2/3 app:
composer require saad-tazi/g-chart-bundle (expect version constraints that predate PHP 7.4; you will likely need --ignore-platform-reqs or a fork).new SaadTazi\GChartBundle\SaadTaziGChartBundle() in AppKernel.php.Resources/views/ and the Twig extension class first — that is where the actual API surface lives. The bundle is thin; the chart-building classes and the Twig helper are the whole product.google.visualization.LineChart draw call. Build the data in a controller/service, hand it to the template, render the container div.In a Laravel app: read the classes, copy the data-table array shape (['cols' => [...], 'rows' => [...]]), and render it yourself in Blade with a <script> block that loads https://www.gstatic.com/charts/loader.js. That is ~40 lines and removes the dependency entirely.
DataTable literal: column descriptors (type, label, optional role) and row arrays of {v: ..., f: ...} cells. Build this in a dedicated class or a ChartData value object rather than inline in a controller — you will reuse it across line/pie/bar/geo variants.{data, options}. The bundle's own structure follows this; mirror it and you keep the option surface discoverable.JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP (important if any label is user-supplied), passes it to the view, view does new google.visualization.LineChart(el).draw(new google.visualization.DataTable(payload.data), payload.options).(elementId, chartType, payload) and centralizes google.charts.load('current', {packages: [...]}), the callback, resize handling, and error display. Do not let every view call google.charts.load — the loader is idempotent-ish but the callback coordination gets messy fast.ChartWrapper/Dashboard/ControlWrapper rather than hand-rolled event listeners. The bundle predates most of this; you will be writing it yourself.chart.googleapis.com/chart (and the Infographics API, likewise deprecated) is non-functional, not merely deprecated. Do not budget time trying to make it work — use the JS charts or a server-side renderer like QuickChart.array() syntax, no strict_types, possibly Symfony\Component\HttpKernel APIs that no longer exist. If you adopt it into a modern Symfony app, vendor a fork rather than fighting Composer's platform checks.developers.google.com/chart.vAxis.gridlines vs vAxes.0.gridlines) fail silently — the chart renders with defaults and you assume the bundle dropped your config. Debug by logging the final JSON.stringify payload and testing it in a standalone HTML file with no framework in the way.loader.js vs the old jsapi script. Only https://www.gstatic.com/charts/loader.js with google.charts.load('current', ...) is current. If the bundle emits a <script src="https://www.google.com/jsapi"> tag, that path has been deprecated for years — replace it."42" as a category and give you a bar chart of equally tall bars or a broken axis. Cast to int/float (or use {v: 42, f: "42 units"} deliberately) before serializing.new Date(...), not strings. The JSON data-table format only understands Date objects for date/datetime types, so plain json_encode of a data table with dates produces strings that render as empty series. Serialize dates as Date(2024,0,15) fragments or use google.visualization.arrayToDataTable with a JS-side conversion.formatted values are injected into the DOM by the renderer. If any of them come from user data, they need escaping before they reach the payload — JSON_HEX_* flags plus a whitelist on which fields you accept.How can I help you explore Laravel packages today?