JFreeChart创建直方条形图包括了:堆栈式直方条形图、时序数据的条形直方图、柱状图等。
本文先对直方图进行介绍。了解简单柱状图的创建过程。
1、概述
直方条形图常常被用来显示表列数据。如下表,为一个简单的两行、三列数据。
| Colnums1 | Colnums2 | Colnums3 |
Row1 | 1.0 | 5.0 | 3.0 |
Row2 | 2.0 | 3.0 | 2.0 |
在JFreeChart里,这个表格数据封装为一个dataset数据对象,每列标题为一个种类,每行为一个系列。每行标题为一个系列名称(或者系列关键值)。直方条形图展现的数据图如下图:
在这个图表的实例中,我们可以看到JFreeChart将每列数据(即一个种类)组合在一起。而且对每行数据(即每个系列)使用各种颜色高亮显示。图表的图例将颜色和系列的名称/关键值对应起来。
2、创建一个DataSet
创建直方条形图的第一步就是创建一个合适的dataset数据集。JFreeChart为直方条形图提供的访问表列数据的一系列方法,必须符合接口CategoryDataset定义。
JFreeChart中提供了一个便利的实现CategoryDataset接口的类为DefaultCategoryDataset。下面显示我们如何使用这个类来封装数据。代码如下:
private CategoryDataset createDataset() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(1.0, "Row 1", "Column 1");
dataset.addValue(5.0, "Row 1", "Column 2");
dataset.addValue(3.0, "Row 1", "Column 3");
dataset.addValue(2.0, "Row 2", "Column 1");
dataset.addValue(3.0, "Row 2", "Column 2");
dataset.addValue(2.0, "Row 2", "Column 3");
return dataset;
}
3、创建一个Chart图表
接下来就是要创建一个JFreeChart的实例,使用上面提供的dataset数据集画一个直方条形图。简单的,我们使用ChartFactory类来创建这个JFreeChart实例。代码如下:
private JFreeChart createChart(CategoryDataset dataset) {
JFreeChart chart = ChartFactory.createBarChart("BarChartDemo", // chart title
"Category", // domain axis label
"Value", // range axis label
dataset, // data
PlotOrientation.VERTICAL, // 图标方向
true, // 是否显示legend
true, // 是否显示tooltips
false // 是否显示URLs
);
return chart;
}
4、理解ChartFactory类
在上面的实例代码中,我们使用ChartFactory类来组装一个JFreeChart实例来显示一个直方条形图。下面我们更仔细的看一下该类是如何工作的,因此我们可以看到直方条形图更多底层的框架结构。理解底层结构的关键是能定制图表的外观。下面是ChartFactory方法createBarChart()方法部分代码:
1.CategoryAxis categoryAxis = new CategoryAxis(categoryAxisLabel);
2.ValueAxis valueAxis = new NumberAxis(valueAxisLabel);
3.BarRenderer renderer = new BarRenderer();
……
4.CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
5.plot.setOrientation(orientation);
6.JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, plot, legend);
以下就是代码所做的工作。
l我们的直方条形图有两个轴,一个轴显示dataset(CategoryAxis)的种类,另一个是显示带有数据(NumberAxis)刻度的数据轴。上面代码中代码1、2行建立了这两个轴,轴的标签是createBarChart()方法传入的。
l第三行,创建了一个BarRender——该类为每一个数据项目画直方图。该render处理大部分画图工作,我们后续代码也会看到可以使用另一个类型的render替换现有的render,来改变图表的整个外观。
lDataset、axes和render都由CategorryPlot来管理,CategorryPlot系统组件之间的大部分交互工作。当我们定制一个图表时,我们经常需要先获得整个图表plot、renderer和dataset的引用。在代码的第四行,创建了一个plot,然后其他组件对它进行赋值。
l最后,在JFreeChart实例中,这个plot用指定的标题被封装。JFreeChart类提供了比较高层次的访问图表。但在这个plot曾思图表就大部分被定义出来了(Plot管理很多对象,例如axes、dataset和renderer)。
图表的内部结构基本上是由上面的知识理论组成。在后续的章节,我们会逐渐学习更多的定制我们图表的方法。
5、简单柱形图实例
柱形图实例代码:
public class BarChartExample
{
/**
* 创建BarChart
* @author 新(mervin)
* @return 生成Chart图片的地址
*/
public String createBarChart()
{
String filePath = "D:\\testJfreeChart.jpg";
try
{
//设置Chart主题
setChartTheme();
DefaultCategoryDataset dataset = getBarDataSet();
JFreeChart chart = ChartFactory.createBarChart3D("水果产量图-复合数据", "水果",
"产量", dataset, PlotOrientation.VERTICAL, true, true, false);
ChartUtilities.saveChartAsJPEG(new File(filePath), chart, 400, 300);
} catch (IOException e)
{
e.printStackTrace();
}
return filePath;
}
/**
* 设置ChartFactory主题,可解决乱码问题
*/
private void setChartTheme()
{
// 创建主题样式
StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
// 设置标题字体
standardChartTheme.setExtraLargeFont(new Font("宋书", Font.BOLD, 20));
// 设置图例的字体
standardChartTheme.setRegularFont(new Font("宋书", Font.PLAIN, 15));
// 设置轴向的字体
standardChartTheme.setLargeFont(new Font("宋书", Font.PLAIN, 15));
// 应用主题样式
ChartFactory.setChartTheme(standardChartTheme);
}
/**
* 获得复杂(组合)BarChart的数据集
* @return BarChart数据集
*/
private DefaultCategoryDataset getBarDataSet()
{
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(100, "北京", "苹果");
dataset.addValue(100, "上海", "苹果");
dataset.addValue(100, "广州", "苹果");
dataset.addValue(200, "北京", "梨子");
dataset.addValue(200, "上海", "梨子");
dataset.addValue(200, "广州", "梨子");
dataset.addValue(300, "北京", "葡萄");
dataset.addValue(300, "上海", "葡萄");
dataset.addValue(300, "广州", "葡萄");
dataset.addValue(400, "北京", "香蕉");
dataset.addValue(400, "上海", "香蕉");
dataset.addValue(400, "广州", "香蕉");
dataset.addValue(500, "北京", "荔枝");
dataset.addValue(500, "上海", "荔枝");
dataset.addValue(500, "广州", "荔枝");
return dataset;
}
/**
* @param args
*/
public static void main(String[] args)
{
BarChartExample piechart = new BarChartExample();
String filePath = piechart.createBarChart();
System.out.println("PieChart file path : " + filePath);
try
{
Runtime.getRuntime().exec(
"rundll32 url.dll FileProtocolHandler " + filePath);
} catch (IOException e)
{
e.printStackTrace();
}
}
}
运行结果: