I am pretty enjoy about the power of Graphviz and are trying to convert a wonderful .NET Core learning roadmap from .Net Core Developer Roadmap to Graphviz Dot for easier to update later.
The layout is okay until I added a new caching node and I cannot control Graphviz to render correctly.
Here is the code.
digraph learning_roadmap {
node[shape=none, width=0, height=0, label=""];
edge[dir=none];
subgraph main_group {
main0 [label = "ASP.NET Core developer"]
prerequisites [label = "Learn the Prerequisites"]
main1 -> main2
main2 -> main3
main3 -> main4 [minlen=4]
main4 -> main5 [minlen=4]
main5 -> main6 [minlen=4]
main6 -> main7 [minlen=4]
main7 -> main8 [minlen=5]
main8 -> main9 [minlen=1]
main9 -> main10 [minlen=5]
{rank=same; main2 -> prerequisites}
{rank=same; cs -> main3}
{rank=same; main4 -> ef}
{rank=same; asp -> main5}
{rank=same; main6 -> sql}
{rank=same; general_skill -> main7}
{rank=same; main8-> di}
{rank=same; db -> main9}
{rank=same; main10 -> caching}
}
subgraph cs_group {
cs [label = "C#"]
cs_basic [label = "Learn the basics of C#"]
linq [label = "Learn LINQ"]
cs1 -> cs2
{rank=same; cs1 -> cs}
{rank=same; cs_basic -> cs1}
{rank=same; linq -> cs2}
}
subgraph ef_group {
ef [label = "Entity"]
ef_basic [label = "Learn the basics of Entity Framework"]
ef_code_first [label = "Code First + Migrations"]
ef_tracking [label = "Change Tracker API"]
ef_loading [label = "Lazy Loading. Eager Loading, Explicit Loading"]
ef1 -> ef2 -> ef3 -> ef4
{rank=same; ef -> ef1}
{rank=same; ef1 -> ef_basic}
{rank=same; ef2 -> ef_code_first}
{rank=same; ef3 -> ef_tracking}
{rank=same; ef4 -> ef_loading}
}
subgraph asp_group {
asp [label="ASP.NET Core Basics"]
mvc [label="MVC"]
rest [label="REST "]
razor_page [label="Razor Pages "]
razor_component [label="Razor Components "]
middlewares [label="Middlewares "]
filter [label="Filters & Attributes "]
setting [label="Application Settings & Configurations"]
asp1 -> asp2 -> asp3 -> asp4 -> asp5 -> asp6 -> asp7
{rank=same; asp1 -> asp}
{rank=same; mvc -> asp1}
{rank=same; rest -> asp2}
{rank=same; razor_page -> asp3}
{rank=same; razor_component -> asp4}
{rank=same; middlewares -> asp5}
{rank=same; filter -> asp6}
{rank=same; setting -> asp7}
}
subgraph sql_group {
sql [label="SQL Fundamentals"]
sql_basic [label="Fundamentals about database design and SQL Syntax"]
{rank=same; sql -> sql_basic}
}
subgraph general_skill_group {
general_skill [label="General Development Skills"]
git [label="GIT - Version Control (GitHub, BitBucket, GitLab)"]
http [label="HTTP/HTTPS protocol Learn to search for solutions"]
search [label="Learn to search for solutions"]
dotnet_cli [label="Learn Dotnet CLI"]
data_structure [label="Data Structures and Algorithms"]
general1 -> general2 -> general3 -> general4 -> general5
{rank=same; general1 -> general_skill}
{rank=same; git -> general1}
{rank=same; http -> general2}
{rank=same; search -> general3}
{rank=same; dotnet_cli -> general4}
{rank=same; data_structure -> general5}
}
subgraph di_group{
di [label="Dependency Injection"]
di_containers [label="DI Containers"]
scrutor [label="Scrutor"]
life_cycles [label="Life Cycles"]
di1 -> di2 -> di3
{rank=same; di -> di2}
{rank=same; di1 -> di_containers}
{rank=same; di2 -> scrutor}
{rank=same; di3 -> life_cycles}
# DI Frameworks
ms_di [label="Microsoft.Extensions.DependencyInjection"]
autofac [label="Autofac"]
ninject [label="Ninject"]
castle_winsor [label="Castle Winsor"]
unity [label="Unity"]
di_container1 -> di_container2 -> di_container3 ->di_container4 -> di_container5
{rank=same; di_containers -> di_container1 [minlen=7] }
{rank=same; di_container1 -> ms_di}
{rank=same; di_container2 -> autofac}
{rank=same; di_container3 -> ninject}
{rank=same; di_container4 -> castle_winsor}
{rank=same; di_container5 -> unity}
# Scope
trasient [label="Trasient"]
scoped [label="Scoped"]
singleton [label="Singleton"]
life_cycle1 -> life_cycle2 -> life_cycle3
{rank=same; life_cycles -> life_cycle1}
{rank=same; life_cycle1 -> trasient}
{rank=same; life_cycle2 -> scoped}
{rank=same; life_cycle3 -> singleton}
}
subgraph db_group {
db [label="Databases"]
relational_db [label="Relational"]
cloud_db [label="Cloud Databases"]
search_engine [label="Search Engines"]
no_sql [label="NoSQL"]
db1 -> db2 [minlen=6]
db2 -> db3 [minlen=5]
db3 -> db4 [minlen=3]
{rank=same; db1 -> db}
{rank=same; relational_db -> db1}
{rank=same; cloud_db -> db2}
{rank=same; search_engine -> db3}
{rank=same; no_sql -> db4}
# Relational databases
sql_server [label="SQL Server"]
postgresql [label="PostgreSQL"]
mysql [label="MySQL"]
sqlite [label="SQLite"]
relational_db1 -> relational_db2 -> relational_db3 -> relational_db4
{rank=same; relational_db2 -> relational_db [minlen=5] }
{rank=same; sql_server -> relational_db1}
{rank=same; postgresql -> relational_db2}
{rank=same; mysql -> relational_db3}
{rank=same; sqlite -> relational_db4}
# Cloud Databases
azure_sql_database [label="Azure SQL Database"]
cosmos_db [label="Azure CosmosDB"]
rds [label="Amazon RDS"]
aurora [label="Amazon Aurora"]
dynamo_db [label="Amazon DynamoDB"]
cloud_db1 -> cloud_db2 -> cloud_db3 -> cloud_db4 -> cloud_db5
{rank=same; cloud_db1 -> cloud_db}
{rank=same; azure_sql_database -> cloud_db1}
{rank=same; cosmos_db -> cloud_db2}
{rank=same; rds -> cloud_db3}
{rank=same; aurora -> cloud_db4}
{rank=same; dynamo_db -> cloud_db5}
# Search Engines
elastic_search [label="ElasticSearch"]
solr [label="Solr"]
sphinx [label="Sphinx"]
search1 -> search2 -> search3
{rank=same; search1 -> search_engine}
{rank=same; elastic_search -> search1}
{rank=same; solr -> search2}
{rank=same; sphinx -> search3}
# NoSQL
mongo_db [label="MongoDB"]
redis [label="Redis"]
lite_db [label="LiteDB"]
cassandra [label="Apache Cassandra"]
raven_db [label="RavenDB"]
couch_db [label="CouchDB"]
no_sql1 -> no_sql2 -> no_sql3 -> no_sql4 -> no_sql5 -> no_sql6
{rank=same; no_sql1 -> no_sql}
{rank=same; mongo_db -> no_sql1}
{rank=same; redis -> no_sql2}
{rank=same; lite_db -> no_sql3}
{rank=same; cassandra -> no_sql4}
{rank=same; raven_db -> no_sql5}
{rank=same; couch_db -> no_sql6}
}
subgraph chaching_group{
caching [label="Caching"]
ef_cache [label="Entity Framework 2nd Level Cache"]
distributed_cache [label="Distributed Cache"]
memory_cache [label="Memory Cache"]
caching1 -> caching2 -> caching3
{rank=same; caching -> caching1 [minlen=5]}
#{rank=same; caching1 -> ef_cache}
#{rank=same; caching2 -> distributed_cache}
#{rank=same; caching3 -> memory_cache}
}
}
Here is the output.
As you can see, I can't make the caching node on the right-hand side or the main edge and it also interrupts database node.
If you have any ideas to fix this, please let me know. Thank you so much.
FYI The tool I use: Graphviz Preview VS Code plugin and Graphviz engine version 2.38.0.20190211

