Using the Chart component to draw a scatter chart with a trend line, and a table that lists the chart points.
Example_09.pdf — the PDF this example creates.
/*
* Example_09.java
*
* Copyright (c) 2026 PDFjet Software
* Licensed under the MIT License. See LICENSE file in the project root.
*/
package examples;
import java.io.*;
import java.util.*;
import com.pdfjet.*;
import com.pdfjet.fonts.*;
/**
* Example_09.java
*
* Draws an XY chart of the countries of a data file, each a marker that links
* to a page about the country, with the trend line of the points, and a table
* of the countries with a marker of their own.
*/
final public class Example_09 {
/** A country of the data file: its name and its point on the chart. */
private static final class Country {
final String name;
final Point point;
Country(String name, Point point) {
this.name = name;
this.point = point;
}
}
public Example_09() throws Exception {
PDF pdf = new PDF(
new BufferedOutputStream(new FileOutputStream("Example_09.pdf")));
Font f1 = new Font(pdf, IBMPlexSans.Bold);
f1.setSize(8f);
Font f2 = new Font(pdf, IBMPlexSans.Regular);
f2.setSize(8f);
Page page = new Page(pdf, Letter.PORTRAIT);
List<Country> countries = readCountries("data/world-communications.txt", "|");
Chart chart = new Chart(f1, f2);
chart.setLocation(70f, 50f);
chart.setSize(500f, 300f);
chart.setTitle("World View - Communications");
chart.setXAxisTitle("Cell phones per capita");
chart.setYAxisTitle("Internet users % of the population");
Series markers = chart.addSeries("").setStrokeColor(Color.gray);
for (Country country : countries) {
markers.addPoint(country.point);
}
addTrendLine(chart, countries);
chart.drawOn(page);
f1.setSize(7f);
f2.setSize(7f);
addTableToChart(page, countries, f1, f2);
pdf.complete();
}
public void addTrendLine(Chart chart, List<Country> countries) {
List<Point> points = new ArrayList<Point>();
for (Country country : countries) {
points.add(country.point);
}
float m = slope(points);
float b = intercept(points, m);
chart.addSeries("Trend line")
.setDrawPath(true)
.setStrokeColor(Color.blue)
.setShape(Shape.INVISIBLE)
.addPoint(0f, b)
.addPoint(1.5f, m * 1.5f + b);
}
public void addTableToChart(
Page page, List<Country> countries, Font f1, Font f2) throws Exception {
Table table = new Table();
List<List<Cell>> tableData = new ArrayList<List<Cell>>();
for (Country country : countries) {
if (country.point.getShape() != Shape.CIRCLE) {
List<Cell> tableRow = new ArrayList<Cell>();
Cell cell = new Cell(f2);
cell.setMarker(country.point, Alignment.LEFT);
cell.setText("");
tableRow.add(cell);
cell = new Cell(f1);
cell.setText(country.name);
tableRow.add(cell);
cell = new Cell(f2);
cell.setText(country.point.getURIAction());
tableRow.add(cell);
tableData.add(tableRow);
}
}
table.setTableData(tableData);
table.autoAdjustColumnWidths();
table.setCellBorderWidth(0.2f);
table.setLocation(70f, 360f);
table.setColumnWidth(0, 9f);
table.drawOn(page);
}
public List<Country> readCountries(
String fileName,
String delimiter) throws Exception {
List<Country> countries = new ArrayList<Country>();
BufferedReader reader = null;
try {
reader = new BufferedReader(
new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
String[] cols = null;
if (delimiter.equals("|")) {
cols = line.split("\\|", -1);
} else if (delimiter.equals("\t")) {
cols = line.split("\t", -1);
} else {
throw new Exception(
"Only pipes and tabs can be used as delimiters");
}
try {
double population =
Double.valueOf(cols[1].replace(",", ""));
String name = cols[0].trim();
String country_name = name;
country_name = country_name.replace(" ", "_");
country_name = country_name.replace("'", "_");
country_name = country_name.replace(",", "_");
country_name = country_name.replace("(", "_");
country_name = country_name.replace(")", "_");
Point point = new Point(
(float) (Double.valueOf(cols[5].replace(",", "")) / population),
(float) (Double.valueOf(cols[7].replace(",", "")) / population * 100));
point.setURIAction("http://pdfjet.com/country/" + country_name + ".txt");
point.setRadius(2f);
if (point.getX() > 1.25f) {
point.setShape(Shape.RIGHT_ARROW);
point.setStrokeColor(Color.black);
} else if (point.getY() > 80f) {
point.setShape(Shape.UP_ARROW);
point.setStrokeColor(Color.blue);
} else if (name.equals("France")) {
point.setShape(Shape.MULTIPLY);
point.setStrokeColor(Color.green);
} else if (name.equals("Canada")) {
point.setShape(Shape.BOX);
point.setStrokeColor(Color.orange);
} else if (name.startsWith("United States")) {
point.setShape(Shape.STAR);
point.setStrokeColor(Color.red);
}
countries.add(new Country(name, point));
} catch (Exception e) {
}
}
} finally {
reader.close();
}
return countries;
}
// The slope and intercept of the ordinary least squares trend line of the points.
private static float slope(List<Point> points) {
return covar(points) / devsq(points) * (points.size() - 1);
}
private static float intercept(List<Point> points, float slope) {
float[] mean = mean(points);
return mean[1] - slope * mean[0];
}
private static float[] mean(List<Point> points) {
float[] mean = new float[2];
for (Point point : points) {
mean[0] += point.getX();
mean[1] += point.getY();
}
mean[0] /= points.size();
mean[1] /= points.size();
return mean;
}
private static float covar(List<Point> points) {
float covariance = 0f;
float[] mean = mean(points);
for (Point point : points) {
covariance += (point.getX() - mean[0]) * (point.getY() - mean[1]);
}
return covariance / (points.size() - 1);
}
private static float devsq(List<Point> points) {
float devsq = 0f;
float[] mean = mean(points);
for (Point point : points) {
devsq = devsq + (float) Math.pow(point.getX() - mean[0], 2);
}
return devsq;
}
public static void main(String[] args) throws Exception {
long time0 = System.currentTimeMillis();
new Example_09();
long time1 = System.currentTimeMillis();
System.out.printf("Example_09 => %4d ms%n", time1 - time0);
}
} // End of Example_09.java
©2026 PDFjet Software.