Example #1
0
 internal bool Overlaps(BranchDeets other)
 {
     if (rowStart > other.rowEnd)
     {
         return(false);
     }
     if (rowEnd < other.rowStart)
     {
         return(false);
     }
     return(true);
 }
Example #2
0
        protected override bool RunInternal(object options)
        {
            SvgdagVerbOptions localOptions = options as SvgdagVerbOptions;

            float startLine = 20.0f;
            float deltaLine = 20.0f;

            // STUFF
            int limit = !localOptions.Limit.HasValue ? 50 : localOptions.Limit.Value;
            var dag   = Workspace.GetDAG(limit);

            string[] colors = new string[] { "green", "blue", "orange", "darkturquoise", "purple", "pink", "olive", "cornflowerblue", "coral", "teal", "blueviolet", "brown", "grey", "maroon", "indigo" };   // add more
            Dictionary <Guid, BranchDeets> branchDeets = new Dictionary <Guid, BranchDeets>();

            branchDeets.Add(Workspace.CurrentBranch.ID, new BranchDeets {
                color = "red"
            });                                                                             // no one else gets red
            int nextColorIndex = 0;

            // Collect branches and assign colors.
            int row = 0;

            foreach (var version in dag.Objects)
            {
                BranchDeets bd;
                if (!branchDeets.TryGetValue(version.Object.Branch, out bd))
                {
                    int useColorIndex = nextColorIndex % colors.Length;
                    branchDeets.Add(version.Object.Branch, bd = new BranchDeets {
                        color = colors[useColorIndex]
                    });
                    nextColorIndex++;
                }

                bd.RowSeen(row);

                ++row;
            }

            float documentLength = startLine + (float)(row + 1) * deltaLine;

            Console.WriteLine(@"<?xml version=""1.0"" standalone=""no""?><!DOCTYPE svg PUBLIC ""-//W3C//DTD SVG 1.1//EN"" ""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"">");
            Console.WriteLine(@"<svg width=""1024pt"" height=""{0}pt"" viewBox=""0 0 1024 {0}"" xmlns=""http://www.w3.org/2000/svg"" xmlns:xlink=""http://www.w3.org/1999/xlink"" version=""1.1"">", documentLength);
            Console.WriteLine(@"<desc>Versionr svg output</desc>");
            // CSS Style town
            Console.WriteLine(@"
  <defs>
    <style type=""text/css""><![CDATA[
      text {
        font-family: Verdana;
        font-size: 9px;
        dominant-baseline: central;
      }
      text.u {
        fill: blue;
      }
      text.g {
        font-family: Courier;
        fill: green;
      }
      circle {
        stroke: black;
        stroke-width: 1px;
      }
      path {
        stroke-width: 1px;
        fill: none;
      }
      path.m {
        stroke-dasharray: 3;
      }
    ]]></style>
  </defs>
            ");


            // Assign columns to branches.
            List <List <BranchDeets> > columnSlot = new List <List <BranchDeets> >();

            columnSlot.Add(new List <BranchDeets>());
            BranchDeets currentBD = branchDeets[Workspace.CurrentBranch.ID];

            columnSlot[0].Add(currentBD);    // current branch always column 0

            foreach (var bd in branchDeets.Values)
            {
                if (bd == currentBD)
                {
                    continue;
                }

                bool inserted = false;
                foreach (var column in columnSlot)
                {
                    bool overlap = false;
                    foreach (var columnBD in column)
                    {
                        if (bd.Overlaps(columnBD))
                        {
                            overlap = true;
                            break;
                        }
                    }

                    if (overlap == false)
                    {
                        column.Add(bd);
                        inserted = true;
                        break;
                    }
                }

                if (inserted == false)
                {
                    columnSlot.Add(new List <BranchDeets>());
                    columnSlot.Last().Add(bd);
                }
            }

            float columnValue = 0.0f;

            foreach (var column in columnSlot)
            {
                foreach (var bd in column)
                {
                    bd.column = columnValue;
                }
                columnValue += 1.0f;
            }

            float guidX           = (columnValue + 1.0f) * deltaLine;
            float branchX         = guidX + 75.0f;
            float userX           = branchX + 100.0f;
            float messageX        = userX + 75.0f;
            float dotColumnStartX = 20.0f;

            float         line        = startLine;
            StringBuilder branchBlurb = new StringBuilder(1024 * 1024);

            branchBlurb.AppendFormat(@"<g transform=""translate({0}, 0)"">", branchX);
            StringBuilder guidBlurb = new StringBuilder(1024 * 1024);

            guidBlurb.AppendFormat(@"<g transform=""translate({0}, 0)"">", guidX);
            StringBuilder userBlurb = new StringBuilder(1024 * 1024);

            userBlurb.AppendFormat(@"<g transform=""translate({0}, 0)"">", userX);
            StringBuilder messageBlurb = new StringBuilder(1024 * 1024);

            messageBlurb.AppendFormat(@"<g transform=""translate({0}, 0)"">", messageX);
            foreach (var version in dag.Objects)
            {
                BranchDeets bd;
                if (!branchDeets.TryGetValue(version.Object.Branch, out bd))
                {
                    int useColorIndex = nextColorIndex % colors.Length;
                    branchDeets.Add(version.Object.Branch, bd = new BranchDeets {
                        color = colors[useColorIndex]
                    });
                    nextColorIndex++;
                }

                branchBlurb.AppendFormat(@"<text y=""{0}"" fill=""{1}"">{2}</text>", line, bd.color, SecurityElement.Escape(Workspace.GetBranch(version.Object.Branch).Name));
                guidBlurb.AppendFormat(@"<text y=""{0}"" class=""g"">{1}</text>", line, version.Object.ID.ToString().Substring(0, 8));
                userBlurb.AppendFormat(@"<text y=""{0}"" class=""u"">{1}</text>", line, SecurityElement.Escape(version.Object.Author));
                messageBlurb.AppendFormat(@"<text y=""{0}"">{1}</text>", line, SecurityElement.Escape(version.Object.Message));

                line += deltaLine;
            }

            branchBlurb.Append("</g>");
            guidBlurb.Append("</g>");
            userBlurb.Append("</g>");
            messageBlurb.Append("</g>");

            Console.Write(branchBlurb);
            Console.Write(guidBlurb);
            Console.Write(userBlurb);
            Console.Write(messageBlurb);

            Dictionary <Guid, VersionDeets> versionDeets = new Dictionary <Guid, VersionDeets>();

            // Draw branch dots (but postpone output)
            StringBuilder dotsBlurb = new StringBuilder(1024 * 1024);

            line = startLine;
            float dotRadius = deltaLine / 4.0f;

            foreach (var version in dag.Objects)
            {
                BranchDeets bd = branchDeets[version.Object.Branch];
                float       x  = dotColumnStartX + bd.column * deltaLine; // using deltaLine for width as well as height for dots, so they're on a square grid
                dotsBlurb.AppendFormat(@"<circle fill=""{0}"" cx=""{1}"" cy=""{2}"" r=""{3}""/>", bd.color, x, line, dotRadius);
                // Save off its position
                versionDeets.Add(version.Object.ID, new VersionDeets {
                    X = x, Y = line, Color = bd.color
                });

                line += deltaLine;
            }

            // Draw connecting lines
            foreach (var version in dag.Objects)
            {
                VersionDeets currentDot = versionDeets[version.Object.ID];
                foreach (var link in version.Links)
                {
                    if (dag.Lookup.ContainsKey(link.Source))
                    {
                        VersionDeets otherDot  = versionDeets[dag.Lookup[link.Source].Item1.ID];
                        string       lineClass = "n";
                        if (link.Merge)
                        {
                            lineClass = "m";
                        }
                        if (currentDot.X != otherDot.X)
                        {
                            Console.WriteLine(@"<path d=""M {0} {1} Q {2} {1} {2} {3}"" class=""{4}"" stroke=""{5}""/>", currentDot.X, currentDot.Y, otherDot.X, otherDot.Y, lineClass, otherDot.Color);
                        }
                        else
                        {
                            Console.WriteLine(@"<path d=""M {0} {1} L {0} {2}"" class=""{3}"" stroke=""{4}""/>", currentDot.X, currentDot.Y, otherDot.Y, lineClass, otherDot.Color);
                        }
                    }
                }
            }

            Console.Write(dotsBlurb);

            Console.WriteLine(@"</svg>");
            return(true);
        }