com.bstek.urule.console.servlet.diagram.ReteNodeLayout Maven / Gradle / Ivy
/*******************************************************************************
* Copyright 2017 Bstek
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
******************************************************************************/
package com.bstek.urule.console.servlet.diagram;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Jacky.gao
* @since 2015年1月29日
*/
public class ReteNodeLayout {
private final int leftMargin=50;
private final int topMargin=50;
private final int nodeWidth=30;
private final int nodeHeight=30;
public Box layout(NodeInfo rootNode){
List children=rootNode.getChildren();
if(children==null){
return null;
}
Map levelXPositionMap=new HashMap();
Map> nodeLevelMap=new HashMap>();
buildNodesLevelMap(children, nodeLevelMap);
int maxSize = buildMaxSize(nodeLevelMap)-1;
int maxWidth=maxSize*nodeWidth+maxSize*leftMargin;
int x=maxWidth/2+leftMargin+nodeWidth;
rootNode.setX(x);
rootNode.setY(5);
buildChildrenNodeLocation(children,rootNode,nodeLevelMap,levelXPositionMap);
Box box=new Box();
box.setWidth(maxWidth+leftMargin*2+nodeWidth);
int maxHeight=nodeLevelMap.size()*nodeHeight*3+topMargin*2;
box.setHeight(maxHeight);
return box;
}
private void buildChildrenNodeLocation(List nodes,NodeInfo rootNode,Map> nodeLevelMap,Map levelXPositionMap){
for(int i=0;i children=node.getChildren();
int xposition=0;
if(levelXPositionMap.containsKey(level)){
xposition=levelXPositionMap.get(level);
}
int rootX=rootNode.getX();
int levelSize=nodeLevelMap.get(level).size();
if(xposition==0){
if(levelSize>1){
int levelWidth=levelSize*nodeWidth+levelSize*leftMargin;
xposition=rootX-levelWidth/2-leftMargin;
}else{
xposition=rootX;
}
}
int x=leftMargin+nodeWidth+xposition;
if(levelSize==1){
x=xposition;
}
node.setX(x);
levelXPositionMap.put(level, x);
if(children!=null){
buildChildrenNodeLocation(children,rootNode,nodeLevelMap,levelXPositionMap);
}
}
}
private int buildMaxSize(Map> nodeLevelMap) {
int maxSize=1;
for(List list:nodeLevelMap.values()){
if(list.size()>maxSize){
maxSize=list.size();
}
}
return maxSize;
}
private void buildNodesLevelMap(List nodes,Map> nodeLevelMap){
for(NodeInfo node:nodes){
int level=node.getLevel();
if(nodeLevelMap.containsKey(level)){
List levelNodes=nodeLevelMap.get(level);
levelNodes.add(node);
}else{
List levelNodes=new ArrayList();
levelNodes.add(node);
nodeLevelMap.put(level, levelNodes);
}
List children=node.getChildren();
if(children==null){
continue;
}
buildNodesLevelMap(children, nodeLevelMap);
}
}
}