JFreeChart生成柱形图(2) (转自 JSP开发技术大全)

14.2 利用JFreeChart生成柱形图14.2.1 利用DefaultCategoryDataset数据集绘制柱形图

通过JFreeChart插件,既可以生成普通效果的柱形图,也可以生成3D效果的柱形图。如果想生成普通效果的柱形图,需要通过工厂类ChartFactory的createBarChart()方法获得JFreeChart类的实例;如果想生成3D效果的柱形图,需要通过工厂类ChartFactory的createBarChart3D()方法获得JFreeChart类的实例,这两个方法的入口参数是完全相同的,各个入口参数的类型及功能如表14.2所示。

表14.2                                      绘制柱形图方法的入口参数类型及功能

参 数 序 号

入 口 参 数

参 数 功 能

1

String title

图表标题

2

String categoryAxisLabel

统计种类轴标题,可以理解为X轴标题

3

String valueAxisLabel

统计值轴标题,可以理解为Y轴标题

4

CategoryDataset dataset

绘图数据集

5

PlotOrientation orientation

用于设定柱形图的绘制方向

垂直:PlotOrientation.VERTICAL

水平:PlotOrientation.HORIZONTAL

6

boolean legend

用于设定是否显示图例

7

boolean tooltips

用于设定是否采用标准生成器

8

boolean urls

用于设定是否包生成链接

工厂类ChartFactory中的方法的返回值均为JFreeChart类的实例,通过返回的JFreeChart类的实例,可以设置绘图属性,也可以省略该步,直接生成图片,JFreeChart插件将采用默认的绘图属性进行绘制。

可以通过JFreeChart实例设置整个图片的绘制属性,例如通过setBackgroundPaint(Paint paint)方法设置图片的背景色,入口参数可以是Color类的实例,也可以是GradientPaint类的实例,通过GradientPaint类的实例可以实现渐变的背景色效果。

还可以通过JFreeChart实例的getCategoryPlot()方法获得CategoryPlot类的实例,通过CategoryPlot类的实例可以设置绘图区的绘图属性,例如设置绘图区的背景色,标准线的绘制属性等。通过CategoryPlot实例的getRenderer()方法可以获得BarRenderer类的实例,通过BarRenderer类的实例可以设置柱形的绘制属性,例如是否绘制柱形的轮廓线,以及柱形的填充色等,通过BarRenderer实例的setSeriesPaint(int series, Paint paint)方法设置柱形的填充色,第一个入口参数为图例的索引位置,从0开始,第二个入口参数为填充色,同样既可以接受Color类的实例,也可以接受GradientPaint类的实例。

 示例14-01 利用DefaultCategoryDataset数据集绘制柱形图

下面来看一个绘制柱形图的完整例子,该例绘制的柱形图效果如图14.1和图14.2所示。

       

   图14.1 当绘图数据全部为正数时绘制出的柱形图       图14.2 当绘图数据存在负数时绘制出的柱形图

代码14-01 光盘位置:光盘\mingrisoft\14\sl\01

绘图时需要用到的相关信息如下:

int width = 500;     // 图像宽度
int height = 375;      // 图像高度
String chartTitle = "编程类图书年销量柱形图分析";     // 图表标题
String subtitle = "------统计时间:2008年";     // 副标题
String xTitle = "销售时间:2008年";     // X轴标题
String yTitle = "销售量    单位:万册";     // Y轴标题
String[] cutline = new String[] { "ASP", "JSP", "PHP" };     // 图例名称
String category[] = new String[] {"第1季度","第2季度","第3季度","第4季度"};   // 统计种类
Double[][] data = new Double[cutline.length][category.length];     // 绘图数据
for (int m = 0; m < cutline.length; m++) {     // 随机获取绘图数据
    for (int n = 0; n < category.length; n++) {
    data[m][n] = 1 + Math.random() * 100;
    }
}
String servletURI = "/servlet/DisplayChart";     // 映射路径

   注意:仔细观察上面的for循环代码,会发现外循环是根据图例个数循环的,内循环是根据数据类别个数循环的,所以,在向绘图数据集中添加数据时,是按照图例的顺序添加的,即添加一个图例所有类别数据后再添加另一个图例的数据(对于竖向柱形图来说,并不是按照柱形从左到右的顺序添加数据的)。

    说明:上面给出的绘图数据为图14.1的绘图数据,限于篇幅,在这里就不给出图14.2的绘图数据了。

首先通过DefaultCategoryDataset类的实例封装绘图数据,代码如下:

DefaultCategoryDataset dataset = new DefaultCategoryDataset();
for (int m = 0; m < cutline.length; m++) {
    for (int n = 0; n < category.length; n++) {
    dataset.addValue(data[m][n], cutline[m], category[n]);
    }
}

本示例绘制3D效果的柱形图,所以通过createBarChart3D()方法获得JFreeChart类的实例,只要改为createBarChart()方法,就可以绘制普通效果的柱形图,代码如下:

JFreeChart chart = ChartFactory.createBarChart3D(chartTitle,     // 图表标题
        xTitle,     // X轴标题
        yTitle,     // Y轴标题
        dataset,     // 绘图数据集
        PlotOrientation.VERTICAL,     // 柱形图绘制方向
        True,     // 显示图例
        True,     // 显示图例名称
        False     // 生成链接
        );

下面开始自定义绘图属性,没有下面的代码,同样可以得到漂亮的3D效果的柱形图。

为图片添加副标题,代码如下:

chart.addSubtitle(new TextTitle(subtitle));

将图片的背景色设置为渐变效果,代码如下:

GradientPaint chartGP = new GradientPaint(0, 0,
        new Color(219, 227, 251), 0, height, Color.WHITE, False);     // 创建渐变色对象
chart.setBackgroundPaint(chartGP);     // 设置图片背景色
通过JFreeChart实例的getCategoryPlot()方法获得CategoryPlot类的实例,目的是设置绘图区的绘图属性,代码如下:
CategoryPlot plot = chart.getCategoryPlot();

设置绘图区的相关绘图属性,代码如下:

plot.setBackgroundPaint(new Color(241, 219, 127));     // 设置绘图区背景色
plot.setRangeGridlinePaint(Color.RED);     // 设置水平方向背景线颜色
plot.setRangeGridlinesVisible(True);     // 设置是否显示水平方向背景线,默认值为True
plot.setDomainGridlinePaint(Color.RED);     // 设置垂直方向背景线颜色
plot.setDomainGridlinesVisible(True);     // 设置是否显示垂直方向背景线,默认值为False

通过CategoryPlot实例的getRenderer()方法获得BarRenderer类的实例,目的是设置柱形的绘制属性,代码如下:

BarRenderer renderer = (BarRenderer) plot.getRenderer();

在这里不绘制柱形的轮廓线,JFreeChart默认为绘制,代码如下:

renderer.setDrawBarOutline(False);

下面设置柱形的填充颜色,同样采用渐变效果,代码如下:

Color color[] = new Color[cutline.length];
color[0] = new Color(99, 99, 0);
color[1] = new Color(255, 169, 66);
color[2] = new Color(33, 255, 66);
for (int i = 0; i < color.length; i++) {
    GradientPaint gp = new GradientPaint(0, 0, color[i].brighter(), 0,
             height, color[i].darker());
    renderer.setSeriesPaint(i, gp);
}

下面通过CategoryPlot实例的getDomainAxis()方法获得CategoryAxis类的实例,目的是设置统计种类轴标题(X轴)的绘制属性,在这里设置为倾斜45°输出,代码如下:

CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);

本示例中就定义了上述的这些绘图属性,读者可以尝试着定义其他属性。下面的代码是利用JFreeChart绘制图片时必须用到的,记住就可以了:

ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());

通过ServletUtilities类的saveChartAsPNG()方法生成PNG格式的图片,并返回图片的名称,如果想生成JPG格式的图片,可以通过ServletUtilities类的saveChartAsJPEG()方法,代码如下:

String fileName = "";
try {
    fileName = ServletUtilities.saveChartAsPNG(chart, width, height, info, session);
} catch (IOException e) {}

下面的代码是在组织图片的浏览路径,供显示到JSP页面时使用:

String graphURL = contextPath + servletURI + "?filename=" + fileName;

14.2.2 利用XYDataset数据集绘制柱形图

利用实现XYDataset接口的数据集,也可以绘制柱形图,XYDataset数据集主要用来绘制与日期相关的统计图。

在封装数据集时,首先需要通过TimeSeries类的实例进行封装,TimeSeries类提供了3个构造函数,在这里我们采用入口参数最多的一个,代码如下:

TimeSeries timeSeries = new TimeSeries(chartTitle, xTitle, yTitle, Month.class);

入口参数依次为图表标题、日期轴标题、数据轴标题和统计种类,第二个和第三个入口参数可以为空,第四个入口参数的可选类型如下。

l     Year.class,按年统计。

l     Month.class,按月统计。

l     Day.class,按日统计。

l     Hour.class,按小时统计。

l     Minute.class,按分统计。

l     Second.class,按秒统计。

l     Millisecond.class,按毫秒统计。

l     Quarter.class,按一刻钟统计。

l     Week.class,按周统计。

l     FixedMillisecond.class,按指定时间段统计。

通过TimeSeries实例的add()方法向TimeSeries实例中添加统计数据,添加完成后以TimeSeries实例为入口参数创建一个TimeSeriesCollection类的实例,并将TimeSeriesCollection实例直接传给IntervalXYDataset类的实例,代码如下:

TimeSeriesCollection tsc = new TimeSeriesCollection(timeSeries);

IntervalXYDataset dataset = tsc;

    说明:类TimeSeriesCollection和类IntervalXYDataset均为XYDataset接口的实现类。

在创建JFreeChart类的实例时,需要通过工厂类ChartFactory的createXYBarChart方法,createXYBarChart方法与14.2.1节使用的createBarChart3D()方法类似,请对照学习。

 示例14-02 利用XYDataset数据集绘制与日期相关的柱形图

下面来看一个利用XYDataset数据集绘制柱形图的例子,该例绘制的柱形图效果如图14.3所示。

图14.3 利用XYDataset数据集绘制与日期相关的柱形图

代码14-02 光盘位置:光盘\mingrisoft\14\sl\02

在本示例中可以在前台向后台传入Map集合,Map集合元素的键为日期、值为统计值,本示例中用来创建数据集的代码如下:

Map data = new HashMap();     // 创建绘图数据集
for (int i = 1; i < 13; i++) {     // 为绘图数据集赋值
    data.put(i, 1 + Math.random() * 100);
}
TimeSeries timeSeries = new TimeSeries(chartTitle, xTitle, yTitle, Month.class);
Iterator it = data.keySet().iterator();
while (it.hasNext()) {
    int key = (Integer) it.next();
    timeSeries.add(new Month(key, new Year(2008)), (Double) data .get(key));
}
TimeSeriesCollection tsc = new TimeSeriesCollection(timeSeries);
IntervalXYDataset dataset = tsc;

本示例中用来创建JFreeChart实例的代码如下:

JFreeChart chart = ChartFactory.createXYBarChart(chartTitle, xTitle,
       True, yTitle, dataset, PlotOrientation.VERTICAL, False, False, False);