jfreechart简单组合图形
jfreechart简单组合图形,柱状图,折线图,下标的处理,后面的图形被前面的给盖住了.
原始需求
接到一个图表的需求,类似下面这样的
很明显,这是一个组合图形,由于系统用的是java,就选了jfreechart来处理,下面是代码.
最终效果
关键代码说明
jfreeChart对象有 categoryplot (只有一个?)
categoryplot 里面有render(多个就是组合图形了)
如果是组合图形,CategoryPlot 大有所用(请去看其api) 下面三个处理,都是从这个类找到的api
render(渲染,这里就是对折线图,XX图的描述了,不同的图不同render,比如 BarRenderer代表柱状图,LineAndShapeRenderer是折线图)
AXIS代表坐标轴,
demo关键代码说明
// 怎么对render排序 , 折线图 不被 盖住就像html中的z-index
//写个标题
//当遇到下面这样的横坐标
代码
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