java Graphics 绘制树形图,保存图片

2019-03-04  本文已影响0人  勇往直前z

最近项目中要做报告,生成树形图显示父子关系,网上没找到合适的工具,所以用Graphics画了个简单的。

很简单直接上代码吧。

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class Dendrogram {

    /**
     * 生成树图写到磁盘
     * @param picType 图片类型JPG GIF JPEG PNG
     * @param file 图片文件
     * @param list 数据模型 [{name: '', children: [{name: '', children: [{}]}]}]
     * @param rootName 根名称
     * @return
     */
    public static boolean writeImage(String picType, File file, List<ShareHolderDto> list, String rootName) {
        BufferedImage bimg = new BufferedImage(2002, 2002, BufferedImage.TYPE_INT_BGR);
        // 拿到画笔
        Graphics2D g = bimg.createGraphics();
        // 画一个图形系统默认是白色
        int imgWidth = 2000;
        int imgHeight = 2000;
        g.fillRect(1, 1, imgWidth, imgHeight);
        // 设置画笔颜色
        g.setColor(new Color(12, 123, 88));
        int fontSize = 14;
        // 设置画笔画出的字体风格
        g.setFont(new Font("隶书", Font.ITALIC, fontSize));
        g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);
        //消除文字锯齿
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        //消除画图锯齿
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 写一个字符串
        int margin = 60;
        int parentY = imgHeight / 2;
        g.drawString(rootName, fontSize, parentY);
        int parentX = computeParentX(rootName, fontSize, fontSize);
        int heightL2 = (imgHeight - fontSize) / list.size();
        for (int i = 0; i < list.size(); i++) {
            ShareHolderDto shareHolderDto = list.get(i);
            int height = heightL2 / 2;
            String name = shareHolderDto.getName();
            g.drawString(name, parentX + margin, height + heightL2 * i);
            // TODO 这里可以写其他属性, y随属性个数增加而增加 fontSize * i
            g.drawString("注册资本:" + (shareHolderDto.getRegCapital() == null?"-":shareHolderDto.getRegCapital()), parentX + margin, height + heightL2 * i + fontSize);
            g.drawLine(parentX, parentY, parentX + margin, height + heightL2 * i);
            if (shareHolderDto.getChildren() != null && !shareHolderDto.getChildren().isEmpty()) {
                int myX = computeParentX(shareHolderDto.getName(), parentX + margin, fontSize);
                drawChildrenTransverse(g, shareHolderDto.getChildren(), height + heightL2 * i, heightL2, heightL2 * i, fontSize, margin, myX);
            }
        }
        // 释放画笔
        g.dispose();
        // 将画好的图片通过流形式写到硬盘上
        boolean val = false;
        try {
            val = ImageIO.write(bimg, picType, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return val;
    }

    /**
     * 循环子树
     * @param g Graphics2D
     * @param children 子节点
     * @param parentY 父节点的Y坐标
     * @param parentHeight 父区域的高度
     * @param startY 父区域起始Y坐标
     * @param fontSize 字体大小
     * @param margin 兄弟节点的间距
     * @param parentX 父节点的X坐标
     */
    private static void drawChildrenTransverse(Graphics2D g, List<ShareHolderDto> children, int parentY, int parentHeight, int startY, int fontSize, int margin, int parentX) {
        int heightLn = parentHeight / children.size();
        for (int i = 0; i < children.size(); i++) {
            ShareHolderDto shareHolderDto = children.get(i);
            int y = heightLn / 2 + heightLn * i + startY;
            int x = parentX + margin;
            String name = shareHolderDto.getName();
            g.drawString(name, x , y);
            g.drawLine(parentX, parentY, x, y);
            if (shareHolderDto.getChildren() != null && !shareHolderDto.getChildren().isEmpty()) {
                int myX = computeParentX(shareHolderDto.getName(), x, fontSize);
                int myStartY = heightLn * i + startY;
                drawChildrenTransverse(g, shareHolderDto.getChildren(),y, heightLn, myStartY, fontSize, margin, myX);
            }
        }
    }

    /**
     * 计算父节点名字末尾X坐标
     * @param str 文本
     * @param patentX 父节点起点X
     * @param fontSize 字体大小
     * @return
     */
    private static int computeParentX(String str, int patentX, int fontSize) {
        return patentX + str.length() * fontSize;
    }

}

下面是效果图:

image.png
源码地址:https://github.com/hardworkingman/graphics-dendrogram 希望对你有帮助,欢迎star(* ̄︶ ̄)
上一篇 下一篇

猜你喜欢

热点阅读