Overview
PDFGraphs is a single-class PHP extension that subclasses FPDF from fpdf.org and adds two layers of functionality:
- Nine high-level chart methods for producing publication-quality bar, line, pie, area, and scatter charts directly inside a PDF.
- Shape primitives and graphics-state utilities that FPDF lacks natively — polygons, filled pie sectors, ellipses, rounded rectangles, rotation, transparency, and gradients — adapted from the well-known fpdf.org community scripts (rotation/script 2, transparency/script 86, gradient/script 41, rounded rect/script 35) and rolled into a single file.
Everything is opt-in via per-call options arrays. Default styling produces a clean, modern aesthetic; six built-in palettes cover the common color directions; and every chart accepts position and dimensions so you can lay out dashboards by hand.
Installation
Drop the two files alongside each other and require the extension. PDFGraphs needs only stock FPDF — no community scripts to install separately.
<?php
require('pdf_graphs.php'); // this extension
$pdf = new PDFGraphs('P', 'mm', 'A4');
$pdf->AddPage();
// ... draw charts ...
$pdf->Output('F', 'report.pdf');
Quick start
Every chart takes the same six positional arguments — data, labels, x, y, width, height — and an optional options array. Coordinates are in whatever unit you passed to the constructor (millimeters by default).
$pdf = new PDFGraphs();
$pdf->AddPage();
$pdf->BarChart(
array(23, 45, 56, 78, 32),
array('Jan', 'Feb', 'Mar', 'Apr', 'May'),
10, 20, 190, 100,
array(
'title' => 'Monthly Sales',
'gradient' => true,
)
);
$pdf->Output('F', 'sales.pdf');
That's the whole pattern. Every chart works this way. The options array is always optional; the chart defaults produce a clean result.
Color palettes
Six built-in palettes ship with the class. Switch with SetPalette($name) — affects every subsequent chart on the document until changed again. Pass a custom array of [R, G, B] triplets for full control.
SetPalette($nameOrList)
$pdf->SetPalette('ocean');
// or a custom palette:
$pdf->SetPalette(array(
array(99, 102, 241),
array(236, 72, 153),
array(245, 158, 11),
));
Charts
BarChart ($data, $labels, $x, $y, $w, $h, $options = array())
Vertical bar chart with one bar per data point. Supports rounded bar tops via RoundedRect, top-to-bottom gradient fills, and rotated x-axis labels for crowded categories.
Options
| Key | Type / default | Description |
|---|---|---|
title | string null | Centered title above the plot area. |
showValues | bool true | Show numeric value label above each bar. |
showGrid | bool true | Draw horizontal grid lines with y-axis tick labels. |
singleColor | bool true | All bars share palette color 0. Set false to cycle through the palette. |
rounded | bool true | Round the top corners of each bar. |
gradient | bool false | Vertical gradient fill, light at top → full color at bottom. |
rotateLabels | int 0 | Rotate x-axis labels by N degrees. Try 30 or 45 for crowded categories. |
Example
$pdf->BarChart(
array(23, 45, 56, 78, 32, 41, 67),
array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'),
10, 20, 190, 90,
array(
'title' => 'Daily Active Users',
'gradient' => true,
'rotateLabels' => 30,
)
);
HorizontalBarChart (...)
Bars run left-to-right with the category label to the left of each bar and the value to the right. Best when you have long category names or more than 8 categories. Each bar uses a different palette color.
Options
| Key | Type / default | Description |
|---|---|---|
title | string null | Centered title. |
showValues | bool true | Show value at the end of each bar. |
showGrid | bool true | Vertical grid lines with x-axis tick labels. |
gradient | bool false | Left-to-right gradient fill, lighter on the left edge. |
Example
$pdf->SetPalette('ocean');
$pdf->HorizontalBarChart(
array(120, 95, 78, 64, 50, 38),
array('Search', 'Direct', 'Social', 'Email', 'Referral', 'Other'),
10, 20, 190, 90,
array('title' => 'Traffic Sources', 'gradient' => true)
);
GroupedBarChart (...)
Multiple series displayed side-by-side within each category group. Pass $series as an array of arrays — one inner array per series, each the same length as $groupLabels.
Options
| Key | Type / default | Description |
|---|---|---|
title | string null | Centered title. |
showGrid | bool true | Horizontal grid lines. |
legend | bool true | Show series legend below the chart. |
gradient | bool false | Vertical gradient fill on each bar. |
Example
$pdf->GroupedBarChart(
array(
array(30, 50, 45, 60), // Q1 series
array(25, 40, 55, 48), // Q2 series
array(15, 30, 35, 42), // Q3 series
),
array('Q1', 'Q2', 'Q3'), // series labels
array('2023', '2024', '2025', '2026'), // group labels (x-axis)
10, 20, 190, 100,
array('title' => 'Quarterly Revenue', 'gradient' => true)
);
StackedBarChart (...)
Same data shape as GroupedBarChart but series stack vertically within each category. Useful when you care about the total and the composition.
Options are identical to GroupedBarChart: title, showGrid, legend, gradient.
Example
$pdf->StackedBarChart(
array(
array(20, 30, 25, 35),
array(15, 25, 30, 20),
array(10, 15, 20, 25),
),
array('Product A', 'Product B', 'Product C'),
array('Q1', 'Q2', 'Q3', 'Q4'),
10, 20, 190, 100,
array('title' => 'Revenue Mix')
);
LineChart (...)
One or more line series. Pass a single flat array for one series, or an array of arrays for multiple series. With smoothFill the area under each line is filled with an alpha-blended version of the series color, giving an Apple-style "translucent layers" look.
Options
| Key | Type / default | Description |
|---|---|---|
title | string null | Centered title. |
showGrid | bool true | Horizontal grid lines. |
showMarkers | bool true | Draw a small circle at each data point. |
legend | bool true | Show series legend (only renders with 2+ series). |
smoothFill | bool false | Fill area under each line with an alpha-blended series color. |
fillAlpha | float 0.35 | Opacity of area fill (0–1). Only used with smoothFill. |
Example
$pdf->LineChart(
array(
array(12, 19, 15, 25, 22, 30, 28, 35, 32, 40),
array( 8, 15, 18, 20, 25, 22, 28, 30, 35, 38),
),
array('Revenue', 'Costs'),
array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct'),
10, 20, 190, 90,
array('title' => 'Revenue vs Costs', 'smoothFill' => true)
);
AreaChart (...)
Convenience wrapper around LineChart with smoothFill = true and showMarkers = false. Use it when you want the area visualization explicitly without remembering the line-chart options.
Options
| Key | Type / default | Description |
|---|---|---|
title | string null | Centered title. |
showGrid | bool true | Horizontal grid lines. |
legend | bool true | Show legend for multi-series. |
fillAlpha | float 0.35 | Opacity of the filled area. |
Example
$pdf->AreaChart(
array(array(10, 18, 14, 22, 28, 35, 42)),
array('Active Users'),
array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'),
10, 20, 190, 90,
array('title' => 'User Growth')
);
PieChart (...)
Classic pie chart with auto-computed percentages, an optional center hole (donut mode), and an optional concentric-arc gradient overlay for a soft "spotlight" look. Sectors start at 12 o'clock and proceed clockwise.
Options
| Key | Type / default | Description |
|---|---|---|
title | string null | Centered title above the chart. |
legend | bool true | Vertical legend to the right of the pie. |
showPercent | bool true | Draw white percentage labels on sectors larger than 4%. |
donut | bool false | Cut a circular hole in the center to make a donut. |
donutRatio | float 0.55 | Inner-hole radius as a fraction of the outer radius. |
gradient | bool false | Radial gradient per sector: lighter center, fuller color at the rim. |
Example
$pdf->PieChart(
array(35, 25, 20, 12, 8),
array('Mobile', 'Desktop', 'Tablet', 'TV', 'Other'),
10, 20, 120, 100,
array('title' => 'Device Share', 'gradient' => true)
);
DonutChart (...)
Convenience wrapper that calls PieChart with donut = true. Identical option set except donut is forced on.
Example
$pdf->SetPalette('sunset');
$pdf->DonutChart(
array(40, 30, 20, 10),
array('Free', 'Pro', 'Team', 'Enterprise'),
10, 20, 120, 100,
array('title' => 'Subscription Tiers', 'gradient' => true)
);
ScatterPlot (...)
Multi-series scatter plot. Each series is a list of [x, y] coordinate pairs. Different series automatically get different marker shapes (circle, square, diamond) in addition to different colors.
Options
| Key | Type / default | Description |
|---|---|---|
title | string null | Centered title. |
showGrid | bool true | Horizontal grid lines with y tick labels; x labels along the bottom. |
legend | bool true | Show legend below the chart for multi-series plots. |
xLabel | string null | Caption below the x-axis. |
alpha | float 0.75 | Marker opacity. Useful for dense overlapping point clouds. |
Example
$pdf->ScatterPlot(
array(
array(array(1,2), array(2,4), array(3,3), array(4,6)),
array(array(1.5,1), array(2.5,3), array(3.5,5)),
),
array('Group A', 'Group B'),
10, 20, 190, 100,
array('title' => 'Correlation', 'xLabel' => 'Input')
);
Shape primitives
FPDF ships with Line, Rect, and not much else. PDFGraphs adds the path operators commonly needed for charts and infographics, all built on the raw PDF cubic-Bezier (c) operator so they're identical in quality to Acrobat's own output.
Polygon ($points, $style = 'D')
Draws a closed polygon. Accepts either a flat array [x1, y1, x2, y2, ...] or a nested array [[x1,y1], [x2,y2], ...]. Style is 'D' (default stroke), 'F' (fill), or 'FD'/'DF' (both).
$pdf->SetFillColor(59, 130, 246);
$pdf->Polygon(array(10, 10, 50, 10, 30, 45), 'F');
SolidArc ($cx, $cy, $rx, $ry, $startDeg, $endDeg, $style = 'F')
A filled pie sector — center, radii (use the same for a circle), and start/end angles in degrees measured clockwise from 12 o'clock. The arc is approximated by ≤90° cubic Bezier segments using the standard k = (4/3) tan(sweep/4) formula, giving sub-0.03% radius error.
$pdf->SetFillColor(34, 197, 94);
$pdf->SolidArc(100, 50, 30, 30, 0, 120, 'F');
// A 120° sector starting at 12 o'clock
Arc ($cx, $cy, $rx, $ry, $startDeg, $endDeg)
Open (stroked) arc — same parameters as SolidArc but draws only the curve, not the radii or fill.
Ellipse / Circle
Center-based ellipse and circle. Ellipse takes radii; Circle takes a single radius. Style follows the usual 'D' / 'F' / 'FD' convention.
$pdf->SetFillColor(236, 72, 153);
$pdf->Circle(50, 50, 20, 'F');
$pdf->Ellipse(100, 50, 30, 15, 'FD');
Rect (which takes top-left), Ellipse and Circle use the center as the anchor point. This matches the fpdf.org script6 convention and reads more naturally for chart code.RoundedRect ($x, $y, $w, $h, $r, $style, $corners)
Rectangle with rounded corners. The $corners string controls which corners are rounded — any subset of '1234': 1=top-left, 2=top-right, 3=bottom-right, 4=bottom-left.
// All four corners rounded
$pdf->RoundedRect(20, 20, 40, 25, 4, 'F');
// Tab-like shape: only top corners
$pdf->RoundedRect(70, 20, 40, 25, 4, 'F', '12');
// Speech-bubble diagonal: top-left and bottom-right
$pdf->RoundedRect(120, 20, 40, 25, 4, 'FD', '13');
Graphics state
Rotate / RotatedText
Rotates subsequent drawing operations around a given point. Call Rotate(0) to clear. RotatedText is a one-shot wrapper that rotates, places text, and unrotates in a single call.
// Vertical y-axis label
$pdf->SetFont('Helvetica', 'B', 10);
$pdf->RotatedText(15, 150, 'Revenue ($M)', 90);
// Or rotate a whole drawing block manually
$pdf->Rotate(15, 100, 100);
$pdf->Rect(80, 80, 40, 40, 'F');
$pdf->Rotate(0);
SetAlpha ($alpha, $bm = 'Normal')
Sets the alpha (transparency) for subsequent fill and stroke operations. $alpha ranges 0 (fully transparent) to 1 (fully opaque). The optional $bm is a PDF blend mode name: Normal, Multiply, Screen, Overlay, Darken, Lighten, etc.
$pdf->SetAlpha(0.4);
$pdf->SetFillColor(59, 130, 246);
$pdf->Rect(20, 20, 50, 50, 'F');
$pdf->SetFillColor(239, 68, 68);
$pdf->Rect(50, 35, 50, 50, 'F');
$pdf->SetAlpha(1.0); // reset
SetAlpha requires PDF 1.4+. PDFGraphs automatically bumps the document version when SetAlpha or gradients are used — you don't need to set it manually.LinearGradient / RadialGradient
Fill a rectangle with a smooth gradient. The chart methods call these internally when gradient => true is set — but you can call them directly for buttons, headers, decorative panels, anything.
// Header bar with vertical gradient
$pdf->LinearGradient(0, 0, 210, 25,
array(59, 130, 246), // top color (lighter)
array(37, 99, 235)); // bottom color
Colors are [R, G, B] arrays with each component 0–255. The optional $coords parameter sets a custom gradient axis in PDF user space; omit it and PDFGraphs picks a sensible default (vertical for LinearGradient, center-out for RadialGradient).
Theme customization
Six public properties on each instance control chart styling. Override them right after construction — they apply to every chart drawn afterward.
| Property | Default | Used for |
|---|---|---|
BG_COLOR | (255, 255, 255) | Donut center hole fill — set to your page background. |
GRID_COLOR | (235, 237, 240) | Grid lines on bar, line, scatter charts. |
AXIS_COLOR | (156, 163, 175) | x-axis baseline. |
TEXT_COLOR | (75, 85, 99) | Value labels on bars and points. |
TITLE_COLOR | (17, 24, 39) | Chart titles. |
LABEL_COLOR | (107, 114, 128) | Axis tick labels and category names. |
Example — dark theme
$pdf = new PDFGraphs();
$pdf->BG_COLOR = array(15, 23, 42);
$pdf->GRID_COLOR = array(51, 65, 85);
$pdf->AXIS_COLOR = array(100, 116, 139);
$pdf->TEXT_COLOR = array(226, 232, 240);
$pdf->TITLE_COLOR = array(241, 245, 249);
$pdf->LABEL_COLOR = array(148, 163, 184);
$pdf->SetPalette('modern');
$pdf->AddPage();
// Fill background dark first
$pdf->SetFillColor(15, 23, 42);
$pdf->Rect(0, 0, 210, 297, 'F');
$pdf->BarChart(/* ... */);
Acrobat compatibility
Gradient fills are implemented via stacked rectangles (for bars) and concentric pie sectors (for pies), not PDF native shading patterns. This is a deliberate choice.
The visual result is essentially indistinguishable from a true shading at normal viewing distances. Each bar uses 28 strips; each pie sector uses 14 concentric arcs. File size impact is roughly 1KB per gradient bar after compression — typically less than a single small JPEG image.
LinearGradient and RadialGradient remain available as public methods and use the same multi-strip approach internally, so anything you build on top of them will be Acrobat-safe by default.
Full example
A two-page sales report showcasing several chart types:
<?php
require('fpdf.php');
require('pdf_graphs.php');
$pdf = new PDFGraphs('P', 'mm', 'A4');
$pdf->SetAutoPageBreak(false);
// --- Page 1: KPIs --------------------------------------------
$pdf->AddPage();
$pdf->SetFont('Helvetica', 'B', 18);
$pdf->Text(10, 15, 'Q4 Sales Report');
$pdf->BarChart(
array(23, 45, 56, 78, 32, 41, 67),
array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'),
10, 25, 95, 75,
array('title' => 'Daily Orders', 'gradient' => true)
);
$pdf->SetPalette('ocean');
$pdf->HorizontalBarChart(
array(120, 95, 78, 64, 50, 38),
array('Search', 'Direct', 'Social', 'Email', 'Referral', 'Other'),
110, 25, 90, 75,
array('title' => 'Channel Mix', 'gradient' => true)
);
$pdf->SetPalette('modern');
$pdf->LineChart(
array(
array(12, 19, 15, 25, 22, 30, 28, 35, 32, 40),
array( 8, 15, 18, 20, 25, 22, 28, 30, 35, 38),
),
array('Revenue', 'Costs'),
array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct'),
10, 110, 190, 85,
array('title' => 'Revenue vs Costs', 'smoothFill' => true)
);
$pdf->PieChart(
array(35, 25, 20, 12, 8),
array('Mobile', 'Desktop', 'Tablet', 'TV', 'Other'),
10, 205, 95, 75,
array('title' => 'Devices', 'gradient' => true)
);
$pdf->SetPalette('sunset');
$pdf->DonutChart(
array(40, 30, 20, 10),
array('Free', 'Pro', 'Team', 'Enterprise'),
110, 205, 90, 75,
array('title' => 'Plans', 'gradient' => true)
);
$pdf->Output('F', 'report.pdf');