コード例 #1
0
        public static void Main(string[] args)
        {
            using (IDbConnection con = OpenDatabaseConnection())
            {
                var relations         = GetRelations(con).ToList();
                var knownAnime        = GetAnime(con).ToDictionary(a => a.AnimeId);
                var relationsPerAnime = relations.Select(r => new { From = r.AnimeId, To = r.RelatedAnimeId })
                                        .Union(relations.Select(r => new { From = r.RelatedAnimeId, To = r.AnimeId }))
                                        .ToLookup(r => r.From, r => r.To);
                var animeGroupCalculator    = AutoAnimeGroupCalculator.CreateFromServerSettings(con);
                AutoGroupExclude relExclude = ServerSettings.GetAutoGroupSeriesRelationExclusions();

                List <HashSet <int> > subGraphs = BuildSubGraphs(relationsPerAnime);

                WriteLine("digraph Shoko_Anime_Relations {");
                WriteLine("\tnode [fontsize=11, fillcolor=powderblue, style=filled];");
                WriteLine("\tgraph [nodesep=1.5, ranksep=6, overlap=false, splines=spline, style=dashed, smoothing=power_dist];");

                int sgCount = 0;

                // Render each subgraph
                foreach (var subgraph in subGraphs)
                {
                    Write("\tsubgraph cluster_");
                    Write(sgCount);
                    WriteLine(" {");

                    foreach (int animeId in subgraph)
                    {
                        Write("\t\t\"");
                        Write(animeId);
                        Write("\" [fillcolor=");

                        if (knownAnime.TryGetValue(animeId, out var anime))
                        {
                            switch (anime.AnimeType)
                            {
                            case AnimeType.Movie:
                                Write("palegreen");
                                break;

                            case AnimeType.OVA:
                                Write("tan");
                                break;

                            case AnimeType.TVSeries:
                                Write("lightblue");
                                break;

                            case AnimeType.TVSpecial:
                                Write("cornsilk");
                                break;

                            case AnimeType.Other:
                                Write("lightpink");
                                break;

                            case AnimeType.Web:
                                Write("pink");
                                break;
                            }

                            if (animeGroupCalculator.GetGroupAnimeId(animeId) == animeId)
                            {
                                Write(", penwidth=2, shape=doubleoctagon");
                            }

                            string title = anime.MainTitle;

                            if (title.Length > MaxTitleLength)
                            {
                                title = title.Substring(0, MaxTitleLength - 3) + "...";
                            }

                            title = WordWrap(title, WordWrapLength);

                            Write(", label=<");
                            Write(anime.AnimeId);

                            if (anime.AirDate != null)
                            {
                                Write("  <i>(");
                                Write(anime.AirDate.Value.ToString("MMM yyyy"));
                                Write(")</i>");
                            }

                            Write("<br/><b>");
                            Write(HttpUtility.HtmlEncode(title).Replace("\n", "<br/>"));
                            Write("</b>>");
                        }
                        else // Write colour for missing series
                        {
                            Write("tomato, shape=box");
                        }

                        Write(", target=_blank, href=\"https://anidb.net/a");
                        Write(animeId);
                        WriteLine("\"];");
                    }

                    WriteLine("\t}");
                    sgCount++;
                }

                // Render all edges
                WriteLine();
                WriteLine("\t#Edges");

                foreach (var edge in relations)
                {
                    Write("\t\"");
                    Write(edge.AnimeId);
                    Write("\" -> \"");
                    Write(edge.RelatedAnimeId);
                    Write("\" [label=\"");
                    Write(edge.RelationType);
                    Write("\"");

                    // If the relation is meant to be exlcuded when calculating groups, then we'll colour it differently
                    if (Enum.TryParse(edge.RelationType.Replace(" ", string.Empty), true, out AutoGroupExclude relType) &&
                        (relType & relExclude) > 0)
                    {
                        Write(", color=grey, style=dashed");
                    }

                    WriteLine("];");
                }

                WriteLine("}");
            }
        }