ChartUtil.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. package com.ruoyi.common.utils.document;
  2. import org.jfree.chart.ChartFactory;
  3. import org.jfree.chart.JFreeChart;
  4. import org.jfree.chart.StandardChartTheme;
  5. import org.jfree.chart.axis.CategoryLabelPositions;
  6. import org.jfree.chart.axis.ValueAxis;
  7. import org.jfree.chart.block.BlockBorder;
  8. import org.jfree.chart.labels.ItemLabelAnchor;
  9. import org.jfree.chart.labels.ItemLabelPosition;
  10. import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
  11. import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
  12. import org.jfree.chart.plot.*;
  13. import org.jfree.chart.renderer.category.LineAndShapeRenderer;
  14. import org.jfree.chart.renderer.category.StandardBarPainter;
  15. import org.jfree.chart.renderer.xy.StandardXYBarPainter;
  16. import org.jfree.chart.ui.RectangleInsets;
  17. import org.jfree.chart.ui.TextAnchor;
  18. import org.jfree.data.category.DefaultCategoryDataset;
  19. import org.jfree.data.general.DefaultPieDataset;
  20. import java.awt.*;
  21. import java.io.File;
  22. import java.text.NumberFormat;
  23. import java.util.Iterator;
  24. import java.util.Map;
  25. import java.util.Map.Entry;
  26. import java.util.Set;
  27. public class ChartUtil {
  28. private static String NO_DATA_MSG = "暂无数据";
  29. private static Font FONT = new Font("宋体", Font.PLAIN, 20);
  30. public static Color[] CHART_COLORS = {
  31. new Color(31,129,188), new Color(92,92,97), new Color(144,237,125), new Color(255,188,117),
  32. new Color(153,158,255), new Color(255,117,153), new Color(253,236,109), new Color(128,133,232),
  33. new Color(158,90,102),new Color(255, 204, 102) };// 颜色
  34. static{
  35. setChartTheme();
  36. }
  37. /**
  38. * 中文主题样式 解决乱码
  39. */
  40. public static void setChartTheme() {
  41. // 设置中文主题样式 解决乱码
  42. StandardChartTheme chartTheme = new StandardChartTheme("CN");
  43. // 设置标题字体
  44. chartTheme.setExtraLargeFont(FONT);
  45. // 设置图例的字体
  46. chartTheme.setRegularFont(FONT);
  47. // 设置轴向的字体
  48. chartTheme.setLargeFont(FONT);
  49. chartTheme.setSmallFont(FONT);
  50. chartTheme.setTitlePaint(new Color(51, 51, 51));
  51. chartTheme.setSubtitlePaint(new Color(85, 85, 85));
  52. chartTheme.setLegendBackgroundPaint(Color.WHITE);// 设置标注
  53. chartTheme.setLegendItemPaint(Color.BLACK);//
  54. chartTheme.setChartBackgroundPaint(Color.WHITE);
  55. // 绘制颜色绘制颜色.轮廓供应商
  56. // paintSequence,outlinePaintSequence,strokeSequence,outlineStrokeSequence,shapeSequence
  57. Paint[] OUTLINE_PAINT_SEQUENCE = new Paint[] { Color.WHITE };
  58. // 绘制器颜色源
  59. DefaultDrawingSupplier drawingSupplier = new DefaultDrawingSupplier(CHART_COLORS, CHART_COLORS, OUTLINE_PAINT_SEQUENCE,
  60. DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
  61. DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE);
  62. chartTheme.setDrawingSupplier(drawingSupplier);
  63. chartTheme.setPlotBackgroundPaint(Color.WHITE);// 绘制区域
  64. chartTheme.setPlotOutlinePaint(Color.WHITE);// 绘制区域外边框
  65. chartTheme.setLabelLinkPaint(new Color(8, 55, 114));// 链接标签颜色
  66. chartTheme.setLabelLinkStyle(PieLabelLinkStyle.CUBIC_CURVE);
  67. chartTheme.setAxisOffset(new RectangleInsets(5, 12, 5, 12));
  68. chartTheme.setDomainGridlinePaint(new Color(192, 208, 224));// X坐标轴垂直网格颜色
  69. chartTheme.setRangeGridlinePaint(new Color(192, 192, 192));// Y坐标轴水平网格颜色
  70. chartTheme.setBaselinePaint(Color.WHITE);
  71. chartTheme.setCrosshairPaint(Color.BLUE);// 不确定含义
  72. chartTheme.setAxisLabelPaint(new Color(51, 51, 51));// 坐标轴标题文字颜色
  73. chartTheme.setTickLabelPaint(new Color(67, 67, 72));// 刻度数字
  74. chartTheme.setBarPainter(new StandardBarPainter());// 设置柱状图渲染
  75. chartTheme.setXYBarPainter(new StandardXYBarPainter());// XYBar 渲染
  76. chartTheme.setItemLabelPaint(Color.black);
  77. chartTheme.setThermometerPaint(Color.white);// 温度计
  78. ChartFactory.setChartTheme(chartTheme);
  79. }
  80. /**
  81. * 必须设置文本抗锯齿
  82. */
  83. public static void setAntiAlias(JFreeChart chart) {
  84. chart.setTextAntiAlias(false);
  85. }
  86. /**
  87. * 设置图例无边框,默认黑色边框
  88. */
  89. public static void setLegendEmptyBorder(JFreeChart chart) {
  90. chart.getLegend().setFrame(new BlockBorder(Color.WHITE));
  91. }
  92. /**
  93. * 提供静态方法:获取报表图形1:饼状图
  94. * @param title 标题
  95. * @param datas 数据
  96. * @param url 字体
  97. */
  98. public static void createPiePort(String title, Map<String,Double> datas, String url){
  99. try {
  100. // 如果不使用Font,中文将显示不出来
  101. DefaultPieDataset pds = new DefaultPieDataset();
  102. // 获取迭代器:
  103. Set<Entry<String, Double>> set = datas.entrySet();
  104. Iterator iterator=(Iterator) set.iterator();
  105. Entry entry=null;
  106. while(iterator.hasNext()){
  107. entry=(Entry) iterator.next();
  108. pds.setValue(entry.getKey().toString(),Double.parseDouble(entry.getValue().toString()));
  109. }
  110. /**
  111. * 生成一个饼图的图表
  112. * 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
  113. */
  114. JFreeChart chart = ChartFactory.createPieChart(title, pds, true, true, true);
  115. setPieRender((PiePlot) chart.getPlot());
  116. //将内存中的图片写到本地硬盘
  117. org.jfree.chart.ChartUtils.saveChartAsPNG(new File(url), chart,800,500);
  118. } catch (Exception e) {
  119. e.printStackTrace();
  120. }
  121. }
  122. /**
  123. * 提供静态方法:获取报表图形1:饼状图
  124. * @param title 标题
  125. * @param datas 数据
  126. * @param url 字体
  127. */
  128. public static void createBarPort(String title, Map<String,Double> datas, String url){
  129. try {
  130. // 如果不使用Font,中文将显示不出来
  131. DefaultCategoryDataset pds = new DefaultCategoryDataset();
  132. // 获取迭代器:
  133. Set<Entry<String, Double>> set = datas.entrySet();
  134. Iterator iterator=(Iterator) set.iterator();
  135. Entry entry=null;
  136. while(iterator.hasNext()){
  137. entry=(Entry) iterator.next();
  138. pds.setValue(Double.parseDouble(entry.getValue().toString()),entry.getKey().toString(),entry.getKey().toString());
  139. }
  140. /**
  141. * 生成一个饼图的图表
  142. * 分别是:显示图表的标题、需要提供对应图表的DateSet对象、是否显示图例、是否生成贴士以及是否生成URL链接
  143. */
  144. JFreeChart chart = ChartFactory.createBarChart(title,"分类","数量", pds, PlotOrientation.VERTICAL, true, true, false);
  145. //将内存中的图片写到本地硬盘
  146. org.jfree.chart.ChartUtils.saveChartAsPNG(new File(url), chart,800,500);
  147. } catch (Exception e) {
  148. e.printStackTrace();
  149. }
  150. }
  151. /**
  152. * 提供静态方法:获取报表图形3:折线图
  153. * @param title 标题
  154. * @param datas 数据
  155. * @param xName 分类(第一季,第二季.....)
  156. * @param yName 柱状图的数量单位
  157. * @param url 字体
  158. */
  159. public static void createLinePort(String title,Map<String,Double> datas,String xName,String yName,String url){
  160. try {
  161. //种类数据集
  162. DefaultCategoryDataset dataset = new DefaultCategoryDataset();
  163. //获取迭代器:
  164. Set<Entry<String, Double>> set = datas.entrySet();
  165. Iterator iterator=(Iterator) set.iterator();
  166. Entry entry=null;
  167. while(iterator.hasNext()){
  168. entry=(Entry) iterator.next();
  169. dataset.setValue(Double.parseDouble(entry.getValue().toString()),//y
  170. title, //名称
  171. entry.getKey().toString()); //x
  172. }
  173. //创建折线图,折线图分水平显示和垂直显示两种
  174. JFreeChart chart = ChartFactory.createLineChart(title, xName, yName, dataset,//2D折线图
  175. PlotOrientation.VERTICAL,
  176. false, // 是否显示图例(对于简单的柱状图必须是false)
  177. true, // 是否生成工具
  178. true);// 是否生成URL链接
  179. //得到绘图区
  180. setLineRender((CategoryPlot)chart.getPlot(),true,true);
  181. org.jfree.chart.ChartUtils.saveChartAsPNG(new File(url), chart, 1000,600);
  182. } catch (Exception e) {
  183. e.printStackTrace();
  184. }
  185. }
  186. /**
  187. * 提供静态方法:获取报表图形3:折线图
  188. * @param title 标题
  189. * @param datas 数据
  190. * @param xName 分类(第一季,第二季.....)
  191. * @param yName 柱状图的数量单位
  192. * @param url 字体
  193. */
  194. public static void createLinePort(String title,DefaultCategoryDataset datas,String xName,String yName,String url){
  195. try {
  196. //创建折线图,折线图分水平显示和垂直显示两种
  197. JFreeChart chart = ChartFactory.createLineChart(title, xName, yName, datas,//2D折线图
  198. PlotOrientation.VERTICAL,
  199. true, // 是否显示图例(对于简单的柱状图必须是false)
  200. true, // 是否生成工具
  201. true);// 是否生成URL链接
  202. //得到绘图区
  203. setLineRender((CategoryPlot)chart.getPlot(),true,true);
  204. org.jfree.chart.ChartUtils.saveChartAsPNG(new File(url), chart, 1000,600);
  205. } catch (Exception e) {
  206. e.printStackTrace();
  207. }
  208. }
  209. /**
  210. * 设置折线图样式
  211. *
  212. * @param plot
  213. * @param isShowDataLabels
  214. * 是否显示数据标签
  215. */
  216. public static void setLineRender(CategoryPlot plot, boolean isShowDataLabels, boolean isShapesVisible) {
  217. plot.setNoDataMessage(NO_DATA_MSG);
  218. plot.setInsets(new RectangleInsets(10, 10, 0, 10), false);
  219. LineAndShapeRenderer lasp = (LineAndShapeRenderer) plot.getRenderer();
  220. LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();
  221. renderer.setSeriesPaint(1, Color.RED);//红色
  222. renderer.setSeriesPaint(0, Color.BLUE);//蓝色
  223. renderer.setDefaultStroke(new BasicStroke(1.5F));
  224. if (isShowDataLabels) {
  225. renderer.setDefaultItemLabelsVisible(true);
  226. renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator(StandardCategoryItemLabelGenerator.DEFAULT_LABEL_FORMAT_STRING,
  227. NumberFormat.getInstance()));
  228. renderer.setDefaultPositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE1, TextAnchor.BOTTOM_CENTER));// weizhi
  229. }
  230. renderer.setDefaultShapesVisible(isShapesVisible);// 数据点绘制形状
  231. setXAixs(plot);
  232. setYAixs(plot);
  233. }
  234. /**
  235. * 设置饼状图渲染
  236. */
  237. public static void setBarRender(Plot plot) {
  238. // CategoryAxis categoryAxis=plot.getDomainAxis();//获得横坐标
  239. // categoryAxis.setLabelFont(new Font("微软雅黑",Font.BOLD,12));//设置横坐标字体
  240. }
  241. /**
  242. * 设置饼状图渲染
  243. */
  244. public static void setPieRender(Plot plot) {
  245. plot.setNoDataMessage(NO_DATA_MSG);
  246. plot.setInsets(new RectangleInsets(10, 10, 5, 10));
  247. PiePlot piePlot = (PiePlot) plot;
  248. piePlot.setInsets(new RectangleInsets(0, 0, 0, 0));
  249. piePlot.setCircular(true);// 圆形
  250. // piePlot.setSimpleLabels(true);// 简单标签
  251. piePlot.setLabelGap(0.01);
  252. piePlot.setInteriorGap(0.05D);
  253. piePlot.setLegendItemShape(new Rectangle(10, 10));// 图例形状
  254. piePlot.setIgnoreNullValues(true);
  255. piePlot.setLabelBackgroundPaint(null);// 去掉背景色
  256. piePlot.setLabelShadowPaint(null);// 去掉阴影
  257. piePlot.setLabelOutlinePaint(null);// 去掉边框
  258. piePlot.setShadowPaint(null);
  259. // 0:category 1:value:2 :percentage
  260. piePlot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0}:{2}"));// 显示标签数据
  261. }
  262. /**
  263. * 设置类别图表(CategoryPlot) X坐标轴线条颜色和样式
  264. *
  265. * @param plot
  266. */
  267. public static void setXAixs(CategoryPlot plot) {
  268. Color lineColor = new Color(31, 121, 170);
  269. plot.getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_45);
  270. plot.getDomainAxis().setAxisLinePaint(lineColor);// X坐标轴颜色
  271. plot.getDomainAxis().setTickMarkPaint(lineColor);// X坐标轴标记|竖线颜色
  272. }
  273. /**
  274. * 设置类别图表(CategoryPlot) Y坐标轴线条颜色和样式 同时防止数据无法显示
  275. *
  276. * @param plot
  277. */
  278. public static void setYAixs(CategoryPlot plot) {
  279. // Color lineColor = new Color(192, 208, 224);
  280. Color lineColor = new Color(31, 121, 170);
  281. ValueAxis axis = plot.getRangeAxis();
  282. axis.setAxisLinePaint(lineColor);// Y坐标轴颜色
  283. axis.setTickMarkPaint(lineColor);// Y坐标轴标记|竖线颜色
  284. // false隐藏Y刻度
  285. axis.setAxisLineVisible(true);
  286. axis.setTickMarksVisible(true);
  287. // Y轴网格线条
  288. plot.setRangeGridlinePaint(new Color(192, 192, 192));
  289. plot.setRangeGridlineStroke(new BasicStroke(1));
  290. plot.getRangeAxis().setUpperMargin(0.1);// 设置顶部Y坐标轴间距,防止数据无法显示
  291. plot.getRangeAxis().setLowerMargin(0.1);// 设置底部Y坐标轴间距
  292. }
  293. /**
  294. * 设置XY图表(XYPlot) X坐标轴线条颜色和样式
  295. *
  296. * @param plot
  297. */
  298. public static void setXY_XAixs(XYPlot plot) {
  299. Color lineColor = new Color(31, 121, 170);
  300. plot.getDomainAxis().setAxisLinePaint(lineColor);// X坐标轴颜色
  301. plot.getDomainAxis().setTickMarkPaint(lineColor);// X坐标轴标记|竖线颜色
  302. }
  303. /**
  304. * 设置XY图表(XYPlot) Y坐标轴线条颜色和样式 同时防止数据无法显示
  305. *
  306. * @param plot
  307. */
  308. public static void setXY_YAixs(XYPlot plot) {
  309. Color lineColor = new Color(192, 208, 224);
  310. ValueAxis axis = plot.getRangeAxis();
  311. axis.setAxisLinePaint(lineColor);// X坐标轴颜色
  312. axis.setTickMarkPaint(lineColor);// X坐标轴标记|竖线颜色
  313. // 隐藏Y刻度
  314. axis.setAxisLineVisible(false);
  315. axis.setTickMarksVisible(false);
  316. // Y轴网格线条
  317. plot.setRangeGridlinePaint(new Color(192, 192, 192));
  318. plot.setRangeGridlineStroke(new BasicStroke(1));
  319. plot.setDomainGridlinesVisible(false);
  320. plot.getRangeAxis().setUpperMargin(0.12);// 设置顶部Y坐标轴间距,防止数据无法显示
  321. plot.getRangeAxis().setLowerMargin(0.12);// 设置底部Y坐标轴间距
  322. }
  323. }