在web页面上显示(绘制)图形

用servlet显示图形:
我先简单的说一下思路,采用servlet绘图。首先生成一个继承自Jframe类的一个frame类(DrawFrame),在这个类当中实现绘制具体图形的函数paint(Graphs2D g),这里主要是应用awt, 和 swing当中的关于绘图的一些函数。代码如下:

public class DrawFrame extends JFrame {



public void paint(Graphics g){

// cast to a Graphics2D object and get size

Graphics2D g2 = (Graphics2D) g;

Dimension dim = this.getSize();



// make sure to fill in the background color

g2.setColor(Color.white);

g2.fillRect(0,0,dim.width,dim.height);



g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);



// draw the x and y axis

g2.setPaint(Color.black);

g2.setStroke(new BasicStroke(2.0f));

g2.draw(new Line2D.Double(40,40, 40,dim.height-60));

g2.draw(new Line2D.Double(40,dim.height-60,

dim.width-40,dim.height-60));

g2.draw(new Line2D.Double(40,40,dim.width-40,40));

g2.draw(new Line2D.Double(dim.width-40,40,dim.width-40,dim.height-60));



g2.setPaint(Color.red);

Font font = g2.getFont().deriveFont(15.0f);

g2.setFont(font);

FontMetrics fm = g2.getFontMetrics();

String string = "welcome friends.";

String str = "this is a svg got from a servlet";

g2.drawString(string,dim.width/2-fm.stringWidth(string)/2-40,80);

g2.drawString(str,dim.width/2-fm.stringWidth(str)/2-40,120);

g2.setStroke(new BasicStroke(20.0f));

g2.setPaint(Color.blue);

g2.draw(new Line2D.Double(dim.width/2-40,dim.height/2-60,dim.width/2+60,dim.height/2+40));

g2.draw3DRect(dim.width/2-40,dim.height/2-60,100,100,true);

}

然后生成一个servlet,在servlet的doget(。。)方法中生成一个frame的对象,此后的问题就是如何将所画的图形转化成能够在web页面上显示的形式,这里我介绍两种方式,一种是通过org.apache.batik.util.awt.svg.SVGGraphics2D,这个类将所拥有的图形frame重新绘制到SVGGraphics2D上,doget(..)代码如下:

ServletOutputStream out = response.getOutputStream();

ServletContext context = this.getServletConfig().getServletContext();



try {

response.setContentType("image/svg+xml");

DrawFrame df = new DrawFrame();

df.setSize(new Dimension(WIDTH, HEIGHT));

// BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);



// create the SVGGraphics2D object, remember to set the size!

Document svgDoc = new DocumentImpl();

SVGGraphics2D g2 = new SVGGraphics2D(svgDoc);

g2.setSVGCanvasSize(df.getSize());



// draw the graph onto the image

df.paint(g2);



Writer writer = new java.io.StringWriter();

g2.stream(writer, false);

out.print(writer.toString());

out.flush();

} catch (Exception e) {

e.printStackTrace();

}

另一种方法是直接将farme 绘制到普通的Graphs2D上,然后通过一个sun公司的com.sun.image.codec.jpeg.JPEGImageEncoder将其转化成jpg格式,然后在网页当中就可以直接用了,代码如下:

……

response.setContentType("image/jpeg");

……

BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);

Graphics2D g2 = image.createGraphics();



// draw the graph onto the image

df.paint(g2);



// encode the output back to the client

JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

encoder.encode(image);

out.flush();

注意这两段代码的开始,都要设置一下显示的格式

response.setContentType("image/svg+xml");

response.setContentType("image/svg+xml");

上面是用servlet显示(绘制)图形,下面是对Jfreechart的介绍

Jfreechart
Jfreechart的思路也是先生成某种chart,然后将此chart转化成某种网页可以显示的格式(jpeg,png)保存到一个临时目录(用到session),最后通过一个servlet将图形显示到页面上。

Jfreechart 简述
Jfreechart是一个开源的类库,目的是生成各种各样的图标,具体能生成的图表如下:

1. pie charts (2D and 3D);

2. bar charts (regular and stacked, with an optional 3D effect);

3. line and area charts;

4. scatter plots and bubble charts;

5. time series, high/low/open/close charts and candle stick charts;

6. combination charts;

7. Pareto charts;

8. Gantt charts;

9. wind plots, meter charts and symbol charts;

10. wafer map charts;

此外,Jfreechart还支持多座标轴与多数据集,能够实现在图上给出点提示,进行放大缩小、打印操作,重要的是Jfreechart生成的图还支持交互,它集成了flash与pdf的优点,舍弃了两者的缺点,并且随着网络应用的发展,开发者们势必对此更加的重视,它比一般意义上的报表工具更加好用,而且功能更加强大

Jfreechart类库结构的简单描述
Jfreechart下边有两个包,一个是org.jfree.chart, 另一个是org.jfree.data,从两个包的名字上面就能看得出,chart包主要包含的是作图时的一些类,而data包包含的是与作图有关的数据的类。下边是用javadoc命令生成的doc结构描述,从中我们能够大概的了解类包的用途。

org.jfree.chart
Core classes, including JFreeChart and ChartPanel.

org.jfree.chart.annotations
A framework for addings annotations to charts.

org.jfree.chart.axis
Axis classes and interfaces.

org.jfree.chart.encoders
Classes related to the encoding of charts to different image formats.

org.jfree.chart.entity
Classes representing components of (or entities in) a chart.

org.jfree.chart.event
Event classes and listener interfaces, used to provide a change notification mechanism so that charts are automatically redrawn whenever changes are made to any chart component.

org.jfree.chart.imagemap
Classes for image maps.

org.jfree.chart.labels
Generators and other classes used for the display of item labels and tooltips.

org.jfree.chart.needle
A range of objects that can be used to represent the needle on a CompassPlot.

org.jfree.chart.plot
Plot classes and related interfaces.

org.jfree.chart.renderer
Plug-in renderers for the CategoryPlot and XYPlot classes.

org.jfree.chart.renderer.category


org.jfree.chart.renderer.xy


org.jfree.chart.resources
Localised resources for the JFreeChart class library.

org.jfree.chart.servlet
Classes for providing useful servlet and JSP functionality.

org.jfree.chart.title
Classes used to display chart titles and subtitles.

org.jfree.chart.ui
An optional package containing user interface components for editing chart properties (used in the JFreeChart demo application);

org.jfree.chart.urls
Classes for adding URLS to charts for HTML image map generation.

org.jfree.data
The base package for classes that represent various types of data.

org.jfree.data.category
A package containing the CategoryDataset interface and related classes.

org.jfree.data.contour


org.jfree.data.function


org.jfree.data.gantt
Data interfaces and classes for Gantt charts.

org.jfree.data.general
Data interfaces and classes.

org.jfree.data.io


org.jfree.data.jdbc


org.jfree.data.resources
Resource bundles for items that require localisation.

org.jfree.data.statistics
Classes for representing statistical data.

org.jfree.data.time
Interfaces and classes for time-related data.

org.jfree.data.xml
Support for reading datasets from XML files.

org.jfree.data.xy
A package containing the XYDataset interface and related classes.


Jfreechart的具体应用
1. 开发环境的搭建

a) 下载jfreechart-0.9.21.zip, 解压缩到某个目录,将里边的jfreechart-0.9.21.jar和Lib目录下的jcommon.jar拷贝到所用开发应用目录WEB-INF/lib下边(如果您的开发环境当中没有servlet.jar包的话,请将这个包也拷贝到上面的目录中。

b) 在/WEB-INF/web.xml文件中增加以下内容。



DisplayChart

org.jfree.chart.servlet.DisplayChart





DisplayChart

/servlet/DisplayChart





2. 开发过程的简单介绍(可以直接在jsp文件中编码,也可以写成javabean然后在jsp当中调用)

a) 简述:首先通过某种方式(数据库,xml,数学运算)得到数据,然后应用得到的数据(还有一些相关的元素,如座标轴,着色属性等)生成一个plot(根据你要生成的图表样式,应用相应的**plot),then根据得到的plot生成一个Jfreechart对象,设置对象属性,然后将得到的对象转化成某种图形格式保存到某一目录,最后将图形送到输出变量当中输出到页面

b) 下面是jfreechart-sample当中的一段程序,很容易验证上面的思路(在这个sample中一共给出了四种图表的简单例子程序,其他的如果用得到的话需要我们通过已有的和类包描述慢慢摸索)

public static String generateXYAreaChart(HttpSession session, PrintWriter pw) {

String filename = null;

try {

// Retrieve list of WebHits for each section and populate a TableXYDataset

WebHitDataSet whDataSet = new WebHitDataSet();

ArrayList sections = whDataSet.getSections();

Iterator sectionIter = sections.iterator();

DefaultTableXYDataset dataset = new DefaultTableXYDataset();

while (sectionIter.hasNext()) {

String section = (String)sectionIter.next();

ArrayList list = whDataSet.getDataByHitDate(section);

XYSeries dataSeries = new XYSeries(section, true, false);

Iterator webHitIter = list.iterator();

while (webHitIter.hasNext()) {

WebHit webHit = (WebHit)webHitIter.next();

dataSeries.add(webHit.getHitDate().getTime(), webHit.getHitCount());

}

dataset.addSeries(dataSeries);

}



// Throw a custom NoDataException if there is no data

if (dataset.getItemCount() == 0) {

System.out.println("No data has been found");

throw new NoDataException();

}



// Create tooltip and URL generators

SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", Locale.UK);

StandardXYToolTipGenerator ttg = new StandardXYToolTipGenerator(

StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,

sdf, NumberFormat.getInstance());

TimeSeriesURLGenerator urlg = new TimeSeriesURLGenerator(

sdf, "bar_chart.jsp", "series", "hitDate");



// Create the X-Axis

DateAxis xAxis = new DateAxis(null);

xAxis.setLowerMargin(0.0);

xAxis.setUpperMargin(0.0);



// Create the X-Axis

NumberAxis yAxis = new NumberAxis(null);

yAxis.setAutoRangeIncludesZero(true);



// Create the renderer

StackedXYAreaRenderer renderer =

new StackedXYAreaRenderer(XYAreaRenderer.AREA_AND_SHAPES, ttg, urlg);

renderer.setSeriesPaint(0, new Color(255, 255, 180));

renderer.setSeriesPaint(1, new Color(206, 230, 255));

renderer.setSeriesPaint(2, new Color(255, 230, 230));

renderer.setSeriesPaint(3, new Color(206, 255, 206));

renderer.setShapePaint(Color.gray);

renderer.setShapeStroke(new BasicStroke(0.5f));

renderer.setShape(new Ellipse2D.Double(-3, -3, 6, 6));

renderer.setOutline(true);



// Create the plot

XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer);

plot.setForegroundAlpha(0.65f);



// Reconfigure Y-Axis so the auto-range knows that the data is stacked

yAxis.configure();



// Create the chart

JFreeChart chart = new JFreeChart(null, JFreeChart.DEFAULT_TITLE_FONT, plot, true);

chart.setBackgroundPaint(java.awt.Color.white);



// Write the chart image to the temporary directory

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

filename = ServletUtilities.saveChartAsPNG(chart, 500, 300, info, session);



// Write the image map to the PrintWriter

ChartUtilities.writeImageMap(pw, filename, info);

pw.flush();





} catch (NoDataException e) {

System.out.println(e.toString());

filename = "public_nodata_500x300.png";

} catch (Exception e) {

System.out.println("Exception - " + e.toString());

e.printStackTrace(System.out);

filename = "public_error_500x300.png";

}

return filename;

}

得到文件名之后就可以在页面中显示了。

上面的例子中都带了注释,相对容易理解,时间的原因就不多解释了

3. 常用类(包)的介绍。。

数据集:Dataset: DefaultCategoryDataset, DefaultContourDataset, DefaultPieDataset, DefaultValueDataset, WaferMapDataset, DefaultTableXYDataset, DefaultOHLCDataset, XYSeriesCollection, XYBarDataset. 这里边都是我们常用的dataset。其中DefaultPieDataset是饼图数据集,DefaultTableXYDataset是二维坐标数据集等,需要我们应用时根据实际情况选择相应的数据集。

ToolTipGenerator(提示):StandardCategoryToolTipGenerator, StandardContourToolTipGenerator, StandardXYLabelGenerator, StandardXYToolTipGenerator, StandardXYZToolTipGenerator等,这些都是继承自org.jfree.chart.labels,在这个类当中还有关于一些标签的类HighLowItemLabelGenerator, IntervalCategoryLabelGenerator, StandardCategoryLabelGenerator, StandardPieItemLabelGenerator, StandardXYLabelGenerator, 在使用时应注意构造函数的参数。不同的类对应的是不同的参数。

Urls:这个类是用来在图表中应用超链接的StandardCategoryURLGenerator, StandardPieURLGenerator, StandardXYURLGenerator, StandardXYZURLGenerator, TimeSeriesURLGenerator.

Axis: 这个类是用来生成图表的坐标的。CategoryAxis, DateAxis, LogarithmicAxis, NumberAxis, PeriodAxis, SubCategoryAxis, ValueAxis.

Render: 这个类是应用到生成plot时的,它定义了图表的渲染模式。AreaRenderer, , CategoryStepRenderer, GanttRenderer, StackedAreaRenderer, StackedBarRenderer, StackedXYBarRenderer, XYBarRenderer, XYAreaRenderer等。注意,有些特定plot可以应用不同的render对象渲染。

Plot:这是在讲图表放到框图当中时需要的表元素,应用时要根据要得到的图利用相应的plot。

JFreeChart:这个类将生成的plot装到一个chart当中,应用时要注意构造函数。

A chart class implemented using the Java 2D APIs. The current version supports bar charts, line charts, pie charts and xy plots (including time series data).

JFreeChart coordinates several objects to achieve its aim of being able to draw a chart on a Java 2D graphics device: a list of Title objects, a Legend, a Plot and a Dataset (the plot in turn manages a horizontal axis and a vertical axis). 注意生成freechart实例以后还要设置相应的属性。

此外还有一些非常有用的类:,比如ChartFactory, ChartUtilities, Legend(StandardLegend), org.jfree.chart.servlet(ServletUtilities.saveChartAsPNG), org.jfree.chart.titleorg.jfree.chart.ui等不可缺少的元素类

你可能感兴趣的:(转载)