JFreeChart构建柱状图
前言
Java开发中,可以采用许多库和框架来实现图表统计功能。以下是一些常见的Java图表统计库和框架:
- JFreeChart:JFreeChart是一个流行的Java图表库,可用于生成各种类型的图表,包括线图、柱状图、饼图等。
- Chart.js:Chart.js是一个基于HTML5 Canvas的JavaScript图表库,可以创建响应式、动态的图表,适用于Web应用程序。
- Apache ECharts:Apache ECharts是一个基于JavaScript的开源图表库,支持多种图表类型,包括折线图、柱状图、散点图等。
- Google Charts:Google Charts是一个免费的Web图表库,提供了丰富的图表类型和交互功能,支持多种数据格式。
- Plotly Java:Plotly Java是一个Java图表库,可用于生成高度定制化的图表和数据可视化,支持多种数据格式。
这些库和框架都提供了方便易用的API和文档,可以根据需要选择合适的工具来实现图表统计功能。
它们的区别
这些Java图表库和框架之间存在一些区别,包括以下方面:
- 适用场景:不同的库和框架适用于不同的场景。例如,JFreeChart适用于生成各种类型的图表,包括线图、柱状图、饼图等;而Chart.js适用于Web应用程序中创建响应式、动态的图表。
- 数据格式:不同的库和框架支持不同的数据格式。例如,Google Charts支持JSON格式的数据,而Plotly Java支持多种数据格式,包括CSV、JSON、Excel等。
- 可定制性:不同的库和框架具有不同的可定制性。例如,Apache ECharts提供了许多主题和样式,可以轻松自定义图表外观;而Plotly Java则提供了高度可定制的API和文档,可以实现更复杂的图表需求。
- 性能:不同的库和框架在性能上也存在差异。例如,JFreeChart采用Java2D技术绘制图表,可能会对大量数据或复杂图表的性能造成影响;而Apache ECharts使用Canvas技术,在大数据量下具有良好的性能表现。
因此,选择合适的Java图表库和框架需要根据具体的需求和情况进行综合考虑
JFreeChart集成springboot生成柱状图
首先,先添加maven
<!-- 图表工具-->
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
研发构建柱状图的工具类
package com.lims.utils;
import com.lims.vo.MonthChartVo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPosition;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import java.awt.*;
import java.io.IOException;
import java.util.List;
/**
* @Description: TODO
* @Author: wanping
* @Date: 5/10/23
**/
public class JChartUtils {
/**
* 依据数据构建图表
* @param monthChartVos
* @return
* @throws IOException
* @throws InvalidFormatException
*/
public static JFreeChart generateMonthChart(List<MonthChartVo> monthChartVos,String title,String xTitle,String yTitle) throws IOException, InvalidFormatException {
if(CollectionUtils.isEmpty(monthChartVos))
return null;
// 创建图表数据集
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
for (MonthChartVo m : monthChartVos) {
dataset.addValue(m.getValue(), m.getRowKey(), m.getColumnKey());
}
// 创建图表对象
JFreeChart chart = ChartFactory.createBarChart(
title, // 图表标题
xTitle, // X轴标签
yTitle, // Y轴标签
dataset, // 数据集
PlotOrientation.VERTICAL,// 图表方向
true, // 是否显示图例
true, // 是否生成工具提示
false // 是否生成URL链接
);
// 设置图表样式
chart.setBackgroundPaint(Color.white);
CategoryPlot plot = chart.getCategoryPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.white);
// 设置柱子的颜色
BarRenderer renderer = (BarRenderer) plot.getRenderer();
renderer.setSeriesPaint(0, Color.GREEN);
renderer.setSeriesPaint(1, Color.BLUE);
// 设置园柱体上标上数值
CategoryItemLabelGenerator generator = new StandardCategoryItemLabelGenerator();
renderer.setDefaultItemLabelGenerator(generator);
renderer.setDefaultItemLabelsVisible(true);
// 设置CategoryKey的显示位置和角度,以使其斜着展示
CategoryAxis categoryAxis = plot.getDomainAxis();
categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
return chart;
}
}
构建应用层
/**
* @Description: TODO
* @Author: wanping
* @Date: 5/9/23
**/
@RestController
@Api(value = "测试图表工具", tags = "测试图表工具")
@RequestMapping("/statistics")
public class StatisticsController {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private StatisticsService StatisticsService;
@GetMapping("/getDeductPointsChart")
public void getDeductPointsChart(String year, String month, String factory, HttpServletResponse response) {
try {
List<MonthChartVo> chart = StatisticsService.getDeductPointsChart(year, month, factory);
String firstDayOfMonth = DatesUtil.getFirstDayOfMonth(Integer.parseInt(year), Integer.parseInt(month));
String lastDayOfMonth = DatesUtil.getLastDayOfMonth(Integer.parseInt(year), Integer.parseInt(month));
String title="情况对比(与上月情况对比)\n"+firstDayOfMonth+"~"+lastDayOfMonth;
JFreeChart jFreeChart = JChartUtils.generateMonthChart(chart,title,"","");
// 将图表输出到响应流中
response.setContentType("image/png");
OutputStream out = response.getOutputStream();
ChartUtils.writeChartAsPNG(out, jFreeChart, 1000, 600);
out.close();
}catch (Exception e){
logger.error("[getDeductPointsChart]查询月份比对图表异常",e);
}
}
}
编写业务逻辑
编写实体vo
/**
* @Description: 月份对比实体
* @Author: wanping
* @Date: 5/10/23
**/
@Data
public class MonthChartVo {
private double value;
private String rowKey;
private String columnKey;
}
编写service
@Resource
private StatisticsMapper statisticsMapper;
@Override
public List<MonthChartVo> getDeductPointsChart(String year, String month,String factory) {
//获取本月数据
List<MonthChartVo> nowMonthData = getMonthData(year, month, factory, "本月");
//获取上月数据
LocalDate prevMonth = DatesUtil.getPrevMonth(Integer.parseInt(year), Integer.parseInt(month));
List<MonthChartVo> prevMonthData = getMonthData(String.valueOf(prevMonth.getYear()), String.valueOf(prevMonth.getMonthValue()), factory, "本月");
List<MonthChartVo> monthChartVos = new ArrayList<>();
String[] titles = {"Y坐标01","Y坐标02","Y坐标03","Y坐标04"};
for (String title : titles) {
//封装上月数据
packMonthlist(prevMonthData,title,monthChartVos,"上月");
//封装本月数据
packMonthlist(nowMonthData,title,monthChartVos,"本月");
}
return monthChartVos;
}
具体的业务逻辑就不写了,主要是思路哈,自己写获取数据逻辑即可
编写应用层
展示图片
// 将图表输出到响应流中
response.setContentType("image/png");
OutputStream out = response.getOutputStream();
ChartUtils.writeChartAsPNG(out, jFreeChart, 1000, 600);
out.close();
导出word
// 导出图表到Word
XWPFDocument doc = new XWPFDocument();
XWPFParagraph para = doc.createParagraph();
XWPFRun run = para.createRun();
run.setText("柱状图对比");
run.setFontSize(16);
File file = new File("chart.png");
ChartUtils.saveChartAsPNG(file, chart, 800, 400);
FileInputStream fis = new FileInputStream(file);
byte[] bytes = IOUtils.toByteArray(fis);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
run.addBreak();
run.addPicture(bais, XWPFDocument.PICTURE_TYPE_PNG, "chart.png", Units.toEMU(400), Units.toEMU(200));
fis.close();
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setHeader("Content-disposition", "attachment; filename=chart.docx");
doc.write(response.getOutputStream());
response.getOutputStream().close();
展示效果如下