Vasek
Vasek

Reputation: 464

How visualize more compressed horizontally graph

There is a graph A:

digraph MyGraph {
    "OssInterface.Host" 
    "OssInterface"
    "OssInterface.CliApp"
    "OssInterface.UnitTests"
    "Services.Localization"
    "Services.Logging"
    "Services.Statistics"
    "Services.Statistics.DataServiceRepo"
    "Services.Statistics.Dto" 
    "Services.Utilities"
    
    "OssInterface.Host" -> "Services.Logging"
    "OssInterface.Host" -> "OssInterface"
    "OssInterface.Host" -> "Services.Utilities"
    "OssInterface.Host" -> "Services.Localization"
    "OssInterface.Host" -> "Services.Statistics.DataServiceRepo"
    "OssInterface.Host" -> "Services.Statistics"
    "OssInterface" -> "Services.Utilities"
    "OssInterface" -> "Services.Logging"
    "OssInterface.CliApp" -> "Services.Logging"
    "OssInterface.CliApp" -> "OssInterface.Host"
    "OssInterface.CliApp" -> "Services.Utilities"
    "OssInterface.CliApp" -> "OssInterface"
    "OssInterface.UnitTests" -> "OssInterface"
    "OssInterface.UnitTests" -> "Services.Logging"
    "Services.Localization" -> "Services.Logging"
    "Services.Statistics" -> "Services.Statistics.Dto"
    "Services.Statistics" -> "Services.Logging"
    "Services.Statistics.DataServiceRepo" -> "Services.Statistics"
    "Services.Statistics.DataServiceRepo" -> "Services.Statistics.Dto"
    "Services.Utilities" -> "Services.Logging"
}

With visualization: enter image description here

And graph B:

digraph MyGraph {
    subgraph "cluster_OssInterface.Host" {              
        "OssInterface.Host/OssInterface.Host"
        "OssInterface.Host/OssInterface.Host.Building"
        "OssInterface.Host/OssInterface.Host.Statistics"
    }
    subgraph "cluster_OssInterface" {
        "OssInterface/OssInterface"
        "OssInterface/OssInterface.Agent"
        "OssInterface/OssInterface.DataSources"
        "OssInterface/OssInterface.DataSources.GrpcStorages"
        "OssInterface/OssInterface.DataSources.HttpStorages"
        "OssInterface/OssInterface.Records"
        "OssInterface/OssInterface.Storage"
        "OssInterface/OssInterface.Storage.Cache"
        "OssInterface/OssInterface.Traps"
        "OssInterface/Common.Trees"
        "OssInterface/Common.Trees.Utils"
        "OssInterface/DataService.Proto.OssData"
    }
    subgraph "cluster_OssInterface.CliApp" {
        "OssInterface.CliApp/OssInterface.CliApp"
    }
    subgraph "cluster_OssInterface.UnitTests" {
        "OssInterface.UnitTests/OssInterface.UnitTests"
        "OssInterface.UnitTests/OssInterface.UnitTests.Fakes"
        "OssInterface.UnitTests/OssInterface.UnitTests.Storage"
        "OssInterface.UnitTests/OssInterface.UnitTests.Storage.Cache"
        "OssInterface.UnitTests/OssInterface.UnitTests.Traps"
    }
    subgraph "cluster_Services.Localization" {
        "Services.Localization/Services.Localization"
    }
    subgraph "cluster_Services.Logging" {
        "Services.Logging/Services.Logging"
    }
    subgraph "cluster_Services.Statistics" {
        "Services.Statistics/Services.Statistics"
    }
    subgraph "cluster_Services.Statistics.DataServiceRepo" {
        "Services.Statistics.DataServiceRepo/Services.Statistics.DataServiceRepo"
    }
    subgraph "cluster_Services.Statistics.Dto" {
        "Services.Statistics.Dto/Services.Statistics.Dto"
    }
    subgraph "cluster_Services.Utilities" {
        "Services.Utilities/Services.Utilities"
    }   
    
    "OssInterface.Host/OssInterface.Host.Building" -> "Services.Logging/Services.Logging"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface.Host/OssInterface.Host"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface.Agent"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface.Traps"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface.Storage.Cache"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface.Storage"
    "OssInterface.Host/OssInterface.Host.Building" -> "Services.Utilities/Services.Utilities"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface.DataSources"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface.Records"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/DataService.Proto.OssData"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface.DataSources.GrpcStorages"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface/OssInterface.DataSources.HttpStorages"
    "OssInterface.Host/OssInterface.Host.Building" -> "Services.Localization/Services.Localization"
    "OssInterface.Host/OssInterface.Host.Building" -> "Services.Statistics.DataServiceRepo/Services.Statistics.DataServiceRepo"
    "OssInterface.Host/OssInterface.Host.Building" -> "OssInterface.Host/OssInterface.Host.Statistics"
    "OssInterface.Host/OssInterface.Host.Building" -> "Services.Statistics/Services.Statistics"
    "OssInterface.Host/OssInterface.Host" -> "Services.Statistics/Services.Statistics"
    "OssInterface.Host/OssInterface.Host" -> "OssInterface/OssInterface"
    "OssInterface.Host/OssInterface.Host" -> "OssInterface/OssInterface.Traps"
    "OssInterface.Host/OssInterface.Host.Statistics" -> "OssInterface/OssInterface.Agent"
    "OssInterface.Host/OssInterface.Host.Statistics" -> "Services.Statistics/Services.Statistics"
    "OssInterface.Host/OssInterface.Host.Statistics" -> "Services.Utilities/Services.Utilities"
    "OssInterface/OssInterface.Agent" -> "OssInterface/OssInterface"
    "OssInterface/OssInterface.Agent" -> "Services.Utilities/Services.Utilities"
    "OssInterface/OssInterface.Agent" -> "Services.Logging/Services.Logging"
    "OssInterface/OssInterface.Agent" -> "OssInterface/OssInterface.Traps"
    "OssInterface/OssInterface.DataSources.GrpcStorages" -> "OssInterface/OssInterface.DataSources"
    "OssInterface/OssInterface.DataSources.GrpcStorages" -> "OssInterface/DataService.Proto.OssData"
    "OssInterface/OssInterface.DataSources.GrpcStorages" -> "OssInterface/OssInterface.Records"
    "OssInterface/OssInterface.DataSources.GrpcStorages" -> "OssInterface/OssInterface"
    "OssInterface/OssInterface.DataSources.GrpcStorages" -> "Services.Utilities/Services.Utilities"
    "OssInterface/OssInterface.DataSources.HttpStorages" -> "OssInterface/OssInterface.DataSources"
    "OssInterface/OssInterface.DataSources" -> "Services.Utilities/Services.Utilities"
    "OssInterface/OssInterface.DataSources" -> "Services.Logging/Services.Logging"
    "OssInterface/OssInterface.DataSources" -> "OssInterface/OssInterface"
    "OssInterface/OssInterface" -> "Services.Logging/Services.Logging"
    "OssInterface/OssInterface.Records" -> "OssInterface/OssInterface"
    "OssInterface/OssInterface.Storage" -> "OssInterface/OssInterface"
    "OssInterface/OssInterface.Storage" -> "Services.Logging/Services.Logging"
    "OssInterface/OssInterface.Storage.Cache" -> "OssInterface/OssInterface.DataSources"
    "OssInterface/OssInterface.Storage.Cache" -> "OssInterface/Common.Trees"
    "OssInterface/OssInterface.Storage.Cache" -> "OssInterface/OssInterface.Storage"
    "OssInterface/OssInterface.Storage.Cache" -> "OssInterface/OssInterface"
    "OssInterface/OssInterface.Storage.Cache" -> "OssInterface/OssInterface.Records"
    "OssInterface/OssInterface.Storage.Cache" -> "OssInterface/OssInterface.Traps"
    "OssInterface/OssInterface.Storage" -> "Services.Utilities/Services.Utilities"
    "OssInterface/OssInterface.Storage" -> "OssInterface/OssInterface.Agent"
    "OssInterface/OssInterface.Traps" -> "OssInterface/OssInterface"
    "OssInterface/OssInterface.Traps" -> "OssInterface/OssInterface.DataSources"
    "OssInterface/OssInterface.Traps" -> "OssInterface/OssInterface.Records"
    "OssInterface/OssInterface.Traps" -> "Services.Utilities/Services.Utilities"
    "OssInterface/OssInterface.Traps" -> "Services.Logging/Services.Logging"
    "OssInterface/OssInterface" -> "Services.Utilities/Services.Utilities"
    "OssInterface/Common.Trees" -> "OssInterface/Common.Trees.Utils"
    "OssInterface.CliApp/OssInterface.CliApp" -> "Services.Logging/Services.Logging"
    "OssInterface.CliApp/OssInterface.CliApp" -> "OssInterface.Host/OssInterface.Host"
    "OssInterface.CliApp/OssInterface.CliApp" -> "Services.Utilities/Services.Utilities"
    "OssInterface.CliApp/OssInterface.CliApp" -> "OssInterface/OssInterface"
    "OssInterface.CliApp/OssInterface.CliApp" -> "OssInterface.Host/OssInterface.Host.Building"
    "OssInterface.UnitTests/OssInterface.UnitTests" -> "OssInterface/OssInterface.DataSources"
    "OssInterface.UnitTests/OssInterface.UnitTests.Fakes" -> "OssInterface/OssInterface.Storage"
    "OssInterface.UnitTests/OssInterface.UnitTests.Fakes" -> "OssInterface/OssInterface"
    "OssInterface.UnitTests/OssInterface.UnitTests.Fakes" -> "Services.Logging/Services.Logging"
    "OssInterface.UnitTests/OssInterface.UnitTests.Fakes" -> "OssInterface/OssInterface.Traps"
    "OssInterface.UnitTests/OssInterface.UnitTests.Fakes" -> "OssInterface/OssInterface.Agent"
    "OssInterface.UnitTests/OssInterface.UnitTests.Storage.Cache" -> "OssInterface/OssInterface.Storage.Cache"
    "OssInterface.UnitTests/OssInterface.UnitTests.Storage.Cache" -> "OssInterface/OssInterface.Storage"
    "OssInterface.UnitTests/OssInterface.UnitTests.Storage.Cache" -> "OssInterface/OssInterface"
    "OssInterface.UnitTests/OssInterface.UnitTests.Storage" -> "OssInterface/OssInterface.Storage"
    "OssInterface.UnitTests/OssInterface.UnitTests.Storage" -> "OssInterface.UnitTests/OssInterface.UnitTests.Fakes"
    "OssInterface.UnitTests/OssInterface.UnitTests.Storage" -> "OssInterface.UnitTests/OssInterface.UnitTests"
    "OssInterface.UnitTests/OssInterface.UnitTests.Storage" -> "OssInterface/OssInterface.Storage.Cache"
    "OssInterface.UnitTests/OssInterface.UnitTests.Traps" -> "OssInterface/OssInterface.Traps"
    "OssInterface.UnitTests/OssInterface.UnitTests.Traps" -> "OssInterface/OssInterface.DataSources"
    "OssInterface.UnitTests/OssInterface.UnitTests.Traps" -> "OssInterface.UnitTests/OssInterface.UnitTests"
    "OssInterface.UnitTests/OssInterface.UnitTests.Traps" -> "OssInterface/OssInterface.Records"
    "OssInterface.UnitTests/OssInterface.UnitTests.Traps" -> "OssInterface/OssInterface"
    "OssInterface.UnitTests/OssInterface.UnitTests" -> "OssInterface/OssInterface.Traps"
    "OssInterface.UnitTests/OssInterface.UnitTests" -> "OssInterface/OssInterface"
    "OssInterface.UnitTests/OssInterface.UnitTests" -> "OssInterface.UnitTests/OssInterface.UnitTests.Fakes"
    "Services.Localization/Services.Localization" -> "Services.Logging/Services.Logging"
    "Services.Statistics/Services.Statistics" -> "Services.Statistics.Dto/Services.Statistics.Dto"
    "Services.Statistics/Services.Statistics" -> "Services.Logging/Services.Logging"
    "Services.Statistics.DataServiceRepo/Services.Statistics.DataServiceRepo" -> "Services.Statistics/Services.Statistics"
    "Services.Statistics.DataServiceRepo/Services.Statistics.DataServiceRepo" -> "Services.Statistics.Dto/Services.Statistics.Dto"
    "Services.Utilities/Services.Utilities" -> "Services.Logging/Services.Logging"
}

With visualization: enter image description here And same graph visualization with msagl enter image description here

In the first case, graphviz visualizes a good graph. In the second case, the graph begins to grow in width. It seems that the graphviz in the second case ignores implicit connections between clusters and creates markup based on child nodes. Msagl takes into account cluster nodes and creates a graph that is very similar in visualization to the first graph.

Is it possible to achieve the same results in graphviz as in msagl? It may not be the same in msagl, but I would like to receive an image that is more compressed horizontally.

Upvotes: 0

Views: 40

Answers (1)

sroush
sroush

Reputation: 6791

Here is a solution:

  • uses splines=ortho. This saves a surprising amount of space not needed for spline edges
  • rectangular nodes - reduce wasted space
  • combined OssInterface cluster into one parent cluster
  • removed common text from node labels
  • other tweaks for labels, colors, ...
digraph MyGraph {
  node    [style=filled fillcolor=mistyrose shape=rect height=1.4] 
  graph   [fontcolor=red2 fontsize=16 newrank=true splines=ortho]
  nodesep=.9
  ranksep=.9

  subgraph cluster000{
    subgraph "cluster_OssInterface.Host" {
      label="OssInterface.Host"
      graph [color=red style=filled fillcolor=lightgrey]
        "OssInterface.Host"
        "OssInterface.Host.Building"
        "OssInterface.Host.Statistics"
    }
    subgraph "cluster_OssInterface.CliApp" {
      label="OssInterface.CliApp"
      graph [color=red style=filled fillcolor=lightgrey]
        "OssInterface.CliApp"
    }
    subgraph "cluster_OssInterface.UnitTests" {
      label="OssInterface.UnitTests"
      graph [color=red style=filled fillcolor=lightgrey]
        "OssInterface.UnitTests"
        "OssInterface.UnitTests.Fakes"
        "OssInterface.UnitTests.Storage"
        "OssInterface.UnitTests.Storage.Cache"
        "OssInterface.UnitTests.Traps"
    }

    subgraph "cluster_OssInterface" {
      label="OssInterface"
      graph [color=red style=filled fillcolor=lightgrey]
        "OssInterface"  
        "OssInterface.Agent"
        "OssInterface.DataSources"
        "OssInterface.DataSources.GrpcStorages"
        "OssInterface.DataSources.HttpStorages"
        "OssInterface.Records"  
        "OssInterface.Storage"
        "OssInterface.Storage.Cache"  
        "OssInterface.Traps"
        "Common.Trees"
        "Common.Trees.Utils"
        "DataService.Proto.OssData"
    }

  subgraph clusterServicesGathered {
    subgraph "cluster_Services.Localization" {
      label="Services.Localization"
      graph [color=red style=filled fillcolor=lightgrey]
        "Services.Localization"
    }
    subgraph "cluster_Services.Logging" {
      label="Services.Logging"
      graph [color=red style=filled fillcolor=lightgrey]
        "Services.Logging"
    }
    subgraph "cluster_Services.Statistics" {
      label="Services.Statistics"
      graph [color=red style=filled fillcolor=lightgrey]
        "Services.Statistics"
    }
    subgraph "cluster_Services.Statistics.DataServiceRepo" {
      label="Services.Statistics.DataServiceRep"
      graph [color=red style=filled fillcolor=lightgrey]
        "Services.Statistics.DataServiceRepo"
    }
    subgraph "cluster_Services.Statistics.Dto" {
      label="Services.Statistics.Dto"
      graph [color=red style=filled fillcolor=lightgrey]
        "Services.Statistics.Dto"
    }
    subgraph "cluster_Services.Utilities" {
      label="Services.Utilities"
      graph [color=red style=filled fillcolor=lightgrey]
        "Services.Utilities"
    }   
  }    
  }

    "OssInterface.Host.Building" -> "Services.Logging"
    "OssInterface.Host.Building" -> "OssInterface"
    "OssInterface.Host.Building" -> "OssInterface.Host"
    "OssInterface.Host.Building" -> "OssInterface.Agent"
    "OssInterface.Host.Building" -> "OssInterface.Traps"
    "OssInterface.Host.Building" -> "OssInterface.Storage.Cache" 
    "OssInterface.Host.Building" -> "OssInterface.Storage"
    "OssInterface.Host.Building" -> "Services.Utilities"
    "OssInterface.Host.Building" -> "OssInterface.DataSources"
    "OssInterface.Host.Building" -> "OssInterface.Records"
    "OssInterface.Host.Building" -> "DataService.Proto.OssData"
    "OssInterface.Host.Building" -> "OssInterface.DataSources.GrpcStorages"
    "OssInterface.Host.Building" -> "OssInterface.DataSources.HttpStorages"
    "OssInterface.Host.Building" -> "Services.Localization" 
    "OssInterface.Host.Building" -> "Services.Statistics.DataServiceRepo" 
    "OssInterface.Host.Building" -> "OssInterface.Host.Statistics"
    "OssInterface.Host.Building" -> "Services.Statistics"
    "OssInterface.Host" -> "Services.Statistics"
    "OssInterface.Host" -> "OssInterface"
    "OssInterface.Host" -> "OssInterface.Traps"
    "OssInterface.Host.Statistics" -> "OssInterface.Agent"
    "OssInterface.Host.Statistics" -> "Services.Statistics"
    "OssInterface.Host.Statistics" -> "Services.Utilities"
    "OssInterface.Agent" -> "OssInterface"
    "OssInterface.Agent" -> "Services.Utilities"
    "OssInterface.Agent" -> "Services.Logging"
    "OssInterface.Agent" -> "OssInterface.Traps"
    "OssInterface.DataSources.GrpcStorages" -> "OssInterface.DataSources"
    "OssInterface.DataSources.GrpcStorages" -> "DataService.Proto.OssData"
    "OssInterface.DataSources.GrpcStorages" -> "OssInterface.Records"
    "OssInterface.DataSources.GrpcStorages" -> "OssInterface"
    "OssInterface.DataSources.GrpcStorages" -> "Services.Utilities"
    "OssInterface.DataSources.HttpStorages" -> "OssInterface.DataSources"
    "OssInterface.DataSources" -> "Services.Utilities"
    "OssInterface.DataSources" -> "Services.Logging"
    "OssInterface.DataSources" -> "OssInterface"
    "OssInterface" -> "Services.Logging"
    "OssInterface.Records" -> "OssInterface"
    "OssInterface.Storage" -> "OssInterface"
    "OssInterface.Storage" -> "Services.Logging"
    "OssInterface.Storage.Cache" -> "OssInterface.DataSources"
    "OssInterface.Storage.Cache" -> "Common.Trees"
    "OssInterface.Storage.Cache" -> "OssInterface.Storage"
    "OssInterface.Storage.Cache" -> "OssInterface"
    "OssInterface.Storage.Cache" -> "OssInterface.Records"
    "OssInterface.Storage.Cache" -> "OssInterface.Traps"
    "OssInterface.Storage" -> "Services.Utilities"
    "OssInterface.Storage" -> "OssInterface.Agent"
    "OssInterface.Traps" -> "OssInterface"
    "OssInterface.Traps" -> "OssInterface.DataSources"
    "OssInterface.Traps" -> "OssInterface.Records"
    "OssInterface.Traps" -> "Services.Utilities"
    "OssInterface.Traps" -> "Services.Logging"
    "OssInterface" -> "Services.Utilities"   
    "Common.Trees" -> "Common.Trees.Utils"
    "OssInterface.CliApp" -> "Services.Logging"
    "OssInterface.CliApp" -> "OssInterface.Host"
    "OssInterface.CliApp" -> "Services.Utilities"
    "OssInterface.CliApp" -> "OssInterface"
    "OssInterface.CliApp" -> "OssInterface.Host.Building"
    "OssInterface.UnitTests" -> "OssInterface.DataSources"
    "OssInterface.UnitTests.Fakes" -> "OssInterface.Storage"  
    "OssInterface.UnitTests.Fakes" -> "OssInterface"
    "OssInterface.UnitTests.Fakes" -> "Services.Logging"
    "OssInterface.UnitTests.Fakes" -> "OssInterface.Traps"
    "OssInterface.UnitTests.Fakes" -> "OssInterface.Agent"
    "OssInterface.UnitTests.Storage.Cache" -> "OssInterface.Storage.Cache" 
    "OssInterface.UnitTests.Storage.Cache" -> "OssInterface.Storage"
    "OssInterface.UnitTests.Storage.Cache" -> "OssInterface"
    "OssInterface.UnitTests.Storage" -> "OssInterface.Storage"
    "OssInterface.UnitTests.Storage" -> "OssInterface.UnitTests.Fakes"
    "OssInterface.UnitTests.Storage" -> "OssInterface.UnitTests"
    "OssInterface.UnitTests.Storage" -> "OssInterface.Storage.Cache"
    "OssInterface.UnitTests.Traps" -> "OssInterface.Traps"
    "OssInterface.UnitTests.Traps" -> "OssInterface.DataSources"
    "OssInterface.UnitTests.Traps" -> "OssInterface.UnitTests"
    "OssInterface.UnitTests.Traps" -> "OssInterface.Records"
    "OssInterface.UnitTests.Traps" -> "OssInterface"
    "OssInterface.UnitTests" -> "OssInterface.Traps"
    "OssInterface.UnitTests" -> "OssInterface"
    "OssInterface.UnitTests" -> "OssInterface.UnitTests.Fakes"
    "Services.Localization" -> "Services.Logging"
    "Services.Statistics" -> "Services.Statistics.Dto"
    "Services.Statistics" -> "Services.Logging"
    "Services.Statistics.DataServiceRepo" -> "Services.Statistics"
    "Services.Statistics.DataServiceRepo" -> "Services.Statistics.Dto"
    "Services.Utilities" -> "Services.Logging"
}

Giving:
enter image description here

Upvotes: 0

Related Questions