public Task WriteAsync(StateDiagram diagram, Stream stream)
 {
     return(WriteInternal(diagram, stream));
 }
Beispiel #2
0
        public Task WriteAsync(StateDiagram diagram, TextWriter writer)
        {
            const string terminalNode = "[*]";

            writer.WriteLine("@startuml");
            foreach (var skinParam in SkipParams)
            {
                writer.Write("skinparam ");
                writer.Write(skinParam.Key);
                writer.Write(" ");
                writer.WriteLine(skinParam.Value);
            }

            var nodesByName     = new Dictionary <string, StateNode>(StringComparer.OrdinalIgnoreCase);
            var namesById       = new Dictionary <string, string>();
            var hasOneStartNode = diagram.Nodes.Values.Count(DisplayAsStartNode) == 1;

            if (!hasOneStartNode)
            {
                nodesByName[terminalNode] = null;
            }
            foreach (var node in diagram.Nodes.Values)
            {
                if (hasOneStartNode && DisplayAsStartNode(node))
                {
                    nodesByName[terminalNode] = node;
                    namesById[node.Id]        = terminalNode;
                }
                else
                {
                    var baseName = node.Name.Replace(" ", "").Replace("-", "");
                    var name     = baseName;
                    var index    = 1;
                    while (nodesByName.ContainsKey(name))
                    {
                        name = baseName + (++index).ToString();
                    }
                    nodesByName[name]  = node;
                    namesById[node.Id] = name;
                    var label = node.Label ?? node.Name;
                    if (label != name)
                    {
                        writer.Write("state \"");
                        writer.Write(label);
                        writer.Write("\" as ");
                        writer.WriteLine(name);
                    }
                }
            }

            var links = new List <StateLink>();

            if (nodesByName[terminalNode] == null)
            {
                links.AddRange(diagram.Nodes.Values
                               .Where(n => n.Type == NodeType.Start)
                               .OrderBy(n => Math.Pow(n.Location.X, 2) + Math.Pow(n.Location.Y, 2))
                               .Select(n => new StateLink(null, n, "Start")));
            }
            links.AddRange(diagram.Links
                           .OrderBy(l => l.Source.Type == NodeType.Start ? 0
          : (l.Related.Type == NodeType.End ? 2 : 1))
                           .ThenBy(l => Math.Pow(l.Source.Location.X, 2) + Math.Pow(l.Source.Location.Y, 2))
                           .ThenBy(l => Math.Pow(l.Related.Location.X, 2) + Math.Pow(l.Related.Location.Y, 2)));

            foreach (var link in links)
            {
                if (link.Source == null)
                {
                    writer.Write(terminalNode);
                }
                else
                {
                    writer.Write(namesById[link.Source.Id]);
                }

                writer.Write(" -");
                var direction = GetDirection(link);
                writer.Write(direction);
                var styles = new List <string>();
                if (link.IsDefault)
                {
                    styles.Add("bold");
                }
                if (link.IsOverride)
                {
                    styles.Add("dashed");
                }
                if (styles.Count > 0)
                {
                    writer.Write('[');
                    writer.Write(string.Join(",", styles));
                    writer.Write(']');
                }
                writer.Write("-> ");

                if (link.Related == null)
                {
                    writer.Write(terminalNode);
                }
                else
                {
                    writer.Write(namesById[link.Related.Id]);
                }
                var label = link.Label ?? link.Name;
                if (!string.IsNullOrEmpty(label))
                {
                    writer.Write(" : ");
                    writer.Write(label);
                }
                writer.WriteLine();
            }

            writer.WriteLine("@enduml");
            writer.Flush();
            return(Task.FromResult(true));
        }