public void RenderFocusGraph(String cssFile, GraphNode focusGraphNode, Int32 depth, String traversalName, String graphName, HashSet <String> keys = null) { SvgEditor e = new SvgEditor(graphName); e.AddCssFile(cssFile); lock (this.svgEditors) { this.svgEditors.Add(e); } SENodeGroup seGroupParents = new SENodeGroup("", "parents"); SENodeGroup seGroupFocus = new SENodeGroup("", "focus"); SENodeGroup seGroupChildren = new SENodeGroup("", "children"); seGroupParents.AppendGroup(seGroupFocus); seGroupFocus.AppendGroup(seGroupChildren); SENode focusSENode = this.CreateNode(focusGraphNode); focusSENode.Class = "focus"; seGroupFocus.AppendNode(focusSENode); { IEnumerable <SENode> parentNodes = TraverseParents(focusGraphNode, focusSENode, $"{traversalName}/*", 1); seGroupParents.AppendNodeRange(parentNodes); } { IEnumerable <SENodeGroup> childNodes = TraverseChildren(focusGraphNode, $"{traversalName}/*", depth, keys, new Stack <GraphNode>()); seGroupFocus.AppendGroupRange(childNodes); } seGroupParents.Sort(); this.legends.TryGetValue("focus", out List <GraphLegend> legendNodes); e.Render(seGroupParents, legendNodes); }
IEnumerable <SENodeGroup> TraverseChildren(GraphNode focusNode, String traversalFilter, Int32 depth, HashSet <String> keys, Stack <GraphNode> nodeStack) { if (nodeStack.Contains(focusNode)) { throw new Exception($"Circular linkage at {focusNode.TraceMsg()}"); } nodeStack.Push(focusNode); Regex traversalFilterRex = new Regex(traversalFilter); bool HasKey(GraphNode.Link childLink) => (keys == null) || keys.Overlaps(childLink.Keys); foreach (GraphNode.Link childLink in focusNode.ChildLinks) { if ( (depth > 0) && (traversalFilterRex.IsMatch(childLink.Traversal.TraversalName)) && (HasKey(childLink)) ) { SENode child = CreateNode(childLink.Node); SENodeGroup childContainer = new SENodeGroup(child.SortPrefix, child.AllText()); childContainer.AppendNode(child); childContainer.AppendGroupRange(TraverseChildren(childLink.Node, traversalFilter, depth - childLink.Depth, keys, nodeStack)); yield return(childContainer); } } nodeStack.Pop(); }