Exemplo n.º 1
0
 /// <summary>
 /// Sets the source and target of the given edge in a single atomic change.
 /// </summary>
 /// <param name="model">Model that contains the graph.</param>
 /// <param name="edge">Cell that specifies the edge.</param>
 /// <param name="source">Cell that specifies the new source terminal.</param>
 /// <param name="target">Cell that specifies the new target terminal.</param>
 public static void SetTerminals(mxIGraphModel model, Object edge, Object source, Object target)
 {
     model.BeginUpdate();
     try
     {
         model.SetTerminal(edge, source, true);
         model.SetTerminal(edge, target, false);
     }
     finally
     {
         model.EndUpdate();
     }
 }
Exemplo n.º 2
0
 /// <summary>
 /// Assigns the value for the given key in the styles of the given cells, or
 /// removes the key from the styles if the value is null.
 /// </summary>
 /// <param name="model">Model to execute the transaction in.</param>
 /// <param name="cells">Array of cells to be updated.</param>
 /// <param name="key">Key of the style to be changed.</param>
 /// <param name="value">New value for the given key.</param>
 public static void SetCellStyles(mxIGraphModel model, Object[] cells, String key, String value)
 {
     if (cells != null && cells.Length > 0)
     {
         model.BeginUpdate();
         try
         {
             for (int i = 0; i < cells.Length; i++)
             {
                 if (cells[i] != null)
                 {
                     String style = SetStyle(
                         model.GetStyle(cells[i]),
                         key, value);
                     model.SetStyle(cells[i], style);
                 }
             }
         }
         finally
         {
             model.EndUpdate();
         }
     }
 }
Exemplo n.º 3
0
 /// <summary>
 /// Sets the source and target of the given edge in a single atomic change.
 /// </summary>
 /// <param name="model">Model that contains the graph.</param>
 /// <param name="edge">Cell that specifies the edge.</param>
 /// <param name="source">Cell that specifies the new source terminal.</param>
 /// <param name="target">Cell that specifies the new target terminal.</param>
 public static void SetTerminals(mxIGraphModel model, Object edge, Object source, Object target)
 {
     model.BeginUpdate();
     try
     {
         model.SetTerminal(edge, source, true);
         model.SetTerminal(edge, target, false);
     }
     finally
     {
         model.EndUpdate();
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Executes the fast organic layout.
        /// </summary>
        /// <param name="parent"></param>
        public void execute(Object parent)
        {
            mxIGraphModel model = graph.Model;

            // Finds the relevant vertices for the layout
            int           childCount = model.GetChildCount(parent);
            List <Object> tmp        = new List <Object>(childCount);

            for (int i = 0; i < childCount; i++)
            {
                Object child = model.GetChildAt(parent, i);

                if (!IsCellIgnored(child))
                {
                    tmp.Add(child);
                }
            }

            vertexArray = tmp.ToArray();
            int n = vertexArray.Length;

            dispX         = new double[n];
            dispY         = new double[n];
            cellLocation  = new double[n][];
            isMoveable    = new bool[n];
            neighbours    = new int[n][];
            radius        = new double[n];
            radiusSquared = new double[n];

            minDistanceLimitSquared = minDistanceLimit * minDistanceLimit;

            if (forceConstant < 0.001)
            {
                forceConstant = 0.001;
            }

            forceConstantSquared = forceConstant * forceConstant;

            // Create a map of vertices first. This is required for the array of
            // arrays called neighbours which holds, for each vertex, a list of
            // ints which represents the neighbours cells to that vertex as
            // the indices into vertexArray
            for (int i = 0; i < vertexArray.Length; i++)
            {
                Object vertex = vertexArray[i];
                cellLocation[i] = new double[2];

                // Set up the mapping from array indices to cells
                indices[vertex] = i;
                mxGeometry bounds = model.GetGeometry(vertex);

                // Set the X,Y value of the internal version of the cell to
                // the center point of the vertex for better positioning
                double width  = bounds.Width;
                double height = bounds.Height;

                // Randomize (0, 0) locations
                double x = bounds.X;
                double y = bounds.Y;

                cellLocation[i][0] = x + width / 2.0;
                cellLocation[i][1] = y + height / 2.0;

                radius[i]        = Math.Min(width, height);
                radiusSquared[i] = radius[i] * radius[i];
            }

            for (int i = 0; i < n; i++)
            {
                dispX[i]      = 0;
                dispY[i]      = 0;
                isMoveable[i] = graph.IsCellMovable(vertexArray[i]);

                // Get lists of neighbours to all vertices, translate the cells
                // obtained in indices into vertexArray and store as an array
                // against the orginial cell index
                Object[] edges = mxGraphModel.GetEdges(model, vertexArray[i]);
                Object[] cells = mxGraphModel.GetOpposites(model, edges,
                                                           vertexArray[i], true, true);

                neighbours[i] = new int[cells.Length];

                for (int j = 0; j < cells.Length; j++)
                {
                    int?index = indices[cells[j]];

                    // Check the connected cell in part of the vertex list to be
                    // acted on by this layout
                    if (index != null)
                    {
                        neighbours[i][j] = (int)index;
                    }

                    // Else if index of the other cell doesn't correspond to
                    // any cell listed to be acted upon in this layout. Set
                    // the index to the value of this vertex (a dummy self-loop)
                    // so the attraction force of the edge is not calculated
                    else
                    {
                        neighbours[i][j] = i;
                    }
                }
            }
            temperature = initialTemp;

            // If max number of iterations has not been set, guess it
            if (maxIterations == 0)
            {
                maxIterations = (int)(20 * Math.Sqrt(n));
            }

            // Main iteration loop
            for (iteration = 0; iteration < maxIterations; iteration++)
            {
                if (!allowedToRun)
                {
                    return;
                }

                // Calculate repulsive forces on all vertices
                calcRepulsion();

                // Calculate attractive forces through edges
                calcAttraction();

                calcPositions();
                reduceTemperature();
            }

            // Moved cell location back to top-left from center locations used in
            // algorithm
            model.BeginUpdate();
            try
            {
                double?minx = null;
                double?miny = null;

                for (int i = 0; i < vertexArray.Length; i++)
                {
                    Object     vertex = vertexArray[i];
                    mxGeometry geo    = model.GetGeometry(vertex);

                    if (geo != null)
                    {
                        cellLocation[i][0] -= geo.Width / 2.0;
                        cellLocation[i][1] -= geo.Height / 2.0;

                        geo = geo.Clone();

                        geo.X = graph.Snap(cellLocation[i][0]);
                        geo.Y = graph.Snap(cellLocation[i][1]);

                        model.SetGeometry(vertex, geo);

                        if (minx == null)
                        {
                            minx = geo.X;
                        }
                        else
                        {
                            minx = Math.Min((double)minx, geo.X);
                        }

                        if (miny == null)
                        {
                            miny = geo.Y;
                        }
                        else
                        {
                            miny = Math.Min((double)miny, geo.Y);
                        }
                    }
                }

                // Modifies the cloned geometries in-place. Not needed
                // to clone the geometries again as we're in the same
                // undoable change.
                if (minx != null || miny != null)
                {
                    for (int i = 0; i < vertexArray.Length; i++)
                    {
                        Object     vertex = vertexArray[i];
                        mxGeometry geo    = model.GetGeometry(vertex);

                        if (geo != null)
                        {
                            if (minx != null)
                            {
                                geo.X -= ((double)minx) - 1;
                            }

                            if (miny != null)
                            {
                                geo.Y -= ((double)miny) - 1;
                            }
                        }
                    }
                }
            }
            finally
            {
                model.EndUpdate();
            }
        }
Exemplo n.º 5
0
        public void execute(Object parent)
        {
            mxIGraphModel model = graph.Model; //.GetModel();

            // Moves the vertices to build a circle. Makes sure the
            // radius is large enough for the vertices to not
            // overlap
            model.BeginUpdate();
            try
            {
                // Gets all vertices inside the parent and finds
                // the maximum dimension of the largest vertex
                double        max        = 0;
                Double        top        = 0;
                Double        left       = 0;
                List <Object> vertices   = new List <Object>();
                int           childCount = model.GetChildCount(parent);

                for (int i = 0; i < childCount; i++)
                {
                    Object cell = model.GetChildAt(parent, i);

                    if (!isVertexIgnored(cell))
                    {
                        vertices.add(cell);
                        mxRectangle bounds = getVertexBounds(cell);

                        if (top == null)
                        {
                            top = bounds.getY();
                        }
                        else
                        {
                            top = Math.Min(top, bounds.getY());
                        }

                        if (left == null)
                        {
                            left = bounds.getX();
                        }
                        else
                        {
                            left = Math.Min(left, bounds.getX());
                        }

                        max = Math.Max(max, Math.Max(bounds.getWidth(), bounds
                                                     .getHeight()));
                    }
                    else if (!isEdgeIgnored(cell))
                    {
                        if (isResetEdges())
                        {
                            graph.resetEdge(cell);
                        }

                        if (isDisableEdgeStyle())
                        {
                            setEdgeStyleEnabled(cell, false);
                        }
                    }
                }

                int    vertexCount = vertices.size();
                double r           = Math.Max(vertexCount * max / Math.PI, radius);

                // Moves the circle to the specified origin
                if (moveCircle)
                {
                    left = x0;
                    top  = y0;
                }

                circle(vertices.ToArray(), r, left, top);
            }
            finally
            {
                model.EndUpdate();
            }
        }