jfreechart简单组合图形

jopen 9年前

jfreechart简单组合图形,柱状图,折线图,下标的处理,后面的图形被前面的给盖住了.

原始需求

接到一个图表的需求,类似下面这样的

jfreechart简单组合图形

很明显,这是一个组合图形,由于系统用的是java,就选了jfreechart来处理,下面是代码.



最终效果

jfreechart简单组合图形




关键代码说明

jfreeChart对象有 categoryplot (只有一个?)

categoryplot 里面有render(多个就是组合图形了)


如果是组合图形,CategoryPlot 大有所用(请去看其api)  下面三个处理,都是从这个类找到的api

render(渲染,这里就是对折线图,XX图的描述了,不同的图不同render,比如 BarRenderer代表柱状图,LineAndShapeRenderer是折线图)


AXIS代表坐标轴,



demo关键代码说明

// 怎么对render排序 , 折线图 不被 盖住就像html中的z-index
categoryplot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);//如果注掉这行,那个折线图,就被柱状图给盖上了
</div>


//写个标题

 CategoryAxis c1 = new CategoryAxis("hello");
  CategoryAxis c2 = new CategoryAxis("单位(M)");
  CategoryAxis[] cc = {c1,c2};
  categoryplot.setDomainAxes(cc);//貌似是标题


//当遇到下面这样的横坐标

jfreechart简单组合图形

     List<Integer> axisIndices = new java.util.ArrayList<Integer>(1);
        axisIndices.add(1);
  categoryplot.mapDatasetToDomainAxes(1, axisIndices);//这个,没搞懂,不过可以成为上面那样了,如果注掉这行,会显示成下面那样



代码


main函数

package org.dgm.test.theme.chart;    import java.awt.Font;  import java.io.IOException;  import java.util.List;    import org.dgm.test.util.TestUtils;  import org.jfree.chart.ChartFactory;  import org.jfree.chart.JFreeChart;  import org.jfree.chart.StandardChartTheme;  import org.jfree.chart.axis.CategoryAxis;  import org.jfree.chart.labels.ItemLabelAnchor;  import org.jfree.chart.labels.ItemLabelPosition;  import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;  import org.jfree.chart.labels.StandardCategoryToolTipGenerator;  import org.jfree.chart.plot.CategoryPlot;  import org.jfree.chart.plot.DatasetRenderingOrder;  import org.jfree.chart.plot.PlotOrientation;  import org.jfree.chart.renderer.category.BarRenderer;  import org.jfree.chart.renderer.category.LineAndShapeRenderer;  import org.jfree.data.category.DefaultCategoryDataset;  import org.jfree.ui.TextAnchor;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;      public class CombineChart {      static Logger log = LoggerFactory.getLogger(CombineChart.class);     public static void main(String[] args) throws IOException {    DefaultCategoryDataset dataset1 = new DefaultCategoryDataset();    dataset1.addValue(200, "1", "上上周");    dataset1.addValue(300, "1", "上周");    dataset1.addValue(400, "1", "这周");            DefaultCategoryDataset lineDataset = new DefaultCategoryDataset();// 折线图数据    lineDataset.addValue(50, "1", "    ");    lineDataset.addValue(30, "1", "");    lineDataset.addValue(45, "1", "  ");        String title = "";    String categoryAxisLabel = "";    String valueAxisLabel = "";    log.info(createFeePieChart( dataset1, 420, 300,      title, categoryAxisLabel, valueAxisLabel, lineDataset));       }      private static String createFeePieChart(     DefaultCategoryDataset dataset, int nWidth, int nHeight,     String title, String categoryAxisLabel, String valueAxisLabel,     DefaultCategoryDataset lineDataset) throws      IOException {      JFreeChart chart = ChartFactory.createBarChart(title,      categoryAxisLabel, valueAxisLabel, dataset,      PlotOrientation.VERTICAL, false, false, false);      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);      CategoryPlot plot = (CategoryPlot) chart.getCategoryPlot();    BarRenderer renderer = (BarRenderer) plot.getRenderer();    // 显示条目标签    renderer.setBaseItemLabelsVisible(true);    // 设置条目标签生成器,在JFreeChart1.0.6之前可以通过renderer.setItemLabelGenerator(CategoryItemLabelGenerator    // generator)方法实现,但是从版本1.0.6开始有下面方法代替    renderer      .setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());  //  renderer.setBaseSeriesVisible(false);    // 设置条目标签显示的位置,outline表示在条目区域外,baseline_center表示基于基线且居中    renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(      ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER));      // 折线图    CategoryPlot categoryplot = (CategoryPlot) chart.getPlot();// 图本身    categoryplot.setDataset(1, lineDataset);// 放折线图数据  //  BarRenderer lineRenderer = new BarRenderer();    LineAndShapeRenderer lineRenderer = new LineAndShapeRenderer();    lineRenderer      .setBaseToolTipGenerator(new StandardCategoryToolTipGenerator());    lineRenderer.setBaseItemLabelsVisible(true);    lineRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());    lineRenderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(      ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER));  //  categoryplot.getDomainAxis(0).setVisible(false);    categoryplot.setRenderer(1, lineRenderer);        log.info(categoryplot.getDomainAxisCount()+"");    CategoryAxis c1 = new CategoryAxis("柱状图");    CategoryAxis c2 = new CategoryAxis("");    CategoryAxis[] cc = {c1,c2};    categoryplot.setDomainAxes(cc);           List<Integer> axisIndices = new java.util.ArrayList<Integer>(1);          axisIndices.add(1);    categoryplot.mapDatasetToDomainAxes(1, axisIndices);        categoryplot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);        return TestUtils.export(chart,"d:/abc/cd/");   }          }




被引用到的java类

ExportUtils:


/* ===========================================================   * JFreeChart : a free chart library for the Java(tm) platform   * ===========================================================   *   * (C) Copyright 2000-2014, by Object Refinery Limited and Contributors.   *   * Project Info:  http://www.jfree.org/jfreechart/index.html   *   * This library is free software; you can redistribute it and/or modify it   * under the terms of the GNU Lesser General Public License as published by   * the Free Software Foundation; either version 2.1 of the License, or   * (at your option) any later version.   *   * This library is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY   * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public   * License for more details.   *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,   * USA.   *   * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.    * Other names may be trademarks of their respective owners.]   *   * ----------------   * ExportUtils.java   * ----------------   * (C) Copyright 2014, by Object Refinery Limited and Contributors.   *   * Original Author:  David Gilbert (for Object Refinery Limited);   * Contributor(s):   -;   *   * Changes:   * --------   * 27-Jun-2014 : Version 1 (DG);   *   */    package org.dgm.test.util;    import java.awt.Graphics2D;  import java.awt.Rectangle;  import java.awt.geom.Rectangle2D;  import java.awt.image.BufferedImage;  import java.io.BufferedOutputStream;  import java.io.File;  import java.io.FileNotFoundException;  import java.io.FileOutputStream;  import java.io.IOException;  import java.io.OutputStream;  import java.lang.reflect.Constructor;  import java.lang.reflect.InvocationTargetException;  import java.lang.reflect.Method;    import javax.imageio.ImageIO;    import org.jfree.chart.util.ParamChecks;  import org.jfree.ui.Drawable;    /**   * Utility functions for exporting charts to SVG and PDF format.   *    * @since 1.0.18   */  public class ExportUtils {        /**       * Returns <code>true</code> if JFreeSVG is on the classpath, and        * <code>false</code> otherwise.  The JFreeSVG library can be found at       * http://www.jfree.org/jfreesvg/       *        * @return A boolean.       */      public static boolean isJFreeSVGAvailable() {          Class<?> svgClass = null;          try {              svgClass = Class.forName("org.jfree.graphics2d.svg.SVGGraphics2D");          } catch (ClassNotFoundException e) {              // svgClass will be null so the function will return false          }          return (svgClass != null);      }        /**       * Returns <code>true</code> if OrsonPDF is on the classpath, and        * <code>false</code> otherwise.  The OrsonPDF library can be found at       * http://www.object-refinery.com/pdf/       *        * @return A boolean.       */      public static boolean isOrsonPDFAvailable() {          Class<?> pdfDocumentClass = null;          try {              pdfDocumentClass = Class.forName("com.orsonpdf.PDFDocument");          } catch (ClassNotFoundException e) {              // pdfDocument class will be null so the function will return false          }          return (pdfDocumentClass != null);      }        /**       * Writes the current content to the specified file in SVG format.  This        * will only work when the JFreeSVG library is found on the classpath.       * Reflection is used to ensure there is no compile-time dependency on       * JFreeSVG.       *        * @param drawable  the drawable (<code>null</code> not permitted).       * @param w  the chart width.       * @param h  the chart height.       * @param file  the output file (<code>null</code> not permitted).       */      public static void writeAsSVG(Drawable drawable, int w, int h,               File file) {          if (!ExportUtils.isJFreeSVGAvailable()) {              throw new IllegalStateException(                      "JFreeSVG is not present on the classpath.");          }          ParamChecks.nullNotPermitted(drawable, "drawable");          ParamChecks.nullNotPermitted(file, "file");          try {              Class<?> svg2Class = Class.forName(                      "org.jfree.graphics2d.svg.SVGGraphics2D");              Constructor<?> c1 = svg2Class.getConstructor(int.class, int.class);              Graphics2D svg2 = (Graphics2D) c1.newInstance(w, h);              Rectangle2D drawArea = new Rectangle2D.Double(0, 0, w, h);              drawable.draw(svg2, drawArea);              Class<?> svgUtilsClass = Class.forName(                      "org.jfree.graphics2d.svg.SVGUtils");              Method m1 = svg2Class.getMethod("getSVGElement", (Class[]) null);              String element = (String) m1.invoke(svg2, (Object[]) null);              Method m2 = svgUtilsClass.getMethod("writeToSVG", File.class,                       String.class);              m2.invoke(svgUtilsClass, file, element);          } catch (ClassNotFoundException ex) {              throw new RuntimeException(ex);          } catch (InstantiationException ex) {              throw new RuntimeException(ex);          } catch (IllegalAccessException ex) {              throw new RuntimeException(ex);          } catch (NoSuchMethodException ex) {              throw new RuntimeException(ex);          } catch (SecurityException ex) {              throw new RuntimeException(ex);          } catch (IllegalArgumentException ex) {              throw new RuntimeException(ex);          } catch (InvocationTargetException ex) {              throw new RuntimeException(ex);          }      }        /**       * Writes a {@link Drawable} to the specified file in PDF format.  This        * will only work when the OrsonPDF library is found on the classpath.       * Reflection is used to ensure there is no compile-time dependency on       * OrsonPDF.       *        * @param drawable  the drawable (<code>null</code> not permitted).       * @param w  the chart width.       * @param h  the chart height.       * @param file  the output file (<code>null</code> not permitted).       */      public static final void writeAsPDF(Drawable drawable,               int w, int h, File file) {          if (!ExportUtils.isOrsonPDFAvailable()) {              throw new IllegalStateException(                      "OrsonPDF is not present on the classpath.");          }          ParamChecks.nullNotPermitted(drawable, "drawable");          ParamChecks.nullNotPermitted(file, "file");          try {              Class<?> pdfDocClass = Class.forName("com.orsonpdf.PDFDocument");              Object pdfDoc = pdfDocClass.newInstance();              Method m = pdfDocClass.getMethod("createPage", Rectangle2D.class);              Rectangle2D rect = new Rectangle(w, h);              Object page = m.invoke(pdfDoc, rect);              Method m2 = page.getClass().getMethod("getGraphics2D");              Graphics2D g2 = (Graphics2D) m2.invoke(page);              Rectangle2D drawArea = new Rectangle2D.Double(0, 0, w, h);              drawable.draw(g2, drawArea);              Method m3 = pdfDocClass.getMethod("writeToFile", File.class);              m3.invoke(pdfDoc, file);          } catch (ClassNotFoundException ex) {              throw new RuntimeException(ex);          } catch (InstantiationException ex) {              throw new RuntimeException(ex);          } catch (IllegalAccessException ex) {              throw new RuntimeException(ex);          } catch (NoSuchMethodException ex) {              throw new RuntimeException(ex);          } catch (SecurityException ex) {              throw new RuntimeException(ex);          } catch (IllegalArgumentException ex) {              throw new RuntimeException(ex);          } catch (InvocationTargetException ex) {              throw new RuntimeException(ex);          }      }            /**       * Writes the current content to the specified file in PNG format.       *        * @param drawable  the drawable (<code>null</code> not permitted).       * @param w  the chart width.       * @param h  the chart height.       * @param file  the output file (<code>null</code> not permitted).       *        * @throws FileNotFoundException if the file is not found.       * @throws IOException if there is an I/O problem.       */      public static void writeAsPNG(Drawable drawable, int w, int h,               File file) throws FileNotFoundException, IOException {          BufferedImage image = new BufferedImage(w, h,                   BufferedImage.TYPE_INT_ARGB);          Graphics2D g2 = image.createGraphics();          drawable.draw(g2, new Rectangle(w, h));          OutputStream out = new BufferedOutputStream(new FileOutputStream(file));          try {              ImageIO.write(image, "png", out);          }          finally {              out.close();          }      }        /**       * Writes the current content to the specified file in JPEG format.       *        * @param drawable  the drawable (<code>null</code> not permitted).       * @param w  the chart width.       * @param h  the chart height.       * @param file  the output file (<code>null</code> not permitted).       *        * @throws FileNotFoundException if the file is not found.       * @throws IOException if there is an I/O problem.       */      public static void writeAsJPEG(Drawable drawable, int w, int h,               File file) throws FileNotFoundException, IOException {          BufferedImage image = new BufferedImage(w, h,                   BufferedImage.TYPE_INT_RGB);          Graphics2D g2 = image.createGraphics();          drawable.draw(g2, new Rectangle(w, h));          OutputStream out = new BufferedOutputStream(new FileOutputStream(file));          try {              ImageIO.write(image, "jpg", out);          }          finally {              out.close();          }      }     }




TestUtils:


/* ===========================================================   * JFreeChart : a free chart library for the Java(tm) platform   * ===========================================================   *   * (C) Copyright 2000-2014, by Object Refinery Limited and Contributors.   *   * Project Info:  http://www.jfree.org/jfreechart/index.html   *   * This library is free software; you can redistribute it and/or modify it   * under the terms of the GNU Lesser General Public License as published by   * the Free Software Foundation; either version 2.1 of the License, or   * (at your option) any later version.   *   * This library is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY   * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public   * License for more details.   *   * You should have received a copy of the GNU Lesser General Public   * License along with this library; if not, write to the Free Software   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,   * USA.   *   * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.    * Other names may be trademarks of their respective owners.]   *   * --------------   * TestUtils.java   * --------------   * (C) Copyright 2007-2014, by Object Refinery Limited.   *   * Original Author:  David Gilbert (for Object Refinery Limited);   * Contributor(s):   -;   *   * Changes:   * --------   * 08-Jun-2007 : Version 1 (DG);   * 19-Mar-2014 : Renamed TestUtils (DG);   *    */    package org.dgm.test.util;    import java.io.ByteArrayInputStream;  import java.io.ByteArrayOutputStream;  import java.io.File;  import java.io.FileNotFoundException;  import java.io.IOException;  import java.io.ObjectInput;  import java.io.ObjectInputStream;  import java.io.ObjectOutput;  import java.io.ObjectOutputStream;  import java.io.Serializable;  import java.util.Collection;  import java.util.Date;  import java.util.Iterator;    import org.jfree.ui.Drawable;    /**   * Some utility methods for use by the testing code.   */  public class TestUtils {        /**       * Returns <code>true</code> if the collections contains any object that       * is an instance of the specified class, and <code>false</code> otherwise.       *       * @param collection  the collection.       * @param c  the class.       *       * @return A boolean.       */      public static boolean containsInstanceOf(Collection collection, Class c) {          Iterator iterator = collection.iterator();          while (iterator.hasNext()) {              Object obj = iterator.next();              if (obj != null && obj.getClass().equals(c)) {                  return true;              }          }          return false;      }        /**       * Returns an object that is the deserialised form of the supplied object.       * The original object is serialised to a byte array then deserialised       * and returned.       *        * @param original  the original object (<code>null</code> not permitted).       *        * @return A serialised and deserialised object.       */      public static <T extends Serializable> T serialised(T original) {          T result = null;          ByteArrayOutputStream buffer = new ByteArrayOutputStream();          ObjectOutput out;          try {              out = new ObjectOutputStream(buffer);              out.writeObject(original);              out.close();              ObjectInput in = new ObjectInputStream(                      new ByteArrayInputStream(buffer.toByteArray()));              result = (T) in.readObject();              in.close();          } catch (IOException e) {              throw new RuntimeException(e);          } catch (ClassNotFoundException e) {              throw new RuntimeException(e);          }          return result;      }                  /**       * 导出 到 path       * @param drawable       * @param path 如 "d:/abc/cd/"       */      public static String export(Drawable drawable,String path){       int width = 800;       int heigh = 520;       Date d = new Date();       String filename = path+d.getTime()+".png";       try {     ExportUtils.writeAsPNG(drawable, width, heigh,new File(filename));    } catch (FileNotFoundException e) {     // TODO Auto-generated catch block     e.printStackTrace();    } catch (IOException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }       return filename;             }          }



一些说明

用到的两个util类都是 从github 中的 demo下来的,作了一点点改动

https://github.com/huawumingguo/jfreechart-fse.git

依赖的版本:

<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.15</version> 
</dependency>

main函数有些log,呃, 这个自行屏蔽吧。其它依赖倒是没有了,

来自:http://my.oschina.net/u/110531/blog/371748