/// <summary> /// expected input is { nodes, edges} object /// </summary> /// <param name="sigmaGraphJson"></param> /// <returns></returns> public RedBlackTree JsonToTree(string sigmaGraphJson) { try { SigmaGraph graph = new SigmaGraph(sigmaGraphJson); return(ConvertToTree(graph)); } catch (Exception ex) { Debug.WriteLine(ex.ToString()); throw ex; } }
public string ToSigmaJson(ITree tree) { //format specified for sigma.js graph SigmaGraph sigma = ConvertToSigmaGraph(tree); var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; string json = JsonConvert.SerializeObject(sigma, Newtonsoft.Json.Formatting.None, settings); return(json); }
public SigmaGraph ConvertToSigmaGraph(ITree tree) { var graph = new SigmaGraph(); if (tree.Root == null) { throw new ArgumentNullException(); } if (tree.Root.Value == null) { return(graph); } int h = tree.GetTreeHeight(); //width of tree on lowest level is 2^(h-1)*2-1 int w = (int)Math.Pow(2, h) - 1; //incremented after every dequeued node, used to calculate current tree level int nodeCounter = 0; int level = 0; int margin = 0; int separator = 0; //traverse tree with queue Queue <Node> queue = new Queue <Node>(); queue.Enqueue(tree.Root); while (queue.Count != 0) { if (nodeCounter >= Math.Pow(2, level)) { nodeCounter = 0; level++; } margin = (int)Math.Pow(2, h - level - 1) - 1; separator = (int)Math.Pow(2, h - level) - 1; int x = margin + (separator + 1) * (nodeCounter) + 1; var node = queue.Dequeue(); nodeCounter++; queue.Enqueue(node.Left); queue.Enqueue(node.Right); if (node.Value == null) { continue; } var snode = new SigmaNode(node, x, level * h); graph.nodes.Add(snode); if (node.Left.Value != null) { graph.edges.Add(new SigmaEdge(node.id.ToString(), node.Left.id.ToString())); } if (node.Right.Value != null) { graph.edges.Add(new SigmaEdge(node.id.ToString(), node.Right.id.ToString())); } if (queue.All(n => n.Value == null)) { break; } } return(graph); }
public RedBlackTree ConvertToTree(SigmaGraph graph) { var edgesCopy = new List <SigmaEdge>(graph.edges); RedBlackTree newTree = new RedBlackTree(); if (graph.nodes.Count == 0) { return(newTree); } graph.nodes.OrderBy(x => x.id); var addedNodes = new List <Node>(); foreach (var edge in graph.edges) { var sourceNode = graph.nodes.FirstOrDefault(x => x.id == edge.source); var targetNode = graph.nodes.FirstOrDefault(x => x.id == edge.target); if (sourceNode != null && targetNode != null) { Node nodeS = FindOrCreateNode(sourceNode); Node nodeT = FindOrCreateNode(targetNode); if (targetNode.isRight) { nodeS.Right = nodeT; } else { nodeS.Left = nodeT; } nodeT.Parent = nodeS; } } //if there were no edges, only root remained in copy collection if (!addedNodes.Any()) { FindOrCreateNode(graph.nodes.First()); } //root is only node with sentinel valued parent newTree.Root = addedNodes.First(x => x.Parent.Value == null); return(newTree); Node FindOrCreateNode(SigmaNode sigmaNode) { if (addedNodes.Any(x => x.id.ToString() == sigmaNode.id)) { return(addedNodes.First(x => x.id.ToString() == sigmaNode.id)); } else { int val; Int32.TryParse(sigmaNode.label, out val); Node newNode = newTree.CreateNode(val); newNode.Color = SigmaNode.SigmaColorToNodeColor(sigmaNode.color); //change to tryparse newNode.id = Int32.Parse(sigmaNode.id); addedNodes.Add(newNode); return(newNode); } } }