绘制热点图

绘制热点图_第1张图片

如上效果

主要类似篮球游戏的热点占位图

代码如下:


package img;


import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


import javax.imageio.ImageIO;


/**
 * 类DrawHeatImage.java的实现描述:TODO 类实现描述 
 * @author broust 2016年4月4日 下午7:27:44
 */
public class DrawHeatImage {


    /**
     * 绘制热点图
     * 
     * @param heatList 热点数量
     * @param colNum 一行布局多少个热点
     * @param gridSize 单元格子的大小--只能绘制正方形
     * @return
     */
    private static BufferedImage drawHeatImage(List heatList, List actorList, int width,
                                               int height) {


        // 创建bufferedImage
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 底色
        g2d.setColor(Color.white);
        // 整个画布为白色
        g2d.fillRect(0, 0, width, height);


        // 开始绘制格子 --热点值
        for (RectWithHeat area : heatList) {
            g2d.setColor(getColor(area.getHeat()));
            g2d.drawString(String.valueOf(area.getHeat()), (int) area.getX(), (int) area.getCenterY());
        }


        // 开始绘制角色
        for (Rectangle actor : actorList) {
            drawActor(g2d, actor, heatList);
        }




        g2d.dispose();
        return image;
    }


    /**
     * @param g2d
     * @param actor
     * @param heatList
     */
    private static void drawActor(Graphics2D g2d, Rectangle actor, List heatList) {
        Color col = getColor(actor, heatList);
        Color[] cols = new Color[] { Color.WHITE, col, Color.WHITE };// 过渡的颜色
        float[] fts = new float[] { 0.0f, 0.2f, 0.5f };// 标记颜色过滤的范围
        // 定义画笔
        RadialGradientPaint paint = new RadialGradientPaint((float) actor.getCenterX(), (float) actor.getCenterY(),
                                                            (float) actor.getHeight(), fts, cols);
        g2d.setPaint(paint);
        // 绘制---角色
        g2d.fillArc((int) actor.getX(), (int) actor.getY(), (int) actor.getWidth(), (int) actor.getHeight(),
                    0, 720);
    }


    /**
     * @param actor
     * @param heatList
     * @return
     */
    private static Color getColor(Rectangle actor, List heatList) {
        int touchAreaNum = 0;
        int totalHeat = 0;
        for (RectWithHeat heat : heatList) {
            if (heat.intersects(actor)) {
                touchAreaNum++;
                totalHeat += heat.getHeat();
            }
        }


        return getColor((int) (totalHeat / touchAreaNum));
    }


    /**
     * 获取颜色
     * 
     * @param rate [0-255]
     * @return
     */
    private static Color getColor(int rate) {
        /**
         * 红色:(255,0,0) --->蓝色:(0,0,255) [红,黄,蓝]
         */
        rate = rate < 0 ? 0 : rate > 255 ? 255 : rate;
        return new Color(rate, 0, 255 - rate);
    }


    /**
     * 保存到文件
     * 
     * @param filePath
     * @param image
     * @throws IOException
     */
    private static void storeToFile(String filePath, BufferedImage image) throws IOException {
        File file = new File(filePath);
        ImageIO.write(image, "JPEG", file);
    }


    /**
     * 生成热点区域数据
     * 
     * @param nums
     * @return
     */
    private static List generateHeatAreas(int areaWidth, int areaHeight, int colNum, int lineNum) {


        Random r = new Random();
        List list = new ArrayList();
        for (int i = 0; i < lineNum; i++) {
            for (int j = 0; j < colNum; j++) {
                RectWithHeat area = new RectWithHeat();
                area.setBounds(j * areaWidth, i * areaHeight, areaWidth, areaHeight);
                area.setHeat(r.nextInt(256));// 0-255
                list.add(area);
            }
        }
        return list;
    }


    private static List generateTestActors(int nums, int height, int backGroundWidth, int backGroundHeight) {
        Random rW = new Random();
        Random rH = new Random();
        List list = new ArrayList();
        for (int i = 0; i < nums; i++) {
            Rectangle actor = new Rectangle();
            actor.setBounds(rW.nextInt(backGroundWidth), rH.nextInt(backGroundHeight), height, height);
            list.add(actor);
        }


        return list;
    }


    public static void main(String[] args) throws IOException {
        List heatDataList = generateHeatAreas(100, 80, 5, 4);
        List actorList = generateTestActors(5, 50, 100 * 5, 80 * 4);
        String filePath = "/Users/broust/tmp/xx/heatImage.jpg";
        storeToFile(filePath, drawHeatImage(heatDataList, actorList, 100 * 5, 80 * 4));
    }


    /**
     * 带热点信息的方块区域 类DrawHeatImage.java的实现描述:TODO 类实现描述
     * 
     * @author broust 2016年4月8日 下午6:26:34
     */
    private static class RectWithHeat extends Rectangle {


        /**
         * 
         */
        private static final long serialVersionUID = 1L;


        private int heat;


        /**
         * @return the heat
         */
        public int getHeat() {
            return heat;
        }


        /**
         * @param heat the heat to set
         */
        public void setHeat(int heat) {
            this.heat = heat;
        }
    }
}


你可能感兴趣的:(java)