封装力引导图的的Java代码

/**
     * 封装力引导关系图的数据
     * @param keywordMap
     * @param originName
     * @return
     */
    public Map<String,Object> getRelationKeywords(Map<String, Integer> keywordMap, String originName){

        Map<String, Object> resultMap = new HashMap<String, Object>();// 返回的结果map
        List<Map<String, Object>> nodeList = new ArrayList<Map<String, Object>>();// 节点集合
        List<Map<String, Object>> edgeList = new ArrayList<Map<String, Object>>();// 连线集合

        int len = keywordMap.size();

        // 半径
        double radius = 25;

        // 原点坐标
        double originX = 0;
        double originY = 0;
        // 原点半径
        double originR = 50;

        // 最小距离
        double minDistance = radius + originR + 100;
        double tempDistance = (radius * 2 * len) / (Math.PI * 2);
        tempDistance = Math.round(tempDistance);
        minDistance = tempDistance > minDistance ? tempDistance : minDistance;

        int maxNum = 0;// 最大数
        for(Integer num : keywordMap.values()){
            if(num.intValue() > maxNum){
                maxNum = num;
            }
        }

        int coef = 30;// 系数
        int temp = 0;// 临时变量
        double max = 1000;// 最大范围坐标
        List<double[]> coordinateList = new ArrayList<double[]>();// 已有坐标集合

        // 初始化第一个节点(中间节点)
        Map<String, Object> firstNodeMap = new HashMap<String, Object>();
        firstNodeMap.put("id", 0);
        firstNodeMap.put("name", originName);
        firstNodeMap.put("x", originX);
        firstNodeMap.put("y", originY);
        firstNodeMap.put("symbolSize", originR * 2);

        int total = 0;
        int n = 1;

        for(Map.Entry<String, Integer> entry : keywordMap.entrySet()){
            temp++;
            String key = entry.getKey();
            Integer value = entry.getValue();
            total += value.intValue();
            double distance = maxNum - value.intValue();
            distance = coef * Math.log1p(distance) + minDistance;
            //System.out.println(distance);
            double[] coordinate = getCoordinate(coordinateList, distance, originX, originY, originR, radius, max, temp);
            coordinateList.add(coordinate);
            //System.out.println("x:"+coordinate[0]+",y:"+coordinate[1]);

            Map<String, Object> nodeMap = new HashMap<String, Object>();
            nodeMap.put("id", n);
            nodeMap.put("name", key);
            nodeMap.put("x", coordinate[0]);
            nodeMap.put("y", coordinate[1]);
            nodeMap.put("symbolSize", radius * 2);
            nodeMap.put("value", value);
            nodeList.add(nodeMap);
            Map<String, Object> edgeMap = new HashMap<String, Object>();
            if(n <= keywordMap.size()){
                edgeMap.put("id", n);
                edgeMap.put("source", 0);
                edgeMap.put("target", n);
                edgeList.add(edgeMap);
            }
            n++;
        }
        firstNodeMap.put("value", total);
        nodeList.add(firstNodeMap);
        resultMap.put("nodes", nodeList);
        resultMap.put("edges", edgeList);

        return resultMap;
    }

    public double[] getCoordinate(List<double[]> coordinateList, double distance, double originX, double originY, double originR, double radius, double max, int temp){
        Stack<Double> xStack = new Stack<Double>();
        Stack<Double> yStack = new Stack<Double>();
        double x = 0;
        double y = 0;
        xStack.push(x);
        yStack.push(y);
        while(!xStack.isEmpty()){
            x = xStack.pop().doubleValue();
            y = yStack.pop().doubleValue();
            double[] coordinate = getCoordinate(coordinateList, distance, originX, originY, originR, radius, x, y);
            if(coordinate != null){
                return coordinate;
            }else{
                double randX = getRandC(max, temp);
                xStack.push(randX);
                double randY = getRandC(max);
                yStack.push(randY);
            }
        }
        return new double[]{x, y};
        //return new double[]{xStack.pop().doubleValue(), yStack.pop().doubleValue()};
    }

    private double[] getCoordinate(List<double[]> coordinateList, double distance, double originX, double originY, double originR, double radius, double x, double y){
        double resultX = Math.pow(distance, 2) - Math.pow((x - originX), 2);
        double resultY = Math.pow(distance, 2) - Math.pow((y - originY), 2);
        if(resultX < 0 || resultY < 0){// x或y坐标太远
            return null;
        }
        boolean boolCCOrigin = judgeCircleCoincide(radius, originR, x, y, originX, originY);
        if(boolCCOrigin){// 和中心圆有重合
            return null;
        }
        if(coordinateList != null){
            for(double[] coordinate : coordinateList){
                boolean boolCCCoordinate = judgeCircleCoincide(radius, radius, x, y, coordinate[0], coordinate[1]);
                if(boolCCCoordinate){// 和已有圆重合
                    return null;
                }
            }
        }
        return new double[]{x, y};
    }

    private double getRandC(double max){
        return getRandomNumber(-max, max);
    }

    private double getRandC(double max, int temp){
        double randC = 0;// 随机坐标
        if(temp % 2 == 0){
            randC = getRandomNumber(0, max);
        }else{
            randC = getRandomNumber(-max, 0);
        }
        // randC = getRandomNumber(-max, max);
        return randC;
    }

    /**
     * 获取min~max之间的随机数
     * @param min
     * @param max
     * @return
     */
    public static double getRandomNumber(double min, double max){
        return min + Math.random() * (max - min);
    }

    /**
     * 判断两圆是否有重合
     * @param r1
     * @param r2
     * @param x1
     * @param y1
     * @param x2
     * @param y2
     * @return
     */
    public static boolean judgeCircleCoincide(double r1, double r2, double x1, double y1, double x2, double y2){
        return Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2) < Math.pow((r1 + r2), 2);
    }

    /**
     * 算出周边点的坐标
     * @param x
     * @param y
     * @param r
     * @param ao
     * @return
     */
    public static String coordinate(String x, String y,int r,int ao){
        String str="";
        double x1=0;
        double y1=0;
        if(null!=y&&!"".equals(y)){
            double y0=Double.parseDouble(y);
            y1   =   y0+r*Math.sin(ao*3.14/180);
            str = String.valueOf(y1);
        }
        if(null!=x&&!"".equals(x)){
            double x0=Double.parseDouble(x);
            x1   =   x0+r*Math.cos(ao*3.14/180); 
            str=String.valueOf(x1);
        }
        return str;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值