/**
* 封装力引导关系图的数据
* @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;
}
}
封装力引导图的的Java代码
最新推荐文章于 2023-11-26 15:41:25 发布