/// <summary> /// Layouts the nodes. /// </summary> public void LayoutNodes() { int nodeYSeperation = NodeY + MinNodeYSeperation; int nodeXSeperation = NodeX + MinNodeXSeperation; int levelXMax = nodeXSeperation * maxLevelNodes; // Sort nodes for layout by level TreeGraph.Sort(PeopleGraphNode.SortByYStart); // Layout the nodes int currentY = -1; int currentX = -01; int levelNodeOffset = 0; for (int i = 0; i < TreeGraph.Count; i++) { PeopleGraphNode item = TreeGraph[i]; // check for chnaged level if (item.YStart > currentY) { currentY = item.YStart; currentX = -1; levelNodeOffset = ((maxLevelNodes * nodeXSeperation) - (maxXNodes[currentY] * nodeXSeperation)) / maxXNodes[currentY]; } // Get vertical start location int offsetY = item.YStart * nodeYSeperation; // Get the next horizontal offset and save currentX += 1; // Do the actual X layout int offsetX = 0; if (maxXNodes[currentY] == 1) { offsetX = (levelXMax - nodeXSeperation) / 2; } else { offsetX = (nodeXSeperation * currentX) + (levelNodeOffset * currentX); } // Save the location for use when laying out the edges PeopleGraphNode itemTemp = TreeGraph.FirstOrDefault(ie => ie.NodeHLink == item.NodeHLink); itemTemp.XStart = offsetX; itemTemp.YStart = offsetY; TreeGraph[i] = itemTemp; } // Allow for spacing TODO make more flexiable CanvasHeight = nodeYSeperation * numLevels; CanvasWidth = nodeXSeperation * maxLevelNodes; }
/// <summary> /// Pres the layout. /// </summary> public void LayoutPreStart() { // Get max horizontal and max/min level minLevel = 0; maxLevel = 0; maxLevelNodes = 0; foreach (var item in maxXNodes) { if (item.Key < minLevel) { minLevel = item.Key; } if (item.Key > maxLevel) { maxLevel = item.Key; } if (item.Value > maxLevelNodes) { maxLevelNodes = item.Value; } } // Convert relative levels to absolute starting at 0 Allows for easy layout on canvas int numNegativeLevels = Math.Abs(minLevel); numLevels = (Math.Abs(minLevel) + maxLevel) + 1; // Plus 1 for the starting zero level for (int i = 0; i < TreeGraph.Count; i++) { PeopleGraphNode t = TreeGraph[i]; t.YStart = TreeGraph[i].YStart + numNegativeLevels; TreeGraph[i] = t; } // offset the maxnodes list to match the TreeGraph absolute levels SortedDictionary <int, int> tempMaxX = new SortedDictionary <int, int>(); foreach (var item in maxXNodes) { tempMaxX.Add(item.Key + numNegativeLevels, maxXNodes[item.Key]); } maxXNodes = tempMaxX; }
///// <summary> ///// Draws the graph. ///// </summary> //public void DrawTheGraph() //{ // Canvas theGraph = new Canvas(); // // Draw the edges for (int i = 0; i < Edges.Count; i++) { // theGraph.Children.Add(Edges[i].TheLine); } // // Draw the nodes for (int i = 0; i < TreeGraph.Count; i++) { PeopleGraphNode item = TreeGraph[i]; // // Assume person PersonModel t = DV.PersonDV.GetModel(item.nodeHLink.HLinkKey); // if (t.HLink.Valid == true) { PersonCardSmall tt = new PersonCardSmall { DataContext = t, // Background = new SolidColorBrush(Colors.AliceBlue), }; theGraph.Children.Add(tt); // tt.SetValue(Canvas.LeftProperty, item.xStart); tt.SetValue(Canvas.TopProperty, // item.yStart); } else { // Assume Family FamilyModel tf = // DV.FamilyDV.GetModel(item.nodeHLink.HLinkKey); FamilyCardSmall tt = new FamilyCardSmall { // DataContext = tf, Background = new SolidColorBrush(Colors.AliceBlue), }; // theGraph.Children.Add(tt); // tt.SetValue(Canvas.LeftProperty, item.xStart); tt.SetValue(Canvas.TopProperty, // item.yStart); } } // // Display it // GraphCanvas = theGraph; //} /// <summary> /// Gets the graph. /// </summary> /// <param name="argHLink"> /// The argument h link. /// </param> public void GetGraph() { // Get people related to personObject person (within 3 jumps and starting at level zero // (the middlish point)) nodeVisitQueue.Enqueue(new NextModel() { HLink = StartHLink, JumpsFromStartNode = 3, Level = 0 }); PeopleGraphNode theNode; do { NextModel t = nodeVisitQueue.Dequeue(); // Handle people if (t.HLink.GetType() == typeof(HLinkPersonModel)) { // Add person to graph theNode = new PeopleGraphNode { NodeHLink = (t.HLink as HLinkPersonModel).DeRef.HLink, YStart = t.Level, }; TreeGraph.Add(theNode); // Add one to the level if (!maxXNodes.ContainsKey(t.Level)) { maxXNodes.Add(t.Level, 0); } // Add one to the level maxXNodes[t.Level] = maxXNodes[t.Level] + 1; AddVisited((t.HLink as HLinkPersonModel).DeRef.HLinkKey, false); if (t.JumpsFromStartNode > 0) { // get parents AddHLink((t.HLink as HLinkPersonModel).DeRef.GChildOf, t.HLink, t.JumpsFromStartNode, t.Level - 1); // get families foreach (HLinkFamilyModel item in (t.HLink as HLinkPersonModel).DeRef.GParentInRefCollection) { AddHLink(t.HLink, item, t.JumpsFromStartNode, t.Level + 1); } } } // Handle families if (t.HLink.GetType() == typeof(HLinkFamilyModel)) { // Add Family theNode = new PeopleGraphNode { NodeHLink = (t.HLink as HLinkFamilyModel).DeRef.HLink, YStart = t.Level, }; TreeGraph.Add(theNode); // Add one to the level if (!maxXNodes.ContainsKey(t.Level)) { maxXNodes.Add(t.Level, 0); } // Add one to the level maxXNodes[t.Level] = maxXNodes[t.Level] + 1; AddVisited((t.HLink as HLinkFamilyModel).DeRef.HLinkKey, false); if (t.JumpsFromStartNode > 0) { // Add Mother and Father at previous level AddHLink((t.HLink as HLinkFamilyModel).DeRef.GMother, t.HLink, t.JumpsFromStartNode, t.Level - 1); AddHLink((t.HLink as HLinkFamilyModel).DeRef.GFather, t.HLink, t.JumpsFromStartNode, t.Level - 1); // Add children at next level foreach (HLinkPersonModel item in (t.HLink as HLinkFamilyModel).DeRef.GChildRefCollection) { AddHLink(t.HLink, item, t.JumpsFromStartNode, t.Level + 1); } } } }while (nodeVisitQueue.Count > 0); }