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

来源:互联网 发布:北京海量数据待遇 编辑:程序博客网 时间:2024/06/11 19:57

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

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转化成某种网页可以显示的格式(jpegpng)保存到一个临时目录(用到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生成的图还支持交互,它集成了flashpdf的优点,舍弃了两者的缺点,并且随着网络应用的发展,开发者们势必对此更加的重视,它比一般意义上的报表工具更加好用,而且功能更加强大

     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.jarLib目录下的jcommon.jar拷贝到所用开发应用目录WEB-INF/lib下边(如果您的开发环境当中没有servlet.jar包的话,请将这个包也拷贝到上面的目录中。

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

<servlet>

       <servlet-name>DisplayChart</servlet-name>

       <servlet-class>org.jfree.chart.servlet.DisplayChart</servlet-class>

       </servlet>

       <servlet-mapping>

        <servlet-name>DisplayChart</servlet-name>

        <url-pattern>/servlet/DisplayChart</url-pattern>

       </servlet-mapping>

</servlet>

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.servletServletUtilities.saveChartAsPNG, org.jfree.chart.titleorg.jfree.chart.ui等不可缺少的元素类

原创粉丝点击