Google Charts Overview
Architecture, singleton package loader, theme adapters, and usage conventions for Google Charts in Plotcn.
Plotcn integrates Google Charts as a first-class third visualization engine alongside Recharts and D3.js.
While Recharts excels at React-first composable dashboard charts and D3.js provides complete custom geometric control, Google Charts offers mature, time-tested charting algorithms and native choropleth geographic mapping through GeoChart.
Three-Engine Unified Architecture
Plotcn isolates visualization engines while standardizing container shells, themes, and accessibility.
Architectural Isolation
To keep Plotcn clean and maintainable, the three engines remain strictly isolated:
- No Cross-Engine Dependencies: Google Charts components never import Recharts or D3 helpers.
- Shared Presentation Layer: All engines share the Plotcn container shell, loading skeletons, error surfaces with retry buttons, theme token adapters, and accessible screen-reader summaries.
- No Monolithic Normalizer: Plotcn does not attempt to force every library into an artificial generic API. Each engine retains its natural strengths while adopting Plotcn's visual styling.
GeoChart vs. Google Maps Platform
An essential distinction in Plotcn's architecture:
- Google GeoChart: A statistical SVG choropleth visualization that is part of Google Charts. It renders country, state, and province maps shaded by data values. It does not require Google Maps Platform, an API key, or a billing account.
- Google Maps Platform: A separate interactive mapping product with street maps, raster/vector tiles, navigation routes, and 3D terrain. If Plotcn introduces interactive mapping in the future, it will be housed in a separate
Mapsfamily rather than bundled into charts.
Singleton Script Loader
Google Charts relies on an external runtime loaded from Google's content delivery network (https://www.gstatic.com/charts/loader.js).
Plotcn implements a resilient singleton loader located in @/lib/google-charts/loader.ts that guarantees:
- Single Script Injection: The script tag is injected into the DOM at most once across the entire application lifetime.
- Concurrent Request Deduplication: If five Google chart components mount simultaneously, they all await the same initialization Promise.
- On-Demand Package Loading: Only the specific package needed (such as
corechartfor line/bar charts orgeochartfor maps) is requested viagoogle.charts.load. - SSR Safety: Guards against accessing
windowordocumentduring server-side pre-rendering, rendering a stable loading skeleton during hydration. - Timeout & Error Handling: If Google's CDN is unreachable or blocked by a Content Security Policy (CSP), the loader transitions gracefully to an error state with an optional retry button.
Theming & Dark Mode
By default, Google Charts renders with white canvas backgrounds and bright default colors. Plotcn provides a theme adapter (@/lib/google-charts/theme.ts) that maps your CSS variables directly into Google Charts options:
Responsive Container
Google Charts renders SVG graphics with fixed dimensions. Plotcn wraps each chart in a GoogleChartContainer equipped with a debounced ResizeObserver:
- Watches the bounding box of the parent container.
- Automatically calls
.draw()when layout boundaries change (e.g. sidebar collapse, window resize, or grid layout shift). - Properly cleans up resize observers and chart event listeners upon unmount to prevent memory leaks.
Available Components
Plotcn currently provides the following Google Charts components:
| Component | Package | Description |
|---|---|---|
<GoogleGeoChart /> | geochart | World, country, and regional choropleth maps |
<GoogleLineChart /> | corechart | Smooth or straight Cartesian line graphs |
<GoogleBarChart /> | corechart | Horizontal bar and vertical column charts |
Installation
Add individual components directly to your project via the registry CLI:
Example: Google Line Chart
Content Security Policy (CSP)
Because Google Charts loads from an external CDN, ensure your CSP headers allow Google's script domain: