JFreeChart绘制XY折线图(工具类设计)

准备用Java写通信的仿真平台作为毕业设计,相比matlab绘图,Java绘图需要自己去写很多工具类,博主在这采用了JFreeChart的开源解决方案,摸索着自己写了一个XY折线图工具类,话不多说贴源码,源码中写了很多注释,配了一套自己用的绘图样式,需要的童鞋可以借鉴借鉴,希望对你有帮助。源代码已上传我的github上。

首先用Maven引入Jar包

<!-- Java 绘图 -->
<dependency>
    <groupId>jfree</groupId>
    <artifactId>jfreechart</artifactId>
    <version>1.0.13</version>
</dependency>

DrawingToolsTest工具类设计

先看效果

下方是我的测试方法,准备了x和y的数据放入Map中,然后传入已经写好的接口中,就一行代码。底层的过程都封装好了,调的话很方便

public class DrawingToolsTest {
    @Test
    public void testTools() {
        int sum = 20;//随机生成20对数
        Map<Double, Double> map1 = new HashMap<>();
        double[] restX = RandomTools.getRadomDouble(1, 20, 1, sum);
        double[] restY = RandomTools.getRadomDouble(1, 20, 1, sum);
        for (int i = 0; i < sum; i++) {
            map1.put(restX[i], restY[i]);
        }

        Map<Double, Double> map2 = new HashMap<>();
        for (int i = 0; i < sum; i++) {
            map2.put(restY[i], restX[i]);
        }

        Map<Double, Double>[] dataSet = new Map[]{map1, map2};
        String[] types = new String[]{"A", "B"};
        //调用绘图工具
        DrawingTools.drawLineChart("axin", "测试", "这是X轴",
                "这是y轴", dataSet, types);

        Scanner in = new Scanner(System.in);
        in.hasNext();
    }
}

/**
 * @author Axin
 */
public class RandomTools {
    /**
     * @param start
     * @param end
     * @param retain 保留几位小数
     * @param sum    生成多少个数
     * @return
     */
    public static double[] getRadomDouble(int start, int end, int retain, int sum) {
        double[] res = new double[sum];

        for (int i = 0; i < sum; i++) {
            BigDecimal db = new BigDecimal(Math.random() * (end - start) + start);
            //四舍五入
            res[i] = db.setScale(retain, BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        return res;
    }
}

运行后:
image

工具类源码

/**
 * 后端绘图类
 *
 * @author Axin
 * @date 2018-10-16
 */

@ConfigurationProperties(prefix = "draw")
public class DrawingTools extends ApplicationFrame {
    private String titleFont;
    private int titleFontSize;
    private String xyFont;
    private int xyFontSize;

    DrawingTools() {
        this("Axin");
    }

    public DrawingTools(String appTitle) {
        super(appTitle);
        this.titleFont = "微软雅黑";
        this.titleFontSize = 20;
        this.xyFont = "微软雅黑";
        this.xyFontSize = 15;
    }

    /**
     * @param appTitle    标题
     * @param chartTitle  图标题
     * @param xName       x轴命名
     * @param yName       y轴命名
     * @param dataSet     数据集
     * @param types       线条种类
     */
    public static void drawLineChart(String appTitle, String chartTitle,
                                     String xName,
                                     String yName,
                                     Map<Double, Double>[] dataSet,
                                     String[] types) {
        DrawingTools tools = new DrawingTools(appTitle);
        IntervalXYDataset dataset = tools.getLineDataset(dataSet, types);
        JFreeChart chart = tools.getLineChart(chartTitle, xName, yName, dataset);

        //绘图模式化
        tools.setChartCSS(chart);
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(900, 600));
        tools.setContentPane(chartPanel);
        tools.pack();
        RefineryUtilities.centerFrameOnScreen(tools);
        tools.setVisible(true);
    }

    private JFreeChart getLineChart(String title, String xName, String yName, XYDataset dataset) {
        /**
         * 图标标题,x轴名称,y轴名称,数据集合,图标显示方向,是否使用图示,是否生成工具栏,是否生成URL链接
         */
        JFreeChart chart = ChartFactory.createXYLineChart(
                title,
                xName,
                yName,
                dataset,
                PlotOrientation.VERTICAL,
                true,
                true,
                false
        );
        return chart;
    }



    /**
     * 自定义设置图表字体样式
     *
     * @param chart
     */
    private void setChartCSS(JFreeChart chart) {
        //初始化
        chart.setBackgroundPaint(ChartColor.WHITE);
        XYPlot plot = chart.getXYPlot();

        //标题
        TextTitle textTitle = chart.getTitle();
        textTitle.setFont(new Font(titleFont, Font.BOLD, titleFontSize));
        LegendTitle legendTitle = chart.getLegend();
        legendTitle.setItemFont(new Font(titleFont, Font.PLAIN, titleFontSize));


        //图表xy轴字体设置
        plot.getDomainAxis().setLabelFont(new Font(xyFont, Font.PLAIN, xyFontSize));
        plot.getDomainAxis().setTickLabelFont(new Font(xyFont, Font.PLAIN, xyFontSize));
        plot.getRangeAxis().setTickLabelFont(new Font(xyFont, Font.PLAIN, xyFontSize));
        plot.getRangeAxis().setLabelFont(new Font(xyFont, Font.PLAIN, xyFontSize));

        //设置背景色-xy轴格子色
        plot.setBackgroundPaint(ChartColor.WHITE);
        plot.setRangeGridlinePaint(ChartColor.lightGray);
//        plot.setDomainGridlinePaint(ChartColor.lightGray);

        //折线图渲染
        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
        plot.setRenderer(renderer);
//        renderer.setPaint(ChartColor.BLACK);
        chart.getLegend().setPosition(RectangleEdge.RIGHT);

    }

    /**
     * @param dataSets int:double
     * @param types    折线的种类
     * @return
     */
    private IntervalXYDataset getLineDataset(Map<Double, Double>[] dataSets, String[] types) {

        XYSeriesCollection dataSet = new XYSeriesCollection();
        int index = 0;
        for (String type : types) {
            XYSeries series = new XYSeries(type);
            for (Map.Entry<Double, Double> data : dataSets[index++].entrySet()) {
                series.add(data.getKey(), data.getValue());
            }
            dataSet.addSeries(series);
        }
        return dataSet;
    }
}

结语

其实在真实生产环境中,后端已经不渲染报表图片之类了,都是后端传数据给前端,由前端来进行可视化,这里使用JFreeChart是为了后端做单元测试而编写的。

posted @ 2018-10-16 21:45  上帝爱吃苹果-Soochow  阅读(2019)  评论(0编辑  收藏  举报