예제 #1
0
        /// <summary>
        /// Get a title for a specified svg element.
        /// </summary>
        private static string GetLayerTitle(SvgElement element, int maxLength = 32)
        {
            string elementName = element.GetName();
            string layerName   = null;

            if (element.ID != null)
            {
                layerName = element.ID;
            }

            if (string.IsNullOrEmpty(layerName) && element.CustomAttributes != null)
            {
                // get custom title attributes.
                foreach (var titleAttribute in AllowedTitles)
                {
                    if (element.CustomAttributes.TryGetValue(titleAttribute, out string title))
                    {
                        if (!string.IsNullOrEmpty(title))
                        {
                            layerName = title;
                            break;
                        }
                    }
                }
            }

            if (string.IsNullOrEmpty(layerName) && element.Children != null)
            {
                // Get child title tag
                SvgTitle title = element.Children.OfType <SvgTitle>().FirstOrDefault();
                if (title != null && !string.IsNullOrEmpty(title.Content))
                {
                    layerName = title.Content;
                }
            }

            if (string.IsNullOrEmpty(layerName))
            {
                // Generate more meanfull name for a svg use node. Add reference element name in a case if it's local document.
                if (element is SvgUse useElement &&
                    useElement.ReferencedElement != null &&
                    !string.IsNullOrEmpty(useElement.ReferencedElement.OriginalString))
                {
                    string str = useElement.ReferencedElement.OriginalString.Trim();
                    if (str.StartsWith("#"))
                    {
                        layerName = str.Substring(1);
                    }
                }
                // Generate more meanfull name for a svg text.
                else if (element is SvgTextBase text && !string.IsNullOrEmpty(text.Text))
                {
                    layerName = text.Text;
                    if (text.Text.Length > maxLength)
                    {
                        layerName = text.Text.Substring(0, maxLength) + "...";
                    }
                }
예제 #2
0
        private void Build(
            SvgGroup workingGroup,
            IFlameGraphNode node,
            SvgUnit width,
            SvgUnit left,
            int depth,
            IFlameGraphNode parent)
        {
            // Reach the max depth
            if (depth > _maxDepth)
            {
                return;
            }

            // Adjust for space between columns.
            SvgUnit adjustedWidth = width - 1;

            if (adjustedWidth < 0)
            {
                return;
            }

            // Adjust height for space between rows
            SvgUnit top            = Height - (depth + 1) * RowHeight;
            SvgUnit adjustedHeight = RowHeight - 1;

            Debug.Assert(adjustedHeight > 0);

            var unitGroup = new SvgGroup();

            workingGroup.Children.Add(unitGroup);
            unitGroup.CustomAttributes.Add("class", "unit_g");

            // Add tooltip for full content
            var title = new SvgTitle()
            {
                Content = node.Content
            };

            // onclick="zoom(this)"
            unitGroup.CustomAttributes.Add("onclick", @"zoom(this)");
            // onmouseover="s('sh_xfree (4 samples, 0.13%)')"
            unitGroup.CustomAttributes.Add("onmouseover", $@"s('{node.Content} ({node.Metric.ToString("0.00")} ms)')");
            // onmouseout="c()"
            unitGroup.CustomAttributes.Add("onmouseout", @"c()");

            unitGroup.Children.Add(title);

            // Create the rectangle:
            var rect = new SvgRectangle
            {
                Fill          = new SvgColourServer(_getFrameBackground(node)),
                X             = left,
                Y             = top,
                CornerRadiusX = 1,
                CornerRadiusY = 1,
                Width         = adjustedWidth,
                Height        = adjustedHeight,
            };

            unitGroup.Children.Add(rect);

            var text = new SvgText(GetFitText(node.Content, adjustedWidth))
            {
                Y          = { top + RowHeight - 5 },
                X          = { left + TextMargin },
                FontSize   = 12,
                FontWeight = SvgFontWeight.W500,
                Fill       = new SvgColourServer(Color.Black),
            };

            unitGroup.Children.Add(text);

            // Process children elements
            int?childrenCount = node.Children?.Count();

            if (childrenCount.HasValue)
            {
                double metricsSum = node.Children.Sum(item => item.Metric);
                if (metricsSum == 0)
                {
                    return;
                }
                double metricsRatio = metricsSum / node.Metric;
                Debug.Assert(metricsRatio <= 1);
                SvgUnit childrenWidth = (float)(width * metricsRatio);
                SvgUnit childLeft     = left + (float)(width - childrenWidth) / 2; // Center the child

                foreach (var child in node.Children)
                {
                    SvgUnit ratioWidth = (float)(child.Metric / metricsSum * childrenWidth);
                    Build(workingGroup, child, ratioWidth, childLeft, depth + 1, node);
                    childLeft += ratioWidth;
                }
            }
        }
예제 #3
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;
            }
        }
예제 #4
0
        void Render(SvgGroup parentGroup,
                    SENode node,
                    float screenX,
                    float screenY,
                    out float width,
                    out float height)
        {
            const float CharMod = 0.7f;

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

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

            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);
            }

            square.Stroke      = Color.Black;
            square.StrokeWidth = this.ToPx(this.BorderWidth);
            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);
            square.Fill        = node.FillColor;

            float textX = this.BorderMargin;
            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.X          = this.ToPx(width / 2);
                t.Y          = this.ToPx(textY);
                t.TextAnchor = "middle";
                t.Value      = line.Text;

                textY += this.LineHeight;
            }
        }
예제 #5
0
        void ParseSvgElement(SvgElement el)
        {
            VectorPath path = null;

            if (el is SvgPolygon)
            {
                SvgPolygon p = (SvgPolygon)el;
                path = CreatePath();

                int len = p.Points.Count;

                if (len % 2 != 0)
                {
                    len--;
                }

                for (int i = 0; i < len; i += 2)
                {
                    float x, y;

                    x = p.Points[i].Value / ppmx;
                    y = p.Points[i + 1].Value / ppmy;

                    if (i == 0)
                    {
                        path.MoveTo(x, y);
                    }
                    else
                    {
                        path.LineTo(x, y);
                    }
                }

                path.ClosePolygon();
            }

            if (el is SvgPath)
            {
                SvgPath p = (SvgPath)el;
                path = CreatePath();

                foreach (SvgElement e in p.Children)
                {
                    if (e is SvgTitle)
                    {
                        SvgTitle title = (SvgTitle)e;
                        path.Title = title.Content;
                    }
                }

                string tag, side;

                tag  = "";
                side = "";
                string guidStr = "";

                path.Side = VectorPathSide.None;

                if (p.TryGetAttribute("gf-tag", out tag))
                {
                    path.Tag = Encoding.UTF8.GetString(Convert.FromBase64String(tag));
                }

                try
                {
                    if (p.TryGetAttribute("gf-guid", out guidStr))
                    {
                        path.Guid = new Guid(guidStr);
                    }
                }
                catch
                {
                }

                if (p.TryGetAttribute("gf-side", out side))
                {
                    if (side == "left")
                    {
                        path.Side = VectorPathSide.Left;
                    }

                    if (side == "right")
                    {
                        path.Side = VectorPathSide.Right;
                    }
                }

                if (p.TryGetAttribute("gf-nome-peca", out string nomePeca))
                {
                    path.NomePeca = "";
                    try
                    {
                        path.NomePeca = Encoding.UTF8.GetString(Convert.FromBase64String(nomePeca));
                    }
                    catch
                    {
                    }
                }

                path.ForceAngle = false;
                string force = "";

                if (p.TryGetAttribute("gf-forceAngle", out force))
                {
                    bool pf = false;

                    if (bool.TryParse(force, out pf))
                    {
                        path.ForceAngle = pf;
                    }
                }

                float sx, sy, ex, ey;

                foreach (SvgPathSegment seg in p.PathData)
                {
                    sx = (seg.Start.X / ppmx);
                    sy = (seg.Start.Y / ppmy);
                    ex = (seg.End.X / ppmx);
                    ey = (seg.End.Y / ppmy);

                    if (seg is SvgLineSegment)
                    {
                        path.LineTo(ex, ey);
                    }
                    else if (seg is SvgCubicCurveSegment)
                    {
                        SvgCubicCurveSegment q = (SvgCubicCurveSegment)seg;
                        path.CurveTo(ex, ey, (q.FirstControlPoint.X / ppmx), (q.FirstControlPoint.Y / ppmy), (q.SecondControlPoint.X / ppmx), (q.SecondControlPoint.Y / ppmy));
                    }
                    else if (seg is SvgQuadraticCurveSegment)
                    {
                        SvgQuadraticCurveSegment q = (SvgQuadraticCurveSegment)seg;
                        path.QCurveTo(ex, ey, (q.ControlPoint.X / ppmx), (q.ControlPoint.Y / ppmy));
                    }
                    else if (seg is SvgClosePathSegment)
                    {
                        path.ClosePolygon();
                    }
                    else if (seg is SvgMoveToSegment)
                    {
                        path.MoveTo(ex, ey);
                    }
                    else
                    {
                    }
                }
            }
            else
            {
            }

            if (path != null)
            {
                path.ClosePath();
            }

            foreach (SvgElement n in el.Children)
            {
                ParseSvgElement(n);
            }
        }