dogviz

A domain object graph (DOG) visualisation built on ruby-graphviz and hence Graphviz

Usage

gem install dogviz
ruby examples/dogfood.rb

Example

Here is the diagram rendered by running the dogfood example

generated graph from examples/dogfood.rb

Use the simple DSL to build your domain graph of things which can be in containers, which in turn can be nested.

Things can point to other things.

Because this is ruby you can use known refactorings for DOG construction: extract methods, push into classes etc.

No external DSL rubbish here! ;)

require 'dogviz'

def create_classes_description(root)
  classes = root.container('classes')
  system = classes.thing('System')
  thing = classes.thing('Thing')
  container = classes.thing('Container')
  container.points_to thing, name: 'contains'
  container.points_to container, name: 'contains'
  system.points_to thing, name: 'contains'
  system.points_to container, name: 'contains'

  classes
end

def create_nested_container_example(root)
  example = root.container 'example DOG'
  thing = example.thing 'a thing outside a container'
  container = example.container 'a container'
  container_thing = container.thing 'a thing in a container'
  nested_container = container.container 'a nested container'
  nested_c_thing = nested_container.thing 'a thing in a nested container'

  container_thing.points_to nested_c_thing
  nested_c_thing.points_to thing, name: 'things point to other things'

  nested_container
end

def create_dog(classes: true)
  domain_object_graph = Dogviz::System.new 'dogviz'

  create_classes_description(domain_object_graph) if classes
  usage = domain_object_graph.group('usage')

  create_nested_container_example(usage)

  domain_object_graph
end

create_dog().output jpg: 'examples/dogviz-generated.jpg'

dog_rolled_up = create_dog(classes: false)
dog_rolled_up.find('a nested container').rollup!
dog_rolled_up.output jpg: 'examples/dogviz-rolled-up-generated.jpg'

Rolling up

You can rollup! containers before rendering so that a single DOG can be used to render simplified views.

The following output from above example shows how diagram can be simplified by rolling up the nested container. Note that pointers to/from contained things are handled gracefully (i think :/).

generated rolled up graph from examples/dogfood.rb

Other Features

#nominate

Containers can #nominate a thing so that it is referenceable via a method call on container.

It's useful if some code somewhere builds a container with multiple thing entry points you might want to point to

def create_c(sys)
  c = sys.container('c')
  c.nominate a: c.thing('a')
  c.nominate b: c.thing('b')
  c
end

c = create_c(sys)
x = sys.thing('x')
x.points_to c.a
x.points_to c.b

Add a documentation link to thing so that url can be visited clicking on the thing an svg output.

thing.doclink("https://github.com/")

splines

Splines can be turned on or off by providing flag to System.new

System.new 'dog', splines: false

Extendable classes

Using standard ruby extension of System, Container and Thing classes, you can easily use:

  • language specific to your domain
  • styling specific to your types
module Creators
  def box(name, options={})
    add Box.new(self, name, options)
  end
end
class WebsiteSystem < System
  include Creators
end
class Box < Container
  def initialize(parent, name, options={})
    super parent, name, {style: 'filled', color: '#ffaaaa'}.merge(options)
  end
  def process(name)
    add Process.new self, name
  end
end
class Process < Thing
  def initialize(parent, name)
    super parent, name, style: 'filled'
  end
  def calls(callee, options={})
    points_to callee, options
  end
end

sys = WebsiteSystem.new 'website'
box = sys.box('website box')
box.process('nginx').calls(box.process('app'))