예제 #1
0
        IEnumerable <SENode> TraverseParents(GraphNode focusNode,
                                             SENode seFocusNode,
                                             String traversalFilter,
                                             Int32 depth)
        {
            const String fcn = "TraverseParents";

            Regex traversalFilterRex = new Regex(traversalFilter);

            HashSet <GraphNode> parentNodes = new HashSet <GraphNode>();

            parentNodes.Add(focusNode);

            foreach (GraphNode.Link parentLink in focusNode.ParentLinks)
            {
                if (
                    (depth >= 0) &&
                    (traversalFilterRex.IsMatch(parentLink.Traversal.TraversalName)) &&
                    (parentNodes.Contains(parentLink.Node) == false)
                    )
                {
                    var parentNode = parentLink.Node;

                    // we want to link to top level parent, not element node.
                    while ((parentNode != null) && (parentNode.Anchor.Item != null))
                    {
                        switch (parentNode.ParentLinks.Count)
                        {
                        case 0:
                            this.ParseItemError(parentNode.TraceMsg(), fcn, $"No parent nodes found");
                            parentNode = null;
                            break;

                        case 1:
                            parentNode = parentNode.ParentLinks[0].Node;
                            break;

                        default:
                            this.ParseItemError(parentNode.TraceMsg(), fcn, $"Multiple ({parentNode.ParentLinks.Count}) parent nodes detected");
                            break;
                        }
                    }
                    if (parentNode != null)
                    {
                        SENode parent = CreateNode(parentNode);
                        yield return(parent);
                    }
                }
            }
        }
예제 #2
0
        void RenderLegend(IEnumerable <GraphLegend> legend,
                          HashSet <String> cssClasses,
                          float x,
                          float y)
        {
            SvgGroup legendGroup = this.doc.AddGroup(null);

            foreach (GraphLegend legendItem in legend)
            {
                bool CssClassUsed() => cssClasses.Contains(legendItem.CssClass);

                void RenderLegendItem()
                {
                    SENode node = new SENode {
                        Class = legendItem.CssClass
                    };

                    node.AddTextLine(legendItem.Item);

                    Render(legendGroup,
                           node,
                           x,
                           y,
                           null,
                           out float width,
                           out float height);
                    x = x + width + this.NodeGapX;
                    float bottom = y + height;

                    if (this.maxX < x)
                    {
                        this.maxX = x;
                    }
                    if (this.maxY < bottom)
                    {
                        this.maxY = bottom;
                    }
                }

                if (CssClassUsed())
                {
                    RenderLegendItem();
                }
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        protected SENode CreateNodeBinding(ElementDefinition.ElementDefinitionBindingComponent binding)
        {
            String hRef = null;
            SENode node = new SENode()
            {
                HRef = hRef
            };

            node.Class = "valueSet";

            String displayName = binding.ValueSet.LastPathPart();

            if (this.TryGetValueSet(binding.ValueSet, out ValueSet vs) == false)
            {
                displayName = vs.Name;
            }
            node.AddTextLine(displayName, hRef);
            node.LhsAnnotation = "bind";
            return(node);
        }
예제 #5
0
        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();
        }
예제 #6
0
        protected SENode CreateNode(GraphNode graphNode)
        {
            SENode node = new SENode
            {
                HRef = graphNode.HRef
            };

            node.Class = graphNode.CssClass;

            String displayName = graphNode.DisplayName;

            //Debug.Assert(displayName != "Breast/Radiology/Composition");

            foreach (String titlePart in displayName.Split('/'))
            {
                String s = titlePart.Trim();
                node.AddTextLine(s, graphNode.HRef);
            }

            node.SortPrefix    = graphNode.SortPrefix;
            node.LhsAnnotation = ResolveAnnotation(graphNode, graphNode.LhsAnnotationText);
            node.RhsAnnotation = ResolveAnnotation(graphNode, graphNode.RhsAnnotationText);
            return(node);
        }
예제 #7
0
 public void AppendNode(SENode node)
 {
     this.Nodes.Add(node);
 }
예제 #8
0
        void Render(SvgGroup parentGroup,
                    SENode node,
                    float screenX,
                    float screenY,
                    HashSet <String> cssClasses,
                    out float width,
                    out float height)
        {
            void AddClass(String cssClassx)
            {
                if (cssClasses == null)
                {
                    return;
                }
                if (cssClasses.Contains(cssClassx) == false)
                {
                    cssClasses.Add(cssClassx);
                }
            }

            //Debug.Assert((this.RenderTestPoint == null) || node.AllText().Contains(RenderTestPoint) == false);
            height = node.TextLines.Count * this.LineHeight + 2 * this.BorderMargin;
            width  = node.Width / 15 + 2 * this.BorderMargin;

            AddClass(parentGroup.Class);
            SvgGroup g = this.doc.AddGroup(parentGroup);

            g.Class     = parentGroup.Class;
            g.Transform = $"translate({this.ToPx(screenX)} {this.ToPx(screenY)})";
            SvgRect square;

            if (node.HRef != null)
            {
                SvgHyperLink l = this.doc.AddHyperLink(g);
                l.Target = "_top";
                l.HRef   = node.HRef.ToString();
                square   = this.doc.AddRect(l);
            }
            else
            {
                square = this.doc.AddRect(g);
            }

            AddClass(node.Class);
            square.Class  = node.Class;
            square.RX     = this.ToPx(this.RectRx);
            square.RY     = this.ToPx(this.RectRy);
            square.X      = "0";
            square.Y      = "0";
            square.Width  = this.ToPx(width);
            square.Height = this.ToPx(height);

            float textY = this.BorderMargin + 1;

            foreach (SEText line in node.TextLines)
            {
                SvgText t;
                if (line.HRef != null)
                {
                    SvgHyperLink l = this.doc.AddHyperLink(g);
                    l.HRef   = line.HRef;
                    l.Target = "_top";
                    if (line.Title != null)
                    {
                        SvgTitle title = this.doc.AddTitle(l);
                        title.Value = line.Title;
                    }

                    t = this.doc.AddText(l);
                }
                else
                {
                    t = this.doc.AddText(g);
                }
                t.Class = GetClass(line.Class, node.Class);
                AddClass(t.Class);

                t.X          = this.ToPx(this.BorderMargin + this.BorderWidth);
                t.Y          = this.ToPx(textY);
                t.TextAnchor = "left";
                t.Value      = line.Text;

                textY += this.LineHeight;
            }
        }