Dot rendering library

Example:

import dot

var graph = new DotGraph("G", "digraph")

var hello = graph.add_node("hello")
var world = graph.add_node("world")

graph.add_edge(hello, world)

print graph.to_dot

Introduced classes

class AttributeMap

dot :: AttributeMap

Map of graph/node/edge attribute that can be rendered to dot.
class DotEdge

dot :: DotEdge

A dot edge that links two nodes
abstract class DotElement

dot :: DotElement

Something that can be rendered in dot format.
class DotGraph

dot :: DotGraph

A Graph representation suited for dot format.
class DotNode

dot :: DotNode

A dot node

All class definitions

class AttributeMap

dot $ AttributeMap

Map of graph/node/edge attribute that can be rendered to dot.
class DotEdge

dot $ DotEdge

A dot edge that links two nodes
abstract class DotElement

dot $ DotElement

Something that can be rendered in dot format.
class DotGraph

dot $ DotGraph

A Graph representation suited for dot format.
class DotNode

dot $ DotNode

A dot node
package_diagram dot::dot dot core core dot::dot->core dot::clusters clusters dot::clusters->dot::dot dot::hello hello dot::hello->dot::dot dot::undirected_clusters undirected_clusters dot::undirected_clusters->dot::dot nitc::commands_graph commands_graph nitc::commands_graph->dot::dot a_star-m a_star-m a_star-m->dot::clusters a_star-m->dot::hello a_star-m->dot::undirected_clusters a_star-m... ... a_star-m...->a_star-m nitc::md_commands md_commands nitc::md_commands->nitc::commands_graph nitc::commands_parser commands_parser nitc::commands_parser->nitc::commands_graph nitc::commands_http commands_http nitc::commands_http->nitc::commands_graph nitc::json_commands json_commands nitc::json_commands->nitc::commands_graph nitc::md_commands... ... nitc::md_commands...->nitc::md_commands nitc::commands_parser... ... nitc::commands_parser...->nitc::commands_parser nitc::commands_http... ... nitc::commands_http...->nitc::commands_http nitc::json_commands... ... nitc::json_commands...->nitc::json_commands

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.

Children

module clusters

dot :: clusters

Example from http://www.graphviz.org/content/cluster
module commands_graph

nitc :: commands_graph

Graph commands
module hello

dot :: hello

Example from http://www.graphviz.org/content/hello
module undirected_clusters

dot :: undirected_clusters

Example from http://www.graphviz.org/Gallery/undirected/fdpclust.html

Descendants

module a_star-m

a_star-m

module api

nitc :: api

Components required to build a web server about the nit model.
module api_auth

nitc :: api_auth

module api_base

nitc :: api_base

Base classes used by nitweb.
module api_docdown

nitc :: api_docdown

Nitdoc specific Markdown format handling for Nitweb
module api_feedback

nitc :: api_feedback

Feedback related features
module api_light

nitc :: api_light

Highlight and collect messages from a piece of code
module api_model

nitc :: api_model

module commands_docdown

nitc :: commands_docdown

Doc down related queries
module commands_http

nitc :: commands_http

Initialize commands from HTTP requests
module commands_parser

nitc :: commands_parser

A parser that create DocCommand from a string
module html_commands

nitc :: html_commands

Render commands results as HTML
module json_commands

nitc :: json_commands

Translate command results to json
module md_commands

nitc :: md_commands

Render commands results as Markdown
module nitdoc

nitc :: nitdoc

Generator of static API documentation for the Nit language
module nitweb

nitc :: nitweb

Runs a webserver based on nitcorn that render things from model.
module nitx

nitc :: nitx

nitx, a command tool that displays useful data about Nit code
module static

nitc :: static

Nitdoc generation framework
module static_base

nitc :: static_base

Base entities shared by all the nitdoc code
module static_cards

nitc :: static_cards

Cards templates for the static documentation
module static_html

nitc :: static_html

Render documentation pages as HTML
module static_index

nitc :: static_index

Manage indexing of Nit model for Nitdoc QuickSearch.
module static_structure

nitc :: static_structure

Composes the pages of the static documentation
module term

nitc :: term

# Dot rendering library
#
# Example:
# ~~~
# import dot
#
# var graph = new DotGraph("G", "digraph")
#
# var hello = graph.add_node("hello")
# var world = graph.add_node("world")
#
# graph.add_edge(hello, world)
#
# print graph.to_dot
# ~~~
module dot

# Something that can be rendered in dot format.
abstract class DotElement

	# Element ID
	var id: String

	# Element attributes
	var attrs = new AttributeMap

	# Get attribute value for `key`
	fun [](key: String): Object do return attrs[key]

	# Set attribute `value` for `key`
	fun []=(key: String, value: Object) do attrs[key] = value

	# Render `self` to dot format
	fun to_dot: Text do
		var res = new Buffer
		res.append "\"{escape_id}\" "
		if attrs.not_empty then res.append "[{attrs.to_dot(",")}]"
		return res.write_to_string
	end

	# Return `id.escape_to_dot`
	fun escape_id: String do return id.escape_to_dot
end

# Map of graph/node/edge attribute that can be rendered to dot.
class AttributeMap
	super HashMap[String, Object]

	# Render `self` to dot.
	#
	# Use `;` for graph attributes `separator` or `,` for node and edge attributes.
	fun to_dot(separator: String): Text do
		var dot = new Buffer
		for key, value in self do
			dot.append "{key}=\"{value.to_s}\"{separator}"
		end
		return dot
	end
end

# A Graph representation suited for dot format.
#
# Creating a new graph
# ~~~
# var graph = new DotGraph("G", "digraph")
# graph["rankdir"] = "BT"
# graph["ranksep"] = 0.3
# graph["nodesep"] = 0.3
# graph.nodes_attrs["fontname"] = "helvetica"
# graph.edges_attrs["color"] = "gray"
# ~~~
#
# Creating subgraphs
# ~~~
# var sub = new DotGraph("cluster_sub", "subgraph")
# sub["label"] = "process #1"
#
# var a0 = sub.add_node("a0")
# var a1 = sub.add_node("a1")
# sub.add_edge(a0, a1)
#
# graph.add sub
# ~~~
class DotGraph
	super DotElement

	# Graph kind like `graph`, `digraph`, `subgraph`...
	var kind: String is writable

	# Nodes attributes
	var nodes_attrs = new AttributeMap

	# Edges attributes
	var edges_attrs = new AttributeMap

	# Node list by id
	var nodes = new HashMap[String, DotElement]

	# Add a node to the graph
	#
	# If the graph already contains a node with that ID, it will be replaced.
	fun add(element: DotElement) do
		nodes[element.id] = element
	end

	# Edge list
	#
	# There can be multiple edges between the same couple of nodes.
	var edges = new Array[DotEdge]

	# Add a new node to the graph
	fun add_node(id: String): DotNode do
		var node = new DotNode(id)
		add node
		return node
	end

	# Add an edge to the graph
	fun add_edge(from, to: DotElement): DotEdge do
		var edge = new DotEdge(from, to)
		add edge
		return edge
	end

	redef fun to_dot do
		var dot = new Buffer
		dot.append "{kind} \"{id}\" \{\n"
		if attrs.not_empty then dot.append attrs.to_dot(";\n")
		if nodes_attrs.not_empty then dot.append "node[{nodes_attrs.to_dot(",")}];\n"
		if edges_attrs.not_empty then dot.append "edge[{edges_attrs.to_dot(",")}];\n"
		for id, node in nodes do
			dot.append "{node.to_dot};\n"
		end
		for edge in edges do
			dot.append("{edge.to_dot};\n")
		end
		dot.append("\}")
		return dot
	end

	# Render `self` as an SVG image
	fun to_svg: Text do
		var proc = new ProcessDuplex("dot", "-Tsvg")
		var svg = proc.write_and_read(to_dot)
		proc.close
		proc.wait
		return svg
	end

	# Show dot in graphviz (blocking)
	fun show do
		var f = new ProcessWriter("dot", "-Txlib")
		f.write to_dot
		f.close
		f.wait
	end
end

# A dot node
#
# Nodes can be created from scratch
# ~~~
# var node = new DotNode("id")
# node["label"] = "ID"
# ~~~
# Then added to a graph
# ~~~
# var graph = new DotGraph("G", "digraph")
# graph.add node
# ~~~
# Or can be created directly from an existing graph
# ~~~
# var node2 = graph.add_node("id2")
# node2["label"] = "ID2"
# ~~~
class DotNode
	super DotElement
end

# A dot edge that links two nodes
#
# Edges can be created from scratch
# ~~~
# var a1 = new DotNode("a1")
# var b1 = new DotNode("b1")
# var edge = new DotEdge(a1, b1)
# edge["color"] = "blue"
# ~~~
# Then added to a graph
# ~~~
# var graph = new DotGraph("G", "digraph")
# graph.add edge
# ~~~
# Or can be created directly from an existing graph
# ~~~
# var a2 = graph.add_node("a2")
# var b2 = graph.add_node("b2")
# var edge2 = graph.add_edge(a2, b2)
# edge2["color"] = "red"
# ~~~
class DotEdge
	super DotElement
	autoinit from, to

	# Node this edge is from
	var from: DotElement

	# Node this edge goes to
	var to: DotElement

	# Is this edge directed?
	var directed = true is writable

	redef fun id do return "{from.id}--{to.id}"

	redef fun to_dot do
		var res = new Buffer
		res.append "\"{from.escape_id}\" "
		if directed then
			res.append "->"
		else
			res.append "--"
		end
		res.append " \"{to.escape_id}\" "
		if attrs.not_empty then res.append "[{attrs.to_dot(",")}]"
		return res.write_to_string
	end
end
lib/dot/dot.nit:15,1--242,3