原文:http://zetcode.com/java/jfreechart/

在本教程中,我们学习如何使用 JFreeChart。 我们展示了如何创建各种类型的图表。 图表显示在 Swing 应用中,并保存到图像文件中。 我们使用 Java Servlet 在 Web 浏览器中创建和呈现图表,并从 MySQL 数据库检索图表数据。

JFreeChart 库

图表是一种以简单方式显示信息的图形,通常使用直线和曲线来显示金额。 JFreeChart 是用于创建图表的流行 Java 库。 JFreeChart 允许创建各种交互式和非交互式图表。 我们可以创建折线图,条形图,面积图,散点图,饼图,甘特图和各种专用图,例如风向图或气泡图。

JFreeChart 可以广泛地定制; 它允许修改图表项目的颜色和绘制,图例,线条或标记的样式。 它会自动绘制轴刻度和图例。 图表具有内置功能,可使用鼠标放大。 现有的图表可以通过库在其数据集合上具有的监听器轻松更新。 它支持多种输出格式,包括 PNG,JPEG,PDF 和 SVG。

JFreeChart 由 David Gilbert 于 2000 年创立。如今,JFreeChart 是 Java 开发者中使用最广泛的图表库。

JFreeChart Maven 依赖项

  1. <dependency>
  2. <groupId>org.jfree</groupId>
  3. <artifactId>jfreechart</artifactId>
  4. <version>1.0.19</version>
  5. </dependency>

对于我们的项目,我们使用此 Maven 依赖项。

JFreeChart 折线图

折线图是一种基本类型的图表,它将信息显示为由直线段连接的一系列数据点。 JavaFX 中的折线图是使用ChartFactory.createXYLineChart()创建的。

LineChartEx.java

  1. package com.zetcode.linechartex;
  2. import java.awt.BasicStroke;
  3. import java.awt.Color;
  4. import java.awt.Font;
  5. import javax.swing.BorderFactory;
  6. import javax.swing.JFrame;
  7. import javax.swing.SwingUtilities;
  8. import org.jfree.chart.ChartFactory;
  9. import org.jfree.chart.ChartPanel;
  10. import org.jfree.chart.JFreeChart;
  11. import org.jfree.chart.axis.NumberAxis;
  12. import org.jfree.chart.block.BlockBorder;
  13. import org.jfree.chart.plot.PlotOrientation;
  14. import org.jfree.chart.plot.XYPlot;
  15. import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
  16. import org.jfree.chart.title.TextTitle;
  17. import org.jfree.data.xy.XYDataset;
  18. import org.jfree.data.xy.XYSeries;
  19. import org.jfree.data.xy.XYSeriesCollection;
  20. public class LineChartEx extends JFrame {
  21. public LineChartEx() {
  22. initUI();
  23. }
  24. private void initUI() {
  25. XYDataset dataset = createDataset();
  26. JFreeChart chart = createChart(dataset);
  27. ChartPanel chartPanel = new ChartPanel(chart);
  28. chartPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
  29. chartPanel.setBackground(Color.white);
  30. add(chartPanel);
  31. pack();
  32. setTitle("Line chart");
  33. setLocationRelativeTo(null);
  34. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  35. }
  36. private XYDataset createDataset() {
  37. XYSeries series = new XYSeries("2016");
  38. series.add(18, 567);
  39. series.add(20, 612);
  40. series.add(25, 800);
  41. series.add(30, 980);
  42. series.add(40, 1410);
  43. series.add(50, 2350);
  44. XYSeriesCollection dataset = new XYSeriesCollection();
  45. dataset.addSeries(series);
  46. return dataset;
  47. }
  48. private JFreeChart createChart(XYDataset dataset) {
  49. JFreeChart chart = ChartFactory.createXYLineChart(
  50. "Average salary per age",
  51. "Age",
  52. "Salary (€)",
  53. dataset,
  54. PlotOrientation.VERTICAL,
  55. true,
  56. true,
  57. false
  58. );
  59. XYPlot plot = chart.getXYPlot();
  60. XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
  61. renderer.setSeriesPaint(0, Color.RED);
  62. renderer.setSeriesStroke(0, new BasicStroke(2.0f));
  63. plot.setRenderer(renderer);
  64. plot.setBackgroundPaint(Color.white);
  65. plot.setRangeGridlinesVisible(true);
  66. plot.setRangeGridlinePaint(Color.BLACK);
  67. plot.setDomainGridlinesVisible(true);
  68. plot.setDomainGridlinePaint(Color.BLACK);
  69. chart.getLegend().setFrame(BlockBorder.NONE);
  70. chart.setTitle(new TextTitle("Average Salary per Age",
  71. new Font("Serif", java.awt.Font.BOLD, 18)
  72. )
  73. );
  74. return chart;
  75. }
  76. public static void main(String[] args) {
  77. SwingUtilities.invokeLater(() -> {
  78. LineChartEx ex = new LineChartEx();
  79. ex.setVisible(true);
  80. });
  81. }
  82. }

在示例中,我们创建了一个折线图,显示每个年龄段的平均工资。

  1. XYSeries series = new XYSeries("2016");
  2. series.add(18, 567);
  3. series.add(20, 612);
  4. series.add(25, 800);
  5. ...

XYSeries表示形式为(x, y)的零个或多个数据项的序列。

  1. XYSeriesCollection dataset = new XYSeriesCollection();
  2. dataset.addSeries(series);

该系列将添加到XYSeriesCollection中,该XYSeriesCollection是可以用作数据集的XYSeries对象的集合。

  1. JFreeChart chart = ChartFactory.createXYLineChart(
  2. "Average salary per age",
  3. "Age",
  4. "Salary (€)",
  5. dataset,
  6. PlotOrientation.VERTICAL,
  7. true,
  8. true,
  9. false
  10. );

ChartFactory.createXYLineChart()创建一个新的折线图。 该方法的参数是:图表标题,X 轴标签,Y 轴标签,数据,绘图方向和三个标志,指示是否显示图例,工具提示和 URL。

  1. XYPlot plot = chart.getXYPlot();

我们可以参考该图以对其进行自定义。

  1. XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
  2. renderer.setSeriesPaint(0, Color.RED);
  3. renderer.setSeriesStroke(0, new BasicStroke(2.0f));
  4. plot.setRenderer(renderer);

在这里,我们为图表线设置了描边和颜色。 XYLineAndShapeRenderer是将数据点与线连接和/或在每个数据点绘制形状的对象。 渲染器通过setRenderer()方法设置。

  1. plot.setBackgroundPaint(Color.white);

setBackgroundPaint()设置绘图区域的背景颜色。

  1. plot.setRangeGridlinesVisible(true);
  2. plot.setRangeGridlinePaint(Color.BLACK);
  3. plot.setDomainGridlinesVisible(true);
  4. plot.setDomainGridlinePaint(Color.BLACK);

我们显示网格线并将其涂成黑色。

  1. chart.getLegend().setFrame(BlockBorder.NONE);

我们删除图例周围的边框。

  1. chart.setTitle(new TextTitle("Average Salary per Age",
  2. new Font("Serif", java.awt.Font.BOLD, 18)
  3. )
  4. );

我们使用新字体创建图表标题。

JFreeChart 教程 - 图1

图:折线图

带有两个序列的折线图

在第二个示例中,我们创建具有两个数据序列的折线图。

LineChartEx2.java

  1. package com.zetcode.linechartex2;
  2. import java.awt.BasicStroke;
  3. import java.awt.Color;
  4. import java.awt.Font;
  5. import javax.swing.BorderFactory;
  6. import javax.swing.JFrame;
  7. import javax.swing.SwingUtilities;
  8. import org.jfree.chart.ChartFactory;
  9. import org.jfree.chart.ChartPanel;
  10. import org.jfree.chart.JFreeChart;
  11. import org.jfree.chart.block.BlockBorder;
  12. import org.jfree.chart.plot.PlotOrientation;
  13. import org.jfree.chart.plot.XYPlot;
  14. import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
  15. import org.jfree.chart.title.TextTitle;
  16. import org.jfree.data.xy.XYDataset;
  17. import org.jfree.data.xy.XYSeries;
  18. import org.jfree.data.xy.XYSeriesCollection;
  19. public class LineChartEx2 extends JFrame {
  20. public LineChartEx2() {
  21. initUI();
  22. }
  23. private void initUI() {
  24. XYDataset dataset = createDataset();
  25. JFreeChart chart = createChart(dataset);
  26. ChartPanel chartPanel = new ChartPanel(chart);
  27. chartPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
  28. chartPanel.setBackground(Color.white);
  29. add(chartPanel);
  30. pack();
  31. setTitle("Line chart");
  32. setLocationRelativeTo(null);
  33. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  34. }
  35. private XYDataset createDataset() {
  36. XYSeries series1 = new XYSeries("2014");
  37. series1.add(18, 530);
  38. series1.add(20, 580);
  39. series1.add(25, 740);
  40. series1.add(30, 901);
  41. series1.add(40, 1300);
  42. series1.add(50, 2219);
  43. XYSeries series2 = new XYSeries("2016");
  44. series2.add(18, 567);
  45. series2.add(20, 612);
  46. series2.add(25, 800);
  47. series2.add(30, 980);
  48. series2.add(40, 1210);
  49. series2.add(50, 2350);
  50. XYSeriesCollection dataset = new XYSeriesCollection();
  51. dataset.addSeries(series1);
  52. dataset.addSeries(series2);
  53. return dataset;
  54. }
  55. private JFreeChart createChart(final XYDataset dataset) {
  56. JFreeChart chart = ChartFactory.createXYLineChart(
  57. "Average salary per age",
  58. "Age",
  59. "Salary (€)",
  60. dataset,
  61. PlotOrientation.VERTICAL,
  62. true,
  63. true,
  64. false
  65. );
  66. XYPlot plot = chart.getXYPlot();
  67. XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
  68. renderer.setSeriesPaint(0, Color.RED);
  69. renderer.setSeriesStroke(0, new BasicStroke(2.0f));
  70. renderer.setSeriesPaint(1, Color.BLUE);
  71. renderer.setSeriesStroke(1, new BasicStroke(2.0f));
  72. plot.setRenderer(renderer);
  73. plot.setBackgroundPaint(Color.white);
  74. plot.setRangeGridlinesVisible(false);
  75. plot.setDomainGridlinesVisible(false);
  76. chart.getLegend().setFrame(BlockBorder.NONE);
  77. chart.setTitle(new TextTitle("Average Salary per Age",
  78. new Font("Serif", Font.BOLD, 18)
  79. )
  80. );
  81. return chart;
  82. }
  83. public static void main(String[] args) {
  84. SwingUtilities.invokeLater(() -> {
  85. LineChartEx2 ex = new LineChartEx2();
  86. ex.setVisible(true);
  87. });
  88. }
  89. }

该示例绘制具有两个数据系列的折线图。

  1. XYSeries series1 = new XYSeries("2014");
  2. series1.add(18, 530);
  3. series1.add(20, 580);
  4. series1.add(25, 740);
  5. ...

我们创建第一个系列; 其中包含 2014 年的数据。

  1. XYSeries series2 = new XYSeries("2016");
  2. series2.add(18, 567);
  3. series2.add(20, 612);
  4. series2.add(25, 800);
  5. ...

创建第二个数据系列; 其中包含 2016 年的数据。

  1. XYSeriesCollection dataset = new XYSeriesCollection();
  2. dataset.addSeries(series1);
  3. dataset.addSeries(series2);

通过addSeries()方法将系列添加到XYSeriesCollection

  1. renderer.setSeriesPaint(0, Color.RED);
  2. renderer.setSeriesStroke(0, new BasicStroke(2.0f));
  3. renderer.setSeriesPaint(1, Color.BLUE);
  4. renderer.setSeriesStroke(1, new BasicStroke(2.0f));

一根线涂成红色,另一根线涂成蓝色。

  1. plot.setRangeGridlinesVisible(false);
  2. plot.setDomainGridlinesVisible(false);

网格线已关闭。

JFreeChart 教程 - 图2

图:具有两个系列的折线图

将图表保存到图像

ChartUtilities是 JFreeChart 的工具方法的集合。 它包括将图表转换为图像格式并创建简单的 HTML 图像映射的方法。

LineChartToPNGEx.java

  1. package com.zetcode.linecharttopngex;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import org.jfree.chart.ChartFactory;
  5. import org.jfree.chart.ChartUtilities;
  6. import org.jfree.chart.JFreeChart;
  7. import org.jfree.chart.plot.PlotOrientation;
  8. import org.jfree.data.xy.XYSeries;
  9. import org.jfree.data.xy.XYSeriesCollection;
  10. public class LineChartToPNGEx {
  11. public static void main(String[] args) throws IOException {
  12. XYSeries series1 = new XYSeries("2014");
  13. series1.add(18, 530);
  14. series1.add(20, 580);
  15. series1.add(25, 740);
  16. series1.add(30, 901);
  17. series1.add(40, 1300);
  18. series1.add(50, 2219);
  19. XYSeriesCollection dataset = new XYSeriesCollection();
  20. dataset.addSeries(series1);
  21. JFreeChart chart = ChartFactory.createXYLineChart(
  22. "Average salary per age",
  23. "Age",
  24. "Salary (€)",
  25. dataset,
  26. PlotOrientation.VERTICAL,
  27. true,
  28. true,
  29. false
  30. );
  31. ChartUtilities.saveChartAsPNG(new File("line_chart.png"), chart, 450, 400);
  32. }
  33. }

该示例创建一个折线图并将其保存到 PNG 文件中。

  1. ChartUtilities.saveChartAsPNG(new File("line_chart.png"), chart, 450, 400);

ChartUtilities.saveChartAsPNG()将图表保存为 PNG 格式的指定文件。

JFreeChart 区域图

区域图以图形方式显示随时间变化的定量数据。 在 JFreeChart 中使用ChartFactory.createAreaChart()方法创建面积图。

AreaChartEx.java

  1. package com.zetcode.areachartex;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import javax.swing.BorderFactory;
  5. import javax.swing.JFrame;
  6. import javax.swing.SwingUtilities;
  7. import org.jfree.chart.ChartFactory;
  8. import org.jfree.chart.ChartPanel;
  9. import org.jfree.chart.JFreeChart;
  10. import org.jfree.chart.plot.CategoryPlot;
  11. import org.jfree.chart.plot.PlotOrientation;
  12. import org.jfree.chart.renderer.AreaRendererEndType;
  13. import org.jfree.chart.renderer.category.AreaRenderer;
  14. import org.jfree.chart.title.TextTitle;
  15. import org.jfree.data.category.CategoryDataset;
  16. import org.jfree.data.general.DatasetUtilities;
  17. public class AreaChartEx extends JFrame {
  18. public AreaChartEx() {
  19. initUI();
  20. }
  21. private void initUI() {
  22. CategoryDataset dataset = createDataset();
  23. JFreeChart chart = createChart(dataset);
  24. ChartPanel chartPanel = new ChartPanel(chart);
  25. chartPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
  26. chartPanel.setBackground(Color.white);
  27. add(chartPanel);
  28. pack();
  29. setTitle("Area chart");
  30. setLocationRelativeTo(null);
  31. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  32. }
  33. private CategoryDataset createDataset() {
  34. double[][] data = new double[][]{
  35. {82502, 84026, 85007, 86216, 85559, 84491, 87672,
  36. 88575, 89837, 90701}
  37. };
  38. CategoryDataset dataset = DatasetUtilities.createCategoryDataset(
  39. new String[]{"Oil"}, new String[]{"2004", "2005", "2006",
  40. "2007", "2008", "2009", "2010", "2011", "2012", "2013"},
  41. data
  42. );
  43. return dataset;
  44. }
  45. private JFreeChart createChart(CategoryDataset dataset) {
  46. JFreeChart chart = ChartFactory.createAreaChart(
  47. "Oil consumption",
  48. "Time",
  49. "Thousands bbl/day",
  50. dataset,
  51. PlotOrientation.VERTICAL,
  52. false,
  53. true,
  54. true
  55. );
  56. CategoryPlot plot = (CategoryPlot) chart.getPlot();
  57. plot.setForegroundAlpha(0.3f);
  58. AreaRenderer renderer = (AreaRenderer) plot.getRenderer();
  59. renderer.setEndType(AreaRendererEndType.LEVEL);
  60. chart.setTitle(new TextTitle("Oil consumption",
  61. new Font("Serif", java.awt.Font.BOLD, 18))
  62. );
  63. return chart;
  64. }
  65. public static void main(String[] args) {
  66. SwingUtilities.invokeLater(() -> {
  67. AreaChartEx ex = new AreaChartEx();
  68. ex.setVisible(true);
  69. });
  70. }
  71. }

该示例显示了一个区域图,该区域图按年份显示了世界原油消耗量。

  1. double[][] data = new double[][]{
  2. {82502, 84026, 85007, 86216, 85559, 84491, 87672,
  3. 88575, 89837, 90701}
  4. };
  5. CategoryDataset dataset = DatasetUtilities.createCategoryDataset(
  6. new String[]{"Oil"}, new String[]{"2004", "2005", "2006",
  7. "2007", "2008", "2009", "2010", "2011", "2012", "2013"},
  8. data
  9. );

使用DatasetUtilities.createCategoryDataset()方法创建数据集。 与类别关联的类别数据集值。 在我们的示例中,我们有数年与石油消耗有关。

  1. CategoryPlot plot = (CategoryPlot) chart.getPlot();
  2. plot.setForegroundAlpha(0.3f);

我们使用setForegroundAlpha()方法使图表透明。

  1. AreaRenderer renderer = (AreaRenderer) plot.getRenderer();
  2. renderer.setEndType(AreaRendererEndType.LEVEL);

我们调整图表的结尾。

JFreeChart 教程 - 图3

图:面积图

JFreeChart 条形图

条形图显示带有矩形条的分组数据,其长度与它们所代表的值成比例。 条形图可以垂直或水平绘制。

BarChartEx.java

  1. package com.zetcode.barchartex;
  2. import java.awt.Color;
  3. import javax.swing.BorderFactory;
  4. import javax.swing.JFrame;
  5. import javax.swing.SwingUtilities;
  6. import org.jfree.chart.ChartFactory;
  7. import org.jfree.chart.ChartPanel;
  8. import org.jfree.chart.JFreeChart;
  9. import org.jfree.chart.plot.PlotOrientation;
  10. import org.jfree.data.category.CategoryDataset;
  11. import org.jfree.data.category.DefaultCategoryDataset;
  12. public class BarChartEx extends JFrame {
  13. public BarChartEx() {
  14. initUI();
  15. }
  16. private void initUI() {
  17. CategoryDataset dataset = createDataset();
  18. JFreeChart chart = createChart(dataset);
  19. ChartPanel chartPanel = new ChartPanel(chart);
  20. chartPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
  21. chartPanel.setBackground(Color.white);
  22. add(chartPanel);
  23. pack();
  24. setTitle("Bar chart");
  25. setLocationRelativeTo(null);
  26. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  27. }
  28. private CategoryDataset createDataset() {
  29. DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  30. dataset.setValue(46, "Gold medals", "USA");
  31. dataset.setValue(38, "Gold medals", "China");
  32. dataset.setValue(29, "Gold medals", "UK");
  33. dataset.setValue(22, "Gold medals", "Russia");
  34. dataset.setValue(13, "Gold medals", "South Korea");
  35. dataset.setValue(11, "Gold medals", "Germany");
  36. return dataset;
  37. }
  38. private JFreeChart createChart(CategoryDataset dataset) {
  39. JFreeChart barChart = ChartFactory.createBarChart(
  40. "Olympic gold medals in London",
  41. "",
  42. "Gold medals",
  43. dataset,
  44. PlotOrientation.VERTICAL,
  45. false, true, false);
  46. return barChart;
  47. }
  48. public static void main(String[] args) {
  49. SwingUtilities.invokeLater(() -> {
  50. BarChartEx ex = new BarChartEx();
  51. ex.setVisible(true);
  52. });
  53. }
  54. }

该代码示例使用条形图显示了 2012 年伦敦每个国家/地区的奥运金牌数量。

  1. DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  2. dataset.setValue(46, "Gold medals", "USA");
  3. dataset.setValue(38, "Gold medals", "China");
  4. dataset.setValue(29, "Gold medals", "UK");
  5. dataset.setValue(22, "Gold medals", "Russia");
  6. dataset.setValue(13, "Gold medals", "South Korea");
  7. dataset.setValue(11, "Gold medals", "Germany");

我们使用DefaultCategoryDataset创建数据集。

  1. JFreeChart barChart = ChartFactory.createBarChart(
  2. "Olympic gold medals in London",
  3. "",
  4. "Gold medals",
  5. dataset,
  6. PlotOrientation.VERTICAL,
  7. false, true, false);

使用ChartFactory.createBarChart()方法创建条形图。

JFreeChart 教程 - 图4

图:条形图

JFreeChart 饼图

饼图是一种圆图,分为多个切片以说明数值比例。 使用 JFreeChart 中的ChartFactory.createPieChart()方法创建一个饼图。

PieChartEx.java

  1. package com.zetcode.piechartex;
  2. import java.awt.Color;
  3. import javax.swing.BorderFactory;
  4. import javax.swing.JFrame;
  5. import javax.swing.SwingUtilities;
  6. import org.jfree.chart.ChartFactory;
  7. import org.jfree.chart.ChartPanel;
  8. import org.jfree.chart.JFreeChart;
  9. import org.jfree.data.general.DefaultPieDataset;
  10. public class PieChartEx extends JFrame {
  11. public PieChartEx() {
  12. initUI();
  13. }
  14. private void initUI() {
  15. DefaultPieDataset dataset = createDataset();
  16. JFreeChart chart = createChart(dataset);
  17. ChartPanel chartPanel = new ChartPanel(chart);
  18. chartPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
  19. chartPanel.setBackground(Color.white);
  20. add(chartPanel);
  21. pack();
  22. setTitle("Pie chart");
  23. setLocationRelativeTo(null);
  24. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  25. }
  26. private DefaultPieDataset createDataset() {
  27. DefaultPieDataset dataset = new DefaultPieDataset();
  28. dataset.setValue("Apache", 52);
  29. dataset.setValue("Nginx", 31);
  30. dataset.setValue("IIS", 12);
  31. dataset.setValue("LiteSpeed", 2);
  32. dataset.setValue("Google server", 1);
  33. dataset.setValue("Others", 2);
  34. return dataset;
  35. }
  36. private JFreeChart createChart(DefaultPieDataset dataset) {
  37. JFreeChart barChart = ChartFactory.createPieChart(
  38. "Web servers market share",
  39. dataset,
  40. false, true, false);
  41. return barChart;
  42. }
  43. public static void main(String[] args) {
  44. SwingUtilities.invokeLater(() -> {
  45. PieChartEx ex = new PieChartEx();
  46. ex.setVisible(true);
  47. });
  48. }
  49. }

该示例使用饼图来显示 Web 服务器的市场份额。

  1. DefaultPieDataset dataset = new DefaultPieDataset();
  2. dataset.setValue("Apache", 52);
  3. dataset.setValue("Nginx", 31);
  4. dataset.setValue("IIS", 12);
  5. ...

DefaultPieDataset用于创建数据集。

  1. JFreeChart barChart = ChartFactory.createPieChart(
  2. "Web servers market share",
  3. dataset,
  4. false, true, false);

使用ChartFactory.createPieChart()方法创建一个新的饼图。

Servlet 中的 JFreeChart

在以下示例中,我们使用 Java servlet 创建饼图。 该图表在 Web 浏览器中呈现。

DoChart.java

  1. package com.zetcode.servletchart;
  2. import java.awt.BasicStroke;
  3. import java.awt.Color;
  4. import java.io.IOException;
  5. import java.io.OutputStream;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.annotation.WebServlet;
  8. import javax.servlet.http.HttpServlet;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. import org.jfree.chart.ChartFactory;
  12. import org.jfree.chart.ChartUtilities;
  13. import org.jfree.chart.JFreeChart;
  14. import org.jfree.data.general.DefaultPieDataset;
  15. @WebServlet(name = "DoChart", urlPatterns = {"/DoChart"})
  16. public class DoChart extends HttpServlet {
  17. @Override
  18. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  19. throws ServletException, IOException {
  20. response.setContentType("image/png");
  21. OutputStream outputStream = response.getOutputStream();
  22. JFreeChart chart = getChart();
  23. int width = 500;
  24. int height = 350;
  25. ChartUtilities.writeChartAsPNG(outputStream, chart, width, height);
  26. }
  27. public JFreeChart getChart() {
  28. DefaultPieDataset dataset = new DefaultPieDataset();
  29. dataset.setValue("Croatia", 22);
  30. dataset.setValue("Bohemia", 34);
  31. dataset.setValue("Bulgaria", 18);
  32. dataset.setValue("Spain", 5);
  33. dataset.setValue("Others", 21);
  34. JFreeChart chart = ChartFactory.createPieChart("Popular destinations",
  35. dataset, true, false, false);
  36. chart.setBorderVisible(false);
  37. return chart;
  38. }
  39. }

DoChart Servlet 创建一个饼图并将其发送到客户端。

  1. response.setContentType("image/png");

setContentType()将内容设置为 PNG 图像。

  1. OutputStream outputStream = response.getOutputStream();

使用getOutputStream()方法,我们得到一个输出流。 这是我们向其发送数据的隧道。

  1. ChartUtilities.writeChartAsPNG(outputStream, chart, width, height);

ChartUtilities.writeChartAsPNG()将二进制数据写入输出字符串。

JFreeChart 教程 - 图5

图:浏览器中的饼图

显示来自 MySQL 数据库的数据

JDBCCategoryDataset是对数据库 JDBC 结果集的CategoryDataset实现。 通过使用字符串 SQL 查询调用executeQuery()来填充数据集。

medals.sql

  1. DROP TABLE IF EXISTS GoldMedalsLondon;
  2. CREATE TABLE GoldMedalsLondon (
  3. Id int(11) NOT NULL AUTO_INCREMENT,
  4. Country text,
  5. Medals int(11) DEFAULT NULL,
  6. PRIMARY KEY (Id)
  7. ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;
  8. LOCK TABLES GoldMedalsLondon WRITE;
  9. INSERT INTO GoldMedalsLondon VALUES (1,'USA',46),(2,'China',38),(3,'UK',29),
  10. (4,'Russia',22),(5,'South Korea',13),(6,'Germany',11);
  11. UNLOCK TABLES;

我们将这些数据存储在 MySQL 数据库表中。

  1. mysql> SELECT * FROM GoldMedalsLondon;
  2. +----+-------------+--------+
  3. | Id | Country | Medals |
  4. +----+-------------+--------+
  5. | 1 | USA | 46 |
  6. | 2 | China | 38 |
  7. | 3 | UK | 29 |
  8. | 4 | Russia | 22 |
  9. | 5 | South Korea | 13 |
  10. | 6 | Germany | 11 |
  11. +----+-------------+--------+
  12. 6 rows in set (0.00 sec)

我们使用mysql工具显示数据。

MySQLChartEx.java

  1. package com.zetcode.mysqlchartex;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.sql.Connection;
  5. import java.sql.DriverManager;
  6. import java.sql.SQLException;
  7. import org.jfree.chart.ChartFactory;
  8. import org.jfree.chart.ChartUtilities;
  9. import org.jfree.chart.JFreeChart;
  10. import org.jfree.chart.plot.PlotOrientation;
  11. import org.jfree.data.jdbc.JDBCCategoryDataset;
  12. public class MySQLChartEx {
  13. private static JDBCCategoryDataset dataset;
  14. public static void main(String[] args) throws IOException, SQLException {
  15. Connection con = null;
  16. String url = "jdbc:mysql://localhost:3306/testdb";
  17. String user = "testuser";
  18. String password = "test623";
  19. try {
  20. con = DriverManager.getConnection(url, user, password);
  21. dataset = new JDBCCategoryDataset(con);
  22. dataset.executeQuery("SELECT Country, Medals FROM GoldMedalsLondon");
  23. } finally {
  24. if (con != null) {
  25. con.close();
  26. }
  27. }
  28. JFreeChart barChart = ChartFactory.createBarChart(
  29. "Olympic Gold medals in London",
  30. "",
  31. "Gold medals",
  32. dataset,
  33. PlotOrientation.VERTICAL,
  34. false, true, false);
  35. ChartUtilities.saveChartAsPNG(new File("medals.png"), barChart, 450, 400);
  36. }
  37. }

该示例从 MySQL 表检索数据,创建条形图,然后将其保存到 PNG 图像中。

  1. con = DriverManager.getConnection(url, user, password);
  2. dataset = new JDBCCategoryDataset(con);

JDBCCategoryDataset已创建; 它以数据库连接为参数。

  1. dataset.executeQuery("SELECT Country, Medals FROM GoldMedalsLondon");

executeQuery()通过针对现有数据库连接执行提供的查询来填充数据集。 SQL 查询必须至少返回两列。 第一列是类别名称,其余列是值。

  1. JFreeChart barChart = ChartFactory.createBarChart(
  2. "Olympic Gold medals in London",
  3. "",
  4. "Gold medals",
  5. dataset,
  6. PlotOrientation.VERTICAL,
  7. false, true, false);

条形图已创建。

  1. ChartUtilities.saveChartAsPNG(new File("medals.png"), barChart, 450, 400);

条形图通过ChartUtilities.saveChartAsPNG()方法保存到 PNG 文件中。

本教程专门针对 JFreeChart 库。 您可能也对相关教程感兴趣: Java Swing 教程Java 2D 教程Java PDFBox 教程Java 教程。 也可以在 JavaFX 中创建图表