示例 6:使用 Apache Batik 在 SVG 中生成图表
无需任何专门的工作,JFreeChart 即可提供现成的 PNG 和 JPEG 图像生成。由于图表实际上是由直线以及诸如矩形、圆形以及其他矢量形状组成的,因此 SVG可伸缩矢量图形)等基于矢量的格式似乎都非常适合图表。尽管 JFreeChart 并不直接提供 SVG 显示功能,但它可与 Apache 的 Batik SVG 工具包结合使用以形成其图表的 SVG 表示。
Batik SVG 工具包是一个基于 Java 的工具包,它用于操作 SVG,免费提供。本示例中使用 Batik 1.7。分发中包括几个可执行的 JAR 文件。其中一个文件 (batik.jar) 是一个可执行的 JAR,它运行一个名为 Squiggle 的 SVG 处理和查看工具 (java –jar batik.jar)。
在本示例中,我们首先将在自己的 Java 代码中将 Batik 直接用作一个库,然后将使用可执行的 JAR (batik.jar) 运行 Squiggle 以查看生成的 SVG 文件。为了构建和运行本示例中与 Batik 有关的代码,必须在类路径或者 JDeveloper 或其他 IDE 的项目)中包括六个 JAR 文件。图 4 显示了这六个 JAR 文件六个以“Batik”开头的 JAR 文件)。
在本示例中,生成的图表是一个显示发货员工资的三维条形图。这与前面的条形图示例示例 3)不同,因为它具有三维而非二维的外观,并被指定为一个水平条形图而非垂直条形图。以下两个代码清单分别显示了如何生成该图表以及如何以 SVG 格式写出。
清单 9: 创建三维条形图
/**
* Create 3D bar chart representing salaries of shipping clerks.
*
* @param aOrientation Horizontal or Vertical orientation.
* @return 3D bar chart.
*/
public JFreeChart createSalaryPerShippingClerkBarChart3D(
PlotOrientation aOrientation)
{
JFreeChart barChart = null;
try
{
final String QUERY_SALARY_PER_SHIPPING_CLERK =
"SELECT first_name || ' ' || last_name AS name, salary " +
"FROM employees " +
"WHERE job_id = 'SH_CLERK'";
final CategoryDataset barDataset =
new JDBCCategoryDataset( databaseAccess.getOracleDbConnection(),
QUERY_SALARY_PER_SHIPPING_CLERK );
barChart =
ChartFactory.createBarChart3D( TITLE_COUNTRIES_PER_REGION, // title
LABEL_SHIPPING_CLERKS,
LABEL_SALARIES,
barDataset,
aOrientation,
true, // legend displayed
true, // tooltips displayed
false ); // no URLs
}
catch (SQLException sqlEx)
{
// exception handling code . . .
}
return barChart;
} |
上一个代码清单演示了创建三维条形图与创建二维条形图基本相同,只是 ChartFactory 类上调用的方法名不同。以下代码清单显示了如何将这个或任何其他生成的 JFreeChart 写出为 SVG 格式。
清单 10: 以 SVG 格式显示 JFreeChart 生成的图表
/**
* Write .svg file based on provided JFreeChart.
*
* @param aChart Chart to be written out as SVG.
* @param aFileName Name of file (without extension) to hold SVG XML.
* @param aWidth Width of image.
* @param aHeight Height of image.
*/
public void writeSvgBasedOnChart( JFreeChart aChart,
String aFileName,
int aWidth,
int aHeight )
{
final String fileExtension = ".svg";
final String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI;
final DOMImplementation dom =
GenericDOMImplementation.getDOMImplementation();
org.w3c.dom.Document document = dom.createDocument(svgNS, "svg", null);
SVGGraphics2D svgGraphic = new SVGGraphics2D(document);
aChart.draw( svgGraphic, new java.awt.Rectangle(aWidth, aHeight) );
try
{
boolean useCSS = true; // we want to use CSS style attributes
OutputStream outputStream =
new FileOutputStream(aFileName + fileExtension);
Writer output = new OutputStreamWriter(outputStream, "UTF-8");
svgGraphic.stream(output, useCSS);
outputStream.flush();
outputStream.close();
}
catch (IOException ioEx)
{
System.err.println("Problem encountered trying to write SVG file: ");
ioEx.printStackTrace();
}
} |
将三维条形图传给上面的方法以便写出 SVG 时,会将该条形图写入到所提供的文件名。生成的 SVG 文件将只是一个扩展名为 .svg 的文本文件,包含符合 SVG 的 XML 内容。可以用任何文本编辑器查看该生成文件中的 XML,但使用 Batik、Inkscape 或几乎是任何现代图形文件编辑器等工具查看 SVG 显示的图像,则更为有趣。实际上,可以在任何最新版本的 Firefox Web 浏览器中直接打开某个 .svg 文件来查看 SVG,因为它附带了一个内置的 SVG 查看器。此处显示的图形是 Batik 的 Squiggle 显示生成的 SVG 文件的快照。
![]() |
| 图10:SVG 格式的三维水平条形图由Batik Squiggle显示) |
用 SVG 格式显示图表有几个好处,其中一个最明显的好处就是能够根据我们的需要放大图像且不会损失分辨率,这都多亏了 SVG 矢量图形的可伸缩性。其他好处包括使用 Inkscape 之类的工具或者甚至手动如果需要的话)编辑生成的 SVG 来调整生成的图像也变得相对容易。
