⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gemlayoutalgorithm.java

📁 用JGraph编的软件
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                                               "setting new Vertice Values"};
    
    /**
     * to identify the different phases of the algorithm for the progress dialog
     */
    private final static int PHASE_INITIALISATION = 0;
    /**
     * to identify the different phases of the algorithm for the progress dialog
     */
    private final static int PHASE_CALCULATION    = 1;
    /**
     * to identify the different phases of the algorithm for the progress dialog
     */
    private final static int PHASE_END            = 2;
    
    /**
     * to identify for the method {@link #loadRuntimeValues(int)}, that the 
     * algorithm wants to perform a new run
     */
    protected final static int VALUES_PUR = 0;
    /**
     * to identify for the method {@link #loadRuntimeValues(int)}, that the 
     * algorithm wants to perform a layout update
     */
    protected final static int VALUES_INC = 1;
    
    /**
     * algorithm used for optimizing the result of this algorithm
     */
    private AnnealingLayoutAlgorithm optimizationAlgorithm;
    
    /**
     * switches the usage of the optimizing algorithm
     */
    private boolean        useOptimizeAlgorithm;
    
    /**
     * configuration of the optimizing algorithm
     */
    private Properties      optimizationAlgorithmConfig;
    /**
     * Switches clustering for the layout update process on/off
     */
    private boolean         isClusteringEnabled;
    /**
     * The initial temperature for clusters. It is recommended, that this value
     * is lower than {@link #initTemperature} to get a good looking layout
     */
    private double          clusterInitTemperature;
    /**
     * Scales forces, that are effecting clusters. It is recommendet to take
     * a value between 1.0 and 0.0. This garanties, that clusters move slower
     * than other cells. That rises the chance of getting a good looking layout
     * after the calculation.
     */
    private double          clusterForceScalingFactor;
    /**
     * Effects, how many clusters are created, when the layout update process
     * starts. This affects the initial number of clusters, which is the number
     * of cells available minus the number of cells to layout. The result of
     * that term is divided by this factor, to get the maximum number of 
     * clusters. After this calculation, the clustering algorithm tries to
     * minimize the number of clusters, so there might be less clusters than 
     * the maximum number.
     */
    private double          clusteringFactor;
    
    /**
     * The initial size for the layout update method perimeter. This describes
     * a radius around an inserted cell. Every other inserted cell in this
     * radius increases the radius by {@link #perimeterSizeInc}. After finishing
     * increasing the radius, every cell, from the cells, that are already 
     * layouted, in the radius is added to the list of cells, that'll gain a
     * new position during the layout update process. This should bring up
     * the behaviour, that the previous layouted cells make space for the layout 
     * of the inserted cells.
     */
    private double perimeterInitSize;
    
    /**
     * Inserted cells whithin a radius of {@link #perimeterInitSize} around
     * a inserted cell are counted. After counting the inserted cells around
     * a inserted cell, the initial radius is increased by this increase value
     * times the number of inserted cells around the inserted cell. Every
     * previous layouted cell in the resulting radius around the inserted cell
     * is going to be layouted again.
     */
    private double perimeterSizeInc;
    
    private boolean isDebugging = false;
        
/******************************************************************************/
/**
 * Constructs a new GEM Layout Algorithm.
 */
    public GEMLayoutAlgorithm(AnnealingLayoutAlgorithm optimizer){
        cellList      = new ArrayList();
        applyCellList = new ArrayList();
        edgeList      = new ArrayList();
        optimizationAlgorithm = optimizer;
    }

/******************************************************************************/
	/**
     * Starts the Calculation of a new layout with the GEM-Algorithm
     * @param jgraph View of Graphnodes
     * @param graphCells List of all nodes the layout should be calculated for
     * @param configuration contains the initial values for the Algorithm
     * @see #initialize()
     * @see #calculate()
	 * @see de.fzi.echidna.layout.LayoutAlgorithm#perform(MyJGraph,List,Properties)
	 */
	public void perform(JGraph    graph,
                         boolean   applyToAll,
                         Properties configuration) {
                            
        isRunning = true;
                            
        jgraph = graph;
        config = configuration;
        
        jgraph.getModel().addGraphModelListener(this);
        
                         
        cellList      = new ArrayList();
        applyCellList = new ArrayList();
        
        //extracting the nodes from jgraph, the algorithm should be performed on
        getNodes(jgraph,applyToAll);
        
        
        loadRuntimeValues(VALUES_PUR);

        long starttime = System.currentTimeMillis();
        //ALGORITHM START
        boolean isCanceled = initialize();//initializes algorithm; sets the startvalues in cells
                
        if( !isCanceled )
             isCanceled = calculate();//performs the algorithm on the cells
        //ALGORITHM END

        if( !isCanceled && useOptimizeAlgorithm )
            isCanceled = optimizationAlgorithm.performOptimization(applyCellList,cellList,edgeList,optimizationAlgorithmConfig,dlgProgress);

        if( !isCanceled )
            correctCoordinates();
                                
        //sets the calculated data into cellView's bounds if not canceled
        if( !isCanceled ) 
            isCanceled = setNewCoordinates(jgraph);
                    
        //removes the temporary data, stored by the algorithm, from the nodes
        removeTemporaryLayoutDataFromCells();

        dlgProgress.setMessage("Algorithm finished");
        
        //prepares for next calculation (maybe useless, because instance of 
        //this algorithm might be thrown away)        
        dlgProgress.setVisible(false);
        
        isRunning = false;
	}
    
/******************************************************************************/
/**
 * Loads the actual desired values from the {@link #config configuration} to
 * the fields, where they are used later.
 * 
 * @param valueID {@link #VALUES_PUR} for a normal run or {@link #VALUES_INC}
 * for a layout update process.
 */
    protected void loadRuntimeValues(int valueID){
        
        maxRounds = applyCellList.size() * 4;//estimated value; reached rarely
        
        countRounds = 0;//start value; counts the rounds in calculate()

        isActive = isTrue((String)
                     config.get(GEMLayoutController.KEY_LAYOUT_UPDATE_ENABLED));
        
        recursionDepth = Integer.parseInt((String)config.get(
                                  GEMLayoutController.KEY_LAYOUT_UPDATE_DEPTH));
                                  
        layoutUpdateMethod = (String) 
                       config.get(GEMLayoutController.KEY_LAYOUT_UPDATE_METHOD);
            
        if( valueID == VALUES_PUR ){
        
            initTemperature          = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_INIT_TEMPERATURE));
            minTemperature           = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_MIN_TEMPERATURE));
            maxTemperature           = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_MAX_TEMPERATURE));
            prefEdgeLength           = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_PREF_EDGE_LENGTH));
            gravitation              = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_GRAVITATION));
            randomImpulseRange       = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_RANDOM_IMPULSE_RANGE));        
            overlapDetectWidth       = Double.parseDouble((String)config.get(
                          GEMLayoutController.KEY_OVERLAPPING_DETECTION_WIDTH));
            overlapPrefDistance      = Double.parseDouble((String)config.get(
                            GEMLayoutController.KEY_OVERLAPPING_PREF_DISTANCE));
            shouldEndPerAverage      = isTrue((String)config.get(
                               GEMLayoutController.KEY_COMPUTE_PERMUTATION));
            shouldComputePermutation = isTrue((String)config.get(
                               GEMLayoutController.KEY_END_CONDITION_AVERAGE));
            avoidOverlapping         = isTrue((String)config.get(
                               GEMLayoutController.KEY_AVOID_OVERLAPPING));
            alphaOsc = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_ALPHA_OSC));
            alphaRot = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_ALPHA_ROT));
            sigmaOsc = Double.parseDouble((String)config.get(
                               GEMLayoutController.KEY_SIGMA_OSC));
            sigmaRot = Double.parseDouble((String)config.get(    //gets 1/x
                               GEMLayoutController.KEY_SIGMA_ROT));
            useOptimizeAlgorithm = isTrue((String)config.get(
                           GEMLayoutController.KEY_OPTIMIZE_ALGORITHM_ENABLED));
            optimizationAlgorithmConfig = (Properties) config.get(
                             GEMLayoutController.KEY_OPTIMIZE_ALGORITHM_CONFIG);

            
        }
        else if( valueID == VALUES_INC ){
            
            initTemperature          = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_INIT_TEMPERATURE));
            minTemperature           = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_MIN_TEMPERATURE));
            maxTemperature           = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_MAX_TEMPERATURE));
            prefEdgeLength           = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_PREF_EDGE_LENGTH));
            gravitation              = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_GRAVITATION));
            randomImpulseRange       = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_RANDOM_IMPULSE_RANGE));        
            overlapDetectWidth       = Double.parseDouble((String)config.get(
            GEMLayoutController.KEY_LAYOUT_UPDATE_OVERLAPPING_DETECTION_WIDTH));
            overlapPrefDistance      = Double.parseDouble((String)config.get(
              GEMLayoutController.KEY_LAYOUT_UPDATE_OVERLAPPING_PREF_DISTANCE));
            shouldEndPerAverage      = isTrue((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_COMPUTE_PERMUTATION));
            shouldComputePermutation = isTrue((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_END_CONDITION_AVERAGE));
            avoidOverlapping         = isTrue((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_AVOID_OVERLAPPING));
                                    
            alphaOsc = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_ALPHA_OSC));
            alphaRot = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_ALPHA_ROT));
            sigmaOsc = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_SIGMA_OSC));
            sigmaRot = Double.parseDouble((String)config.get(    //gets 1/x
                 GEMLayoutController.KEY_LAYOUT_UPDATE_SIGMA_ROT));
            useOptimizeAlgorithm = isTrue((String)config.get(
             GEMLayoutController.KEY_LAYOUT_UPDATE_OPTIMIZE_ALGORITHM_ENABLED));
            optimizationAlgorithmConfig = (Properties) config.get(
               GEMLayoutController.KEY_LAYOUT_UPDATE_OPTIMIZE_ALGORITHM_CONFIG);
            perimeterInitSize = Double.parseDouble((String)config.get(
             GEMLayoutController.KEY_LAYOUT_UPDATE_METHOD_PERIMETER_INIT_SIZE));
            perimeterSizeInc = Double.parseDouble((String)config.get(
              GEMLayoutController.KEY_LAYOUT_UPDATE_METHOD_PERIMETER_SIZE_INC));
            isClusteringEnabled = isTrue((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_CLUSTERING_ENABLED));
            clusterInitTemperature = Double.parseDouble((String)config.get(
            GEMLayoutController.KEY_LAYOUT_UPDATE_CLUSTERING_INIT_TEMPERATURE));
            clusterForceScalingFactor = Double.parseDouble((String)config.get(
        GEMLayoutController.KEY_LAYOUT_UPDATE_CLUSTERING_FORCE_SCALING_FACTOR));
            clusteringFactor = Double.parseDouble((String)config.get(
                 GEMLayoutController.KEY_LAYOUT_UPDATE_CLUSTERING_FACTOR));
        }
        //with that line sigmaRot will be 1/(x*cellCount) with x is configurable
        sigmaRot *= 1.0 / (double) (applyCellList.size() == 0 ? 1 : applyCellList.size());
    }

/******************************************************************************/
/**
 * Helping method. Transforms a String, containing only the characters "true" or
 * "false", regardless if upper or lower case, into a boolean value.
 * 
 * @param boolValue String containing a boolean value
 * @return boolean value represented by the given string
 */
    protected boolean isTrue(String boolValue){
        if( boolValue != null ){
            if( "TRUE".equals(boolValue.toUpperCase()) ){
                return true;
            }
            else if( "FALSE".equals(boolValue.toUpperCase()) ){
                return false;
            }
        }
        return false;        
    }

/******************************************************************************/    
/**
 * Extracts the Cells from JGraph and fills {@link #applyCellList}, 
 * {@link #cellList} and {@link #edgeList}. If applyToAll is 
 * <b><code>false</code></b> only in jgraph selected cells are added to
 * {@link #applyCellList} else all cells are added.
 * 
 * @param jgraph actual instance of jgraph
 * @param applyToAll determines, if this algorithm should be performed on all 
 * cells or only on the selected. 
 */
    private void getNodes(JGraph jgraph, boolean applyToAll){
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -