package com.taobao.top.analysis.util; import java.awt.Color; import java.awt.Font; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.List; import java.util.Map; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.labels.StandardPieSectionLabelGenerator; import org.jfree.chart.plot.PiePlot3D; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.title.TextTitle; import org.jfree.data.category.CategoryDataset; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.general.DefaultPieDataset; import org.jfree.data.general.PieDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; /** * 绘图工具类 * @author sihai * */ public class ChartUtil { /** * 绘制饼图 * @param name * @param outputFileName * @param data */ public static void drawPie(String name, String outputFileName, List<Entry> data) { PieDataset dataset = makePieDataSet(data); JFreeChart chart = ChartFactory.createPieChart3D(name, dataset, true, true, false); PiePlot3D plot = (PiePlot3D)chart.getPlot(); // 图片中显示百分比:默认方式 //plot.setLabelGenerator(new StandardPieSectionLabelGenerator(StandardPieToolTipGenerator.DEFAULT_TOOLTIP_FORMAT)); // 图片中显示百分比:自定义方式,{0} 表示选项, {1} 表示数值, {2} 表示所占比例 ,小数点后两位 plot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}={1}({2})", NumberFormat.getNumberInstance(), new DecimalFormat("0.00%"))); // 图例显示百分比:自定义方式, {0} 表示选项, {1} 表示数值, {2} 表示所占比例 plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator("{0}={1}({2})")); // 设置背景色为白色 chart.setBackgroundPaint(Color.white); // 指定图片的透明度(0.0-1.0) plot.setForegroundAlpha(1.0f); // 指定显示的饼图上圆形(false)还椭圆形(true) plot.setCircular(true); // 设置图标题的字体 Font font = new Font("黑体",Font.CENTER_BASELINE,20); TextTitle title = new TextTitle(name); title.setFont(font); chart.setTitle(title); FileOutputStream output = null; try { output = new FileOutputStream(outputFileName); ChartUtilities.writeChartAsJPEG(output, 100, chart, 640, 480, null); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } finally { if(output != null) { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 绘制柱状图 * @param name * @param xName * @param yName * @param outputFileName * @param data */ public static void drawBar(String name, String xName, String yName, String outputFileName, List<Entry> data) { JFreeChart chart = ChartFactory.createBarChart(name, // 图表标题 xName, // 目录轴的显示标签 yName, // 数值轴的显示标签 makeCategoryDataset(data), // 数据集 PlotOrientation.VERTICAL, // 图表方向:水平、垂直 true, // 是否显示图例(对于简单的柱状图必须是false) false, // 是否生成工具 false // 是否生成URL链接 ); /*chart.getTitle().setFont((new Font("宋体", Font.CENTER_BASELINE, 20))); chart.getLegend().setItemFont(new Font("宋体", Font.CENTER_BASELINE, 15)); Font labelFont = new Font("SansSerif", Font.TRUETYPE_FONT, 12); chart.setAntiAlias(false); chart.setBackgroundPaint(Color.WHITE); // create plot CategoryPlot plot = chart.getCategoryPlot(); // 设置横虚线可见 plot.setRangeGridlinesVisible(true); // 虚线色彩 plot.setRangeGridlinePaint(Color.gray); // 设置柱图背景色(注意,系统取色的时候要使用16位的模式来查看颜色编码,这样比较准确) plot.setBackgroundPaint(new Color(160, 160, 255)); // 数据轴精度 NumberAxis vn = (NumberAxis) plot.getRangeAxis(); // vn.setAutoRangeIncludesZero(true); DecimalFormat df = new DecimalFormat("#0.00"); vn.setNumberFormatOverride(df); // 数据轴数据标签的显示格式 // x轴设置 CategoryAxis domainAxis = plot.getDomainAxis(); domainAxis.setLabelFont(labelFont);// 轴标题 domainAxis.setTickLabelFont(labelFont);// 轴数值 // Lable(Math.PI/3.0)X轴文字的倾斜度 domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 5.0)); domainAxis.setMaximumCategoryLabelWidthRatio(0.6f);// 横轴上的 Lable 是否完整显示 // 设置距离图片左端距离 domainAxis.setLowerMargin(0.1); // 设置距离图片右端距离 domainAxis.setUpperMargin(0.1); plot.setDomainAxis(domainAxis); // y轴设置 ValueAxis rangeAxis = plot.getRangeAxis(); rangeAxis.setLabelFont(labelFont); rangeAxis.setTickLabelFont(labelFont); // 设置最高的一个 Item 与图片顶端的距离 rangeAxis.setUpperMargin(0.15); // 设置最低的一个 Item 与图片底端的距离 rangeAxis.setLowerMargin(0.15); plot.setRangeAxis(rangeAxis); BarRenderer renderer = new BarRenderer(); // 设置柱子宽度 renderer.setMaximumBarWidth(0.05); // 设置柱子高度 renderer.setMinimumBarLength(0.2); // 设置柱子边框颜色 renderer.setBaseOutlinePaint(Color.BLACK); // 设置柱子边框可见 renderer.setDrawBarOutline(true); // // 设置柱的颜色 // renderer.setSeriesPaint(0, new Color(204, 255, 255)); // renderer.setSeriesPaint(1, new Color(153, 204, 255)); // renderer.setSeriesPaint(2, new Color(51, 204, 204)); // 设置每个地区所包含的平行柱的之间距离 renderer.setItemMargin(0.0); // 显示每个柱的数值,并修改该数值的字体属性 renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); renderer.setBaseItemLabelsVisible(true); plot.setRenderer(renderer); // 设置柱的透明度 plot.setForegroundAlpha(1.0f);*/ FileOutputStream output = null; try { output = new FileOutputStream(outputFileName); ChartUtilities.writeChartAsJPEG(output, 100, chart, 1024, 800, null); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } finally { if(output != null) { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 绘制折线图 * @param name * @param xName * @param yName * @param outputFileName * @param multiLineData */ public static void drawLine(String name, String xName, String yName, String outputFileName, Map<String, List<LineEntry>> multiLineData) { XYSeriesCollection seriesCollection = new XYSeriesCollection(); for(Map.Entry<String, List<LineEntry>> line : multiLineData.entrySet()) { XYSeries series = new XYSeries(line.getKey()); for(LineEntry entry : line.getValue()) { series.add(entry.x, entry.y); } seriesCollection.addSeries(series); } JFreeChart chart = ChartFactory.createXYLineChart(name, xName, yName, seriesCollection, PlotOrientation.VERTICAL, true, true, false); FileOutputStream output = null; try { output = new FileOutputStream(outputFileName); ChartUtilities.writeChartAsJPEG(output, 100, chart, 1024, 800, null); } catch (FileNotFoundException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } finally { if(output != null) { try { output.close(); } catch (IOException e) { e.printStackTrace(); } } } } private static PieDataset makePieDataSet(List<Entry> data) { DefaultPieDataset dataset = new DefaultPieDataset(); for(Entry entry : data) { dataset.setValue(entry.key, entry.value); } return dataset; } private static CategoryDataset makeCategoryDataset(List<Entry> data) { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); for(Entry entry : data) { dataset.setValue(entry.value, "", entry.key); } return dataset; } /** * * @author sihai * */ public static class Entry { public String key; public Number value; public Entry(String key, Number value) { this.key = key; this.value = value; } } /** * * @author sihai * */ public static class LineEntry { public Number x; public Number y; public LineEntry(Number x, Number y) { this.x = x; this.y = y; } } }