Anton 5 rokov pred
rodič
commit
c874d3cebf

+ 28 - 1
DrawGraph/Algorithm.cs

@@ -8,7 +8,7 @@ namespace DrawGraph
 {
     public class Algorithm
     {
-        public static int MinDistance(int[] path, bool[] includedToPath, int n)
+        private static int MinDistance(int[] path, bool[] includedToPath, int n)
         {
             // Initialize min value 
             int min = int.MaxValue, min_index = -1;
@@ -56,5 +56,32 @@ namespace DrawGraph
 
             return path[finishIndex];
         }
+        
+        public static LinkedList<Node> DepthSearch(Node[] node, Edge[] edge, int sourceIndex, int targetIndex)
+        {
+            var visited = new HashSet<Node>();
+            var path = new LinkedList<Node>();
+            Dfs(node[sourceIndex], node[targetIndex], visited, path, edge);
+            if (path.Count > 0)
+                path.AddFirst(node[sourceIndex]);
+            return path;
+        }
+
+        private static bool Dfs(Node node, Node goal,HashSet<Node> visited, LinkedList<Node> path, Edge[] edges)
+        {
+            if (Node.Compare(node, goal))
+                return true;
+
+            visited.Add(node);
+            foreach(var edge in edges.Where(x=>!visited.Contains(x.SourceNode) || !visited.Contains(x.TargetNode)))
+            {
+                if(Dfs(edge.TargetNode, goal, visited, path, edges))
+                {
+                    path.AddFirst(edge.TargetNode);
+                    return true;
+                }
+            }
+            return false;
+        }
     }
 }

+ 34 - 1
DrawGraph/DrawGraph.csproj

@@ -31,11 +31,39 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=1.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.1.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
+    </Reference>
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
     <Reference Include="System" />
+    <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
+    </Reference>
     <Reference Include="System.Core" />
     <Reference Include="System.Drawing" />
+    <Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Numerics" />
+    <Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.6.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Text.Encodings.Web, Version=4.0.4.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Text.Encodings.Web.4.6.0\lib\netstandard2.0\System.Text.Encodings.Web.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Text.Json, Version=4.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Text.Json.4.6.0\lib\net461\System.Text.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
+    </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
@@ -50,11 +78,16 @@
     <Compile Include="ArrowLineBase.cs" />
     <Compile Include="Edge.cs" />
     <Compile Include="Export.cs" />
-    <Compile Include="GraphState.cs" />
+    <Compile Include="GraphAction.cs" />
+    <Compile Include="Import.cs" />
     <Compile Include="Matrix.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Settings.cs" />
     <Compile Include="Node.cs" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="packages.config" />
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>

+ 25 - 41
DrawGraph/Edge.cs

@@ -1,70 +1,49 @@
-using System.Drawing;
-using System.Windows.Shapes;
+using System;
+using System.Xml.Serialization;
 
 namespace DrawGraph
 {
     public class Edge
     {
-        public Line Line { get; }
-        public ArrowLine ArrowLine { get; }
-        public Node StartNode { get; }
-        public Node FinishNode { get; }
+        [XmlAttribute("source")]
+        public Node SourceNode { get; }
+        [XmlAttribute("target")]
+        public Node TargetNode { get; }
+        [XmlAttribute("weight")]
         public int? Weight { get; set; }
         public bool IsFocused { get; }
 
-        public Edge(Line line, Node v1, Node v2)
+        public Edge(Node v1, Node v2, bool IsFocused)
         {
-            Line = line;
-            StartNode = v1;
-            FinishNode = v2;
-            IsFocused = false;
+            SourceNode = v1;
+            TargetNode = v2;
+            this.IsFocused = IsFocused;
         }
 
-        public Edge(ArrowLine line, Node v1, Node v2)
+        public Edge(Node sourceNode, Node targetNode, int weight, bool IsFocused)
         {
-            ArrowLine = line;
-            StartNode = v1;
-            FinishNode = v2;
-            IsFocused = true;
-        }
-
-        public Edge(Line line, Node v1, Node v2, int weight)
-        {
-            Line = line;
-            StartNode = v1;
-            FinishNode = v2;
+            SourceNode = sourceNode;
+            TargetNode = targetNode;
             Weight = weight;
-            IsFocused = false;
-        }
-        public Edge(ArrowLine line, Node v1, Node v2, int weight)
-        {
-            ArrowLine = line;
-            StartNode = v1;
-            FinishNode = v2;
-            IsFocused = true;
-            Weight = weight;
-
-            ArrowLine.X1 = v1.CenterByX;
-            ArrowLine.X2 = v2.CenterByX;
-            ArrowLine.Y1 = v1.CenterByY;
-            ArrowLine.Y2 = v2.CenterByY;
-            ArrowLine.StrokeThickness = 2;
+            this.IsFocused = IsFocused;
         }
 
         public static double GetCenterByX(Edge edge)
         {
-            var x = (edge.FinishNode.X + edge.StartNode.X) / 2;
+            var x = (edge.TargetNode.X + edge.SourceNode.X) / 2;
             return x;
         }
 
         public static double GetCenterByY(Edge edge)
         {
-            var y = (edge.FinishNode.Y + edge.StartNode.Y) / 2;
+            var y = (edge.TargetNode.Y + edge.SourceNode.Y) / 2;
             return y;
         }
 
         public static bool IsCursorOnNode(System.Windows.Point cursorPosition, Node Node)
         {
+            try
+            {
                 if (Node.CenterByX - cursorPosition.X <= Settings.NodeWidth / 2 &&
                     Node.CenterByX - cursorPosition.X >= 0)
                 {
@@ -88,11 +67,16 @@ namespace DrawGraph
                 }
 
                 return false;
+            }
+            catch(Exception ex)
+            {
+                throw new Exception(ex.Message);
+            }
         }
 
         public static bool IsNodeBelongToEdge(Edge edge, Node Node)
         {
-            if (Node.Compare(Node, edge.StartNode) || Node.Compare(Node, edge.FinishNode))
+            if (Node.Compare(Node, edge.SourceNode) || Node.Compare(Node, edge.TargetNode))
                 return true;
 
             return false;

+ 116 - 14
DrawGraph/Export.cs

@@ -1,10 +1,12 @@
-using System.IO;
+using System;
+using System.IO;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
 using System.Xml;
 using System.Windows.Media.Imaging;
-using Microsoft.Win32;
+using System.Text.Json;
+using System.Text;
 
 namespace DrawGraph
 {
@@ -58,28 +60,128 @@ namespace DrawGraph
             }
         }
 
-        public static void ToGraphML(Node[] nodes)
+        public static void ToGraphML(Node[] nodes, bool direction, string path)
         {
-            //<? xml version = "1.0" encoding = "UTF-8" ?>
-            //    < graphml xmlns = "http://graphml.graphdrawing.org/xmlns"
-            //xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance"
-            //xsi: schemaLocation = "http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd" >
             XmlDocument doc = new XmlDocument();
             XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
+            var root = doc.CreateElement("graph");
+            var attr = doc.CreateAttribute("id");
+            attr.InnerText = "G";
+            root.Attributes.Append(attr);
+            var dir = doc.CreateAttribute("edgedefault");
+            dir.InnerText = direction ? "directed" : "undirected";
+            root.Attributes.Append(dir);
             doc.AppendChild(declaration);
+            doc.AppendChild(root);
             XmlProcessingInstruction pi =
                 doc.CreateProcessingInstruction("graphml", "xmlns=\"http://graphml.graphdrawing.org/xmlns \" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance \" xsi: schemaLocation = \"http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd \"");
-            SaveFileDialog sfd = new SaveFileDialog();
+            doc.InsertBefore(pi, doc.ChildNodes[1]);
+
+            for (int i = 0; i < nodes.Length; i++)
+            {
+                XmlNode Node = doc.CreateElement("node");
+                var attribute = doc.CreateAttribute("id");
+                attribute.InnerText = "n" + i.ToString();
+                Node.Attributes.Append(attribute);
+                root.AppendChild(Node);
+            }
+            doc.Save(path);
+        }
+
+        public static void ToGraphML(Node[] nodes, Edge[] edges, bool direction, string path)
+        {
+            XmlDocument doc = new XmlDocument();
+            XmlDeclaration declaration = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
             var root = doc.CreateElement("graph");
-            foreach (var node in nodes)
+            var attr = doc.CreateAttribute("id");
+            attr.InnerText = "G";
+            root.Attributes.Append(attr);
+            var dir = doc.CreateAttribute("edgedefault");
+            dir.InnerText = direction ? "directed" : "undirected";
+            root.Attributes.Append(dir);
+            doc.AppendChild(declaration);
+            doc.AppendChild(root);
+            XmlProcessingInstruction pi =
+                doc.CreateProcessingInstruction("graphml", "xmlns=\"http://graphml.graphdrawing.org/xmlns \" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance \" xsi: schemaLocation = \"http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd \"");
+            doc.InsertBefore(pi, doc.ChildNodes[1]);
+
+            for (int i = 0; i < nodes.Length; i++)
+            {
+                XmlNode node = doc.CreateElement("node");
+                var attribute = doc.CreateAttribute("id");
+                attribute.InnerText = "n" + i.ToString();
+                node.Attributes.Append(attribute);
+                var XCoord = doc.CreateAttribute("positionX");
+                XCoord.InnerText = nodes[i].X.ToString();
+                node.Attributes.Append(XCoord);
+                var YCoord = doc.CreateAttribute("positionY");
+                YCoord.InnerText = nodes[i].Y.ToString();
+                node.Attributes.Append(YCoord);
+                root.AppendChild(node);
+            }
+
+            for (int i = 0; i < edges.Length; i++)
             {
-                var XNode = doc.CreateElement("node");
+                XmlNode edge = doc.CreateElement("edge");
+                var sourceAttribute = doc.CreateAttribute("source");
+                for (int j = 0; j < nodes.Length; j++)
+                    if (Node.Compare(edges[i].SourceNode, nodes[j]))
+                        sourceAttribute.InnerText = "n" + j.ToString();
+                edge.Attributes.Append(sourceAttribute);
+                var targetAttribute = doc.CreateAttribute("target");
+                for (int j = 0; j < nodes.Length; j++)
+                    if (Node.Compare(edges[i].TargetNode, nodes[j]))
+                        targetAttribute.InnerText = "n" + j.ToString();
+                edge.Attributes.Append(targetAttribute);
+                if (edges[i].Weight > 0)
+                {
+                    var weightAttr = doc.CreateAttribute("weight");
+                    weightAttr.InnerText = edges[i].Weight.ToString();
+                    edge.Attributes.Append(weightAttr);
+                }
+                root.AppendChild(edge);
             }
-            sfd.Filter = "GraphML files (*.graphml)|*.graphml";
-            if (sfd.ShowDialog() == true)
+            doc.Save(path);
+        }
+
+        public static void ToJSON(
+            Node[] nodes, Edge[] edges, bool direction, string path)
+        {
+            if (edges is null)
+            {
+                throw new ArgumentNullException(nameof(edges));
+            }
+
+            JsonSerializerOptions options = new JsonSerializerOptions()
+            {
+                AllowTrailingCommas = true,
+                IgnoreNullValues = false,
+                PropertyNameCaseInsensitive = true
+            };
+            Type type = typeof(Node);
+            string[] json = new string[nodes.Length];
+            for(int i = 0; i < nodes.Length; i++)
             {
-                doc.Save(sfd.FileName);
+                json[i] = JsonSerializer.Serialize(nodes[i], type, options);
+                if (File.Exists(path))
+                {
+                    using(FileStream fs = new FileStream(path, FileMode.Append))
+                    {
+                        byte[] Byte = Encoding.ASCII.GetBytes(json[i]);
+                        fs.Write(Byte, 0, Byte.Length);
+                    }
+                }
+                else
+                {
+                    
+                    using(FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
+                    {
+                        path += "graph.json";
+                        byte[] Byte = Encoding.ASCII.GetBytes(json[i]);
+                        fs.Write(Byte, 0, Byte.Length);
+                    }
+                }
             }
         }
     }
-}
+}

+ 0 - 14
DrawGraph/GraphState.cs

@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace DrawGraph
-{
-    public class GraphState
-    {
-        public static bool focused = false;
-        public static bool named = false;
-    }
-}

+ 182 - 12
DrawGraph/Matrix.cs

@@ -1,7 +1,17 @@
-namespace DrawGraph
+using System;
+using System.Collections.Generic;
+using System.Windows.Controls;
+
+namespace DrawGraph
 {
     public class Matrix
     {
+        /// <summary>
+        /// Creates an adjacency matrix from given nodes and edges
+        /// </summary>
+        /// <param name="nodes">Array of nodes</param>
+        /// <param name="edges">Array of edges</param>
+        /// <returns>Adjacency matrix in 2D int array</returns>
         public static int[,] AdjacencyCreate(Node[] nodes, Edge[] edges)
         {
             int length = nodes.Length;
@@ -19,21 +29,21 @@
                             var edge = edges[k];
                             if (edge.IsFocused)
                             {
-                                if (Node.Compare(edge.FinishNode, Node1) &&
-                                    Node.Compare(edge.StartNode, Node2))
+                                if (Node.Compare(edge.TargetNode, Node1) &&
+                                    Node.Compare(edge.SourceNode, Node2))
                                     if (edge.Weight > 0)
                                         matrix[i, j] = (int) edge.Weight;
                                     else
                                         matrix[i, j] = 1;
-                                else if (Node.Compare(edge.StartNode, Node1) &&
-                                         Node.Compare(edge.FinishNode, Node2))
+                                else if (Node.Compare(edge.SourceNode, Node1) &&
+                                         Node.Compare(edge.TargetNode, Node2))
                                     if (edge.Weight > 0)
                                         matrix[i, j] = (int) edge.Weight;
                             }
                             else
                             {
-                                if (Node.Compare(edge.FinishNode, Node1) &&
-                                    Node.Compare(edge.StartNode, Node2))
+                                if (Node.Compare(edge.TargetNode, Node1) &&
+                                    Node.Compare(edge.SourceNode, Node2))
                                     if (edge.Weight > 0)
                                     {
                                         matrix[i, j] = (int) edge.Weight;
@@ -44,8 +54,8 @@
                                         matrix[i, j] = 1;
                                         InvertElement(matrix, i, j);
                                     }
-                                else if (Node.Compare(edge.StartNode, Node1) &&
-                                         Node.Compare(edge.FinishNode, Node2))
+                                else if (Node.Compare(edge.SourceNode, Node1) &&
+                                         Node.Compare(edge.TargetNode, Node2))
                                     if (edge.Weight > 0)
                                     {
                                         matrix[i, j] = (int) edge.Weight;
@@ -68,11 +78,31 @@
 
             return matrix;
         }
-        public static int[,] InvertElement(int[,] matrix, int indexX, int indexY)
+        /// <summary>
+        /// Creates an adjacency matrix from given nodes and edges
+        /// </summary>
+        /// <param name="nodes">List of nodes</param>
+        /// <param name="edges">List of edges</param>
+        /// <returns>Adjacency matrix in 2D int array</returns>
+        public static int[,] AdjacencyCreate(List<Node> nodes, List<Edge> edges)
+        {
+            Node[] node = nodes.ToArray();
+            Edge[] edge = edges.ToArray();
+            
+            return AdjacencyCreate(node, edge);
+        }
+        private static int[,] InvertElement(int[,] matrix, int indexX, int indexY)
         {
             matrix[indexY, indexX] = matrix[indexX, indexY];
             return matrix;
         }
+
+        /// <summary>
+        /// Creates an incidence matrix from given nodes and edges
+        /// </summary>
+        /// <param name="nodes">Array of nodes</param>
+        /// <param name="edges">Array of edges</param>
+        /// <returns>Incidence matrix in 2D int array</returns>
         public static int[,] IncidenceCreate(Node[] nodes, Edge[] edges)
         {
             var rows = nodes.Length;
@@ -87,11 +117,11 @@
                     var edge = edges[j];
 
 
-                    if (Node.Compare(Node, edge.FinishNode) && edge.IsFocused)
+                    if (Node.Compare(Node, edge.TargetNode) && edge.IsFocused)
                         matrix[i, j] = -1;
                     else
                     {
-                        if (Node.Compare(Node, edge.FinishNode) || Node.Compare(Node, edge.StartNode))
+                        if (Node.Compare(Node, edge.TargetNode) || Node.Compare(Node, edge.SourceNode))
                             if (edge.Weight > 0)
                                 matrix[i, j] = (int)edge.Weight;
                             else
@@ -104,5 +134,145 @@
 
             return matrix;
         }
+        /// <summary>
+        /// Creates an incidence matrix from given nodes and edges
+        /// </summary>
+        /// <param name="nodes">List of nodes</param>
+        /// <param name="edges">List of edges</param>
+        /// <returns>Incidence matrix in 2D int array</returns>
+        public static int[,] IncidenceCreate(List<Node> nodes, List<Edge> edges)
+        {
+            Node[] node = nodes.ToArray();
+            Edge[] edge = edges.ToArray();
+            return IncidenceCreate(node, edge);
+        }
+
+        /// <summary>
+        /// Creates nodes and edges from adjacency matrix
+        /// </summary>
+        /// <param name="matrix">Adjacency matrix</param>
+        /// <returns>Tuple of node and edge array</returns>
+        public static Tuple<Node[], Edge[]> FromAdjacency(int[,] matrix)
+        {
+            Random random = new Random();
+            Node[] nodes = new Node[matrix.GetLength(0)];
+            Edge[] edges = new Edge[0];
+            int[,] buffer = new int[edges.Length, edges.Length];
+            for (int i = 0; i < nodes.Length; i++)
+            {
+                nodes[i] = new Node(random.Next(0, Settings.CanvasWidth), random.Next(0, Settings.CanvasHeight));
+            }
+
+            for (int i = 0; i < nodes.Length; i++)
+                for (int j = 0; j < nodes.Length; j++)
+                {
+                    if (matrix[i, j] > 0 && matrix[i, j] == matrix[j, i])
+                    {
+                        buffer[j, i] = 1;
+                        buffer[i, j] = 1;
+                    }
+                    else if (matrix[i, j] > 0 && matrix[i, j] != matrix[j, i])
+                        buffer[i, j] = 1;
+                    else
+                        buffer[i, j] = 0;
+                }
+
+            for (int i = 0; i < nodes.Length; i++)
+            {
+                var sourceNode = nodes[i];
+                for (int j = 0; j < nodes.Length; j++)
+                {
+                    var targetNode = nodes[j];
+                    if (buffer[i, j] != 1)
+                    {
+                        if (matrix[i, j] > 0 && matrix[j, i] == matrix[i, j])
+                        {
+                            Array.Resize(ref edges, edges.Length + 1);
+                            var index = edges.Length - 1;
+                            edges[index] = new Edge(sourceNode, targetNode, false);
+                        }
+                        else if (matrix[i, j] > 0 && matrix[i, j] != matrix[j, i])
+                        {
+                            Array.Resize(ref edges, edges.Length + 1);
+                            var index = edges.Length - 1;
+                            edges[index] = new Edge(sourceNode, targetNode, true);
+                        }
+                    }
+                }
+            }
+            return Tuple.Create(nodes, edges);
+        }
+        /// <summary>
+        /// Creates nodes and edges from adjacency matrix and add all elements to your canvas
+        /// </summary>
+        /// <param name="matrix">Adjacency matrix</param>
+        /// <param name="canvas">Canvas to draw</param>
+        /// <returns>Tuple of nodes and edges</returns>
+        public static Tuple<Node[], Edge[]> FromAdjacencyToCanvas(int[,] matrix, Canvas canvas)
+        {
+            var items = FromAdjacency(matrix);
+            Node[] nodes = items.Item1;
+            Edge[] edges = items.Item2;
+
+            GraphAction.AddRangeToCanvas(nodes, edges, canvas);
+            return Tuple.Create(nodes, edges);
+        }
+        /// <summary>
+        /// Creates nodes and edges from incidence matrix
+        /// </summary>
+        /// <param name="matrix">Incidence matrix</param>
+        /// <returns>Tuple of nodes and edges array</returns>
+        public static Tuple<Node[], Edge[]> FromIncidence(int[,] matrix)
+        {
+            Random random = new Random();
+            int rows = matrix.GetLength(0);
+            int cols = matrix.GetLength(1);
+            Node[] nodes = new Node[rows];
+            Edge[] edges = new Edge[cols];
+            int cost = int.MaxValue;
+            Node buffer = null;
+
+            for(int i = 0; i < rows; i++)
+            {
+                nodes[i] = new Node(random.Next(0, Settings.CanvasWidth), random.Next(0, Settings.CanvasHeight));
+            }
+
+            for(int i = 0; i < cols; i++)
+            {
+                for(int j = 0; j < rows; j++)
+                {
+                    if (matrix[i, j] > 0)
+                    {
+                        if (buffer == null)
+                        {
+                            cost = matrix[i, j];
+                            buffer = nodes[j];
+                        }
+                        else
+                        {
+                            if (matrix[i, j] == (cost * (-1)))
+                                edges[i] = new Edge(buffer, nodes[j], matrix[i, j], true);
+                            else
+                                edges[i] = new Edge(buffer, nodes[j], matrix[i, j], false);
+                        }
+                    }
+                }
+            }
+            return Tuple.Create(nodes, edges);
+        }
+        /// <summary>
+        /// Creates nodes and edges from incidence matrix and add all elements to your canvas
+        /// </summary>
+        /// <param name="matrix">Incidence matrix</param>
+        /// <param name="canvas">Canvas to draw</param>
+        /// <returns>Tuple of nodes and edges</returns>
+        public static Tuple<Node[], Edge[]> FromIncidenceToCanvas(int[,] matrix, Canvas canvas)
+        {
+            var tuple = FromIncidence(matrix);
+            Node[] nodes = tuple.Item1;
+            Edge[] edges = tuple.Item2;
+            GraphAction.AddRangeToCanvas(nodes, edges, canvas);
+            return Tuple.Create(nodes, edges);
+        }
     }
 }

+ 36 - 11
DrawGraph/Node.cs

@@ -1,8 +1,15 @@
-namespace DrawGraph
+using System.Xml.Serialization;
+using System.Windows.Shapes;
+using System.Windows.Controls;
+using System.Collections.Generic;
+
+namespace DrawGraph
 {
     public class Node
     {
+        [XmlAttribute("positionX")]
         public int X { get; set; }
+        [XmlAttribute("positionY")]
         public int Y { get; set; }
 
         public Node(int x, int y)
@@ -11,35 +18,53 @@
             Y = y;
         }
 
+        /// <summary>
+        /// Get center X-coordinate of node
+        /// </summary>
         public int CenterByX => (X * 2 + (Settings.NodeWidth/2)) / 2;
 
+        /// <summary>
+        /// Get center Y-coordinate of node
+        /// </summary>
         public int CenterByY => (Y * 2 + (Settings.NodeHeight / 2)) / 2;
 
-        public static bool Compare(Node v1, Node v2)
+        /// <summary>
+        /// Compare two nodes
+        /// </summary>
+        /// <param name="node1">First node to compare</param>
+        /// <param name="node2">Second node to compare</param>
+        /// <returns>True if nodes are equal, false if not equal</returns>
+        public static bool Compare(Node node1, Node node2)
         {
-            if (Equals(v1, v2))
+            if (Equals(node1, node2))
                 return true;
-            if (v1 == v2)
+            if (node1 == node2)
                 return true;
-            if (v1.X == v2.X && v1.Y == v2.Y)
+            if (node1.X == node2.X && node1.Y == node2.Y)
                 return true;
             return false;
         }
 
-        public static bool IsNodeOverlaid(Node v1, Node v2)
+
+        /// <summary>
+        /// Compare nodes and returns true if they are overlaid
+        /// </summary>
+        /// <param name="node1"></param>
+        /// <param name="node2"></param>
+        /// <returns>True if overlaid, false if not</returns>
+        public static bool IsNodeOverlaid(Node node1, Node node2)
         {
-            var x = v1.X - v2.X;
-            var y = v1.Y - v2.Y;
+            var x = node1.X - node2.X;
+            var y = node1.Y - node2.Y;
             if(x<=Settings.NodeWidth/2 && x>=0)
                 if (y <= Settings.NodeHeight / 2 && y > 0)
                     return true;
-            x = v2.X - v1.X;
-            y = v2.Y - v1.Y;
+            x = node2.X - node1.X;
+            y = node2.Y - node1.Y;
             if (x <= Settings.NodeWidth / 2 && x >= 0)
                 if (y <= Settings.NodeHeight / 2 && y > 0)
                     return true;
             return false;
         }
-
     }
 }

+ 4 - 33
DrawGraph/Settings.cs

@@ -1,7 +1,4 @@
-using System;
-using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Shapes;
+using System.Windows.Media;
 
 namespace DrawGraph
 {
@@ -11,34 +8,8 @@ namespace DrawGraph
         public static int NodeHeight = 10;
         public static int StrokeThickness = 2;
         public static int FontSize = 16;
+        public static int CanvasWidth = 500;
+        public static int CanvasHeight = 500;
         public static Brush FillColor = Brushes.Black;
-
-        public static void ClearCanvas(Edge[] edges, Node[] nodes)
-        {
-            if (edges != null && nodes != null)
-            {
-                Array.Clear(edges, 0, edges.Length);
-                Array.Clear(nodes, 0, nodes.Length);
-            }
-            else
-            {
-                throw new NullReferenceException();
-            }
-        }
-
-        public static void RemoveAllEdges(Canvas canvas, Line[] lines, Edge[] edges)
-        {
-            Array.Clear(edges, 0, edges.Length);
-            for (int i = 0; i < lines.Length; i++)
-            {
-                canvas.Children.Remove(lines[i]);
-            }
-        }
-
-        public static void RemoveLastAdded(Canvas canvas)
-        {
-            int removingElement = canvas.Children.Count-1;
-            canvas.Children.RemoveAt(removingElement);
-        }
-    }
+    };
 }