JFreeChart构建柱状图

JFreeChart构建柱状图

前言

Java开发中,可以采用许多库和框架来实现图表统计功能。以下是一些常见的Java图表统计库和框架:

  1. JFreeChart:JFreeChart是一个流行的Java图表库,可用于生成各种类型的图表,包括线图、柱状图、饼图等。
  2. Chart.js:Chart.js是一个基于HTML5 Canvas的JavaScript图表库,可以创建响应式、动态的图表,适用于Web应用程序。
  3. Apache ECharts:Apache ECharts是一个基于JavaScript的开源图表库,支持多种图表类型,包括折线图、柱状图、散点图等。
  4. Google Charts:Google Charts是一个免费的Web图表库,提供了丰富的图表类型和交互功能,支持多种数据格式。
  5. Plotly Java:Plotly Java是一个Java图表库,可用于生成高度定制化的图表和数据可视化,支持多种数据格式。

这些库和框架都提供了方便易用的API和文档,可以根据需要选择合适的工具来实现图表统计功能。

它们的区别

这些Java图表库和框架之间存在一些区别,包括以下方面:

  1. 适用场景:不同的库和框架适用于不同的场景。例如,JFreeChart适用于生成各种类型的图表,包括线图、柱状图、饼图等;而Chart.js适用于Web应用程序中创建响应式、动态的图表。
  2. 数据格式:不同的库和框架支持不同的数据格式。例如,Google Charts支持JSON格式的数据,而Plotly Java支持多种数据格式,包括CSV、JSON、Excel等。
  3. 可定制性:不同的库和框架具有不同的可定制性。例如,Apache ECharts提供了许多主题和样式,可以轻松自定义图表外观;而Plotly Java则提供了高度可定制的API和文档,可以实现更复杂的图表需求。
  4. 性能:不同的库和框架在性能上也存在差异。例如,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();

展示效果如下

posted @ 2023-05-10 17:59  小学程序员  阅读(358)  评论(0编辑  收藏  举报