【JFreeChart】自定義蜘蛛網圖生成帶刻度三角雷達圖 自定義文字風格 背景色

 

工作中需要生成PDF 且包含圖表。iText 或其他 可以訪問網頁地址轉PDF。但是效果不是特別理想。故用iText代碼方式實現生成PDF。奈何圖表又是一個問題(還是個三角形的雷達圖)。Java端生成的有好幾個(Charts4j、JFreeChart還有幾個忘記名字了)。最終選擇了JFreeChart。生成圖表圖片文件後再插入PDF即可。iText使用內容整理後續更新。

Maven搭建項目引入JFreeChart

<!-- https://mvnrepository.com/artifact/org.jfree/jfreechart -->
<dependency>
	<groupId>org.jfree</groupId>
	<artifactId>jfreechart</artifactId>
	<version>1.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jfree/jcommon -->
<dependency>
	<groupId>org.jfree</groupId>
	<artifactId>jcommon</artifactId>
	<version>1.0.24</version>
</dependency>

繼承SpiderWebPlot 實現帶刻度雷達圖

import org.jfree.chart.plot.SpiderWebPlot;
import org.jfree.data.category.CategoryDataset;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.geom.*;
import java.text.NumberFormat;

/**
 * @Description 帶刻度雷達圖
 * @className MySpiderWebPlot
 * @Date 2019/7/16-11:15
 **/
public class MySpiderWebPlot extends SpiderWebPlot {
    private static final long serialVersionUID = 201907171429L;


    private int ticks = DEFAULT_TICKS;
    //默認刻度個數
    private static final int DEFAULT_TICKS = 5;
    private NumberFormat format = NumberFormat.getInstance();
    //刻度顯示的角度
    private static final double PERPENDICULAR = 90;
    //刻度的長度
    private static final double TICK_SCALE = 0.010;
    private int valueLabelGap = DEFAULT_GAP;
    //刻度與刻度說明的間隔
    private static final int DEFAULT_GAP = 10;
    private static final double THRESHOLD = 15;



    MySpiderWebPlot(CategoryDataset createCategoryDataset) {
        super(createCategoryDataset);
    }
    @Override
    protected void drawLabel(final Graphics2D g2, final Rectangle2D plotArea, final double value,
                             final int cat, final double startAngle, final double extent) {
        super.drawLabel(g2, plotArea, value, cat, startAngle, extent);
        final FontRenderContext frc = g2.getFontRenderContext();
        final double[] transformed = new double[2];
        final double[] transformer = new double[2];
        final Arc2D arc1 = new Arc2D.Double(plotArea, startAngle, 0, Arc2D.OPEN);
        for (int i = 1; i <= ticks; i++) {
            final Point2D point1 = arc1.getEndPoint();
            final double deltaX = plotArea.getCenterX();
            final double deltaY = plotArea.getCenterY();
            double labelX = point1.getX() - deltaX;
            double labelY = point1.getY() - deltaY;
            final double scale = ((double) i / (double) ticks);
            final AffineTransform tx = AffineTransform.getScaleInstance(scale, scale);
            final AffineTransform pointTrans = AffineTransform.getScaleInstance(scale + TICK_SCALE, scale + TICK_SCALE);
            transformer[0] = labelX;
            transformer[1] = labelY;
            pointTrans.transform(transformer, 0, transformed, 0, 1);
            final double pointX = transformed[0] + deltaX;
            final double pointY = transformed[1] + deltaY;
            tx.transform(transformer, 0, transformed, 0, 1);
            labelX = transformed[0] + deltaX;
            labelY = transformed[1] + deltaY;
            double rotated = (PERPENDICULAR);
            AffineTransform rotateTrans = AffineTransform.getRotateInstance(Math.toRadians(rotated), labelX, labelY);
            transformer[0] = pointX;
            transformer[1] = pointY;
            rotateTrans.transform(transformer, 0, transformed, 0, 1);
            final double x1 = transformed[0];
            final double y1 = transformed[1];
            rotated = (-PERPENDICULAR);
            rotateTrans = AffineTransform.getRotateInstance(Math.toRadians(rotated), labelX, labelY);
            rotateTrans.transform(transformer, 0, transformed, 0, 1);
            final Composite saveComposite = g2.getComposite();
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
            g2.draw(new Line2D.Double(transformed[0], transformed[1], x1, y1));
            if (startAngle == this.getStartAngle()) {
                final String label = format.format(((double) i / (double) ticks) * this.getMaxValue());
                final LineMetrics lm = getLabelFont().getLineMetrics(label, frc);
                final double ascent = lm.getAscent();
                if (Math.abs(labelX - plotArea.getCenterX()) < THRESHOLD) {
                    labelX += valueLabelGap;
                    labelY += ascent / (float) 2;
                } else if (Math.abs(labelY - plotArea.getCenterY()) < THRESHOLD) {
                    labelY += valueLabelGap;
                } else if (labelX >= plotArea.getCenterX()) {
                    if (labelY < plotArea.getCenterY()) {
                        labelX += valueLabelGap;
                        labelY += valueLabelGap;
                    } else {
                        labelX -= valueLabelGap;
                        labelY += valueLabelGap;
                    }
                } else {
                    if (labelY > plotArea.getCenterY()) {
                        labelX -= valueLabelGap;
                        labelY -= valueLabelGap;
                    } else {
                        labelX += valueLabelGap;
                        labelY -= valueLabelGap;
                    }
                }
                g2.setPaint(getLabelPaint());
                g2.setBackground(Color.green);
                g2.setFont(getLabelFont());
                g2.drawString(label, (float) labelX, (float) labelY);
            }
            g2.setComposite(saveComposite);
        }
    }
}

 新建圖表對象生成和數據組裝方法

 

import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.SpiderWebPlot;
import org.jfree.data.category.DefaultCategoryDataset;


import java.awt.*;


/**
 * @Description 帶刻度三角雷達圖 自定義文字風格 背景色
 * @className Test
 * @Date 2019/7/16-11:16
 **/
public class Test {
    /**
     * @Description 創建圖表對象
     * @Author 小帥丶
     * @Date  2019/7/17 14:32
     * @return org.jfree.chart.JFreeChart
     **/
    public static JFreeChart createChart() {
        MySpiderWebPlot spiderwebplot = new MySpiderWebPlot(createDataset());
        Font font = new Font("SansSerif", Font.BOLD,24);
        JFreeChart jfreechart = new JFreeChart("", font,spiderwebplot, false);
        //獲取圖表對象  對圖表進行額外處理
        SpiderWebPlot plot = (SpiderWebPlot) jfreechart.getPlot();
        //設置圖表文字
        plot.setLabelFont(font);
        //設置圖表背景色
        plot.setSeriesPaint(Color.green);
        return jfreechart;
    }
    /**
     * @Description 組裝測試數據
     * @Author 小帥丶
     * @Date  2019/7/17 14:31
     * @return org.jfree.data.category.DefaultCategoryDataset
     **/
    public static DefaultCategoryDataset createDataset() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        String group1 = "失信等級統計";
        //value就是數據值
        dataset.addValue(20,group1, "低危");
        dataset.addValue(2, group1, "高危");
        dataset.addValue(4, group1, "中危");


        return dataset;
    }
}

在SWING中顯示圖表

public class Test {   
 public static void main(String args[]) {
        //在SWING中顯示
        JFrame jf = new JFrame();
        jf.add(erstelleSpinnenDiagramm());
        jf.pack();
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }
    /**
     * @Description 圖表放C/S面板
     * @Author 小帥丶
     * @Date  2019/7/17 14:32
     * @Param []
     * @return javax.swing.JPanel
     **/
    public static JPanel erstelleSpinnenDiagramm() {
        JFreeChart jfreechart =createChart();
        ChartPanel chartpanel = new ChartPanel(jfreechart);
        return chartpanel;
    }
}

 效果圖

將圖表保存爲圖片文件

  public class Test {
    public static void main(String args[]) {
        //將JFreeChart保存爲圖片存在文件路徑中
        saveAsFile("E:/JfreeChart/MySpiderWebPlot.png",400,300);
    }
    /**
     * @Description 保存爲圖片
     * @Author 小帥丶
     * @Date  2019/7/17 14:41
     * @param outputPath 圖片保存路徑
     * @param weight 寬度
     * @param height 高度
     * @return void
     **/
    public static void saveAsFile(String outputPath, int weight, int height) {
        FileOutputStream out = null;
        try {
            File outFile = new File(outputPath);
            if (!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdirs();
            }
            out = new FileOutputStream(outputPath);
            // 保存爲PNG
            ChartUtils.writeChartAsPNG(out, createChart(),weight, height);
            // 保存爲JPEG
            // ChartUtilities.writeChartAsJPEG(out, chart, 500, 400);
            out.flush();
        }catch (Exception e) {
            System.out.println("異常 = " + e.getMessage());
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    System.out.println("異常 = " + e.getMessage());
                }
            }
        }
    }
}

圖片效果圖

 

 多個group效果圖

       //設置圖表背景色 多個
        plot.setSeriesPaint(0,Color.blue );
        plot.setSeriesPaint(1,Color.cyan );

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章