Index of sample files created by GraphViz2 V 2.56.

All scripts and input files required to generate these examples are available in the GraphViz2 repo.

Input file # 1 - t/gen.Heawood.t

Demonstrates the transitive 6-net, also known as Heawood's graph.

# Annotation: Demonstrates the transitive 6-net, also known as Heawood's graph.
#
# Reverse-engineered from graphs/directed/Heawood.gv from the Graphviz distro for V 2.26.3.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2 -> new(
	global => {name => 'Heawood'},
	graph  => {rankdir => 'TB'},
);

$graph->default_edge(color => 'black');
$graph->default_node(
 fontname => "Arial",
 shape    => "circle",
 width    => "0.50000",
 height   => "0.50000",
 color    => "black",
);

$graph->add_edge(from => $_, to => ($_ + 1) ) for 0 .. 12;
$graph -> add_edge(from => 13, to =>  0);
$graph -> add_edge(from =>  0, to =>  5, len => 2.5);
$graph -> add_edge(from =>  2, to =>  7, len => 2.5);
$graph -> add_edge(from =>  4, to =>  9, len => 2.5);
$graph -> add_edge(from =>  6, to => 11, len => 2.5);
$graph -> add_edge(from =>  8, to => 13, len => 2.5);
$graph -> add_edge(from => 10, to =>  1, len => 2.5);
$graph -> add_edge(from => 12, to =>  3, len => 2.5);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec->catfile('html', "Heawood.$format");
  $graph->run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 1 - gen.Heawood.svg

Input file # 2 - t/gen.anonymous.t

Demonstrates empty strings for node names and labels.

# Annotation: Demonstrates empty strings for node names and labels.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
 edge   => {color => 'grey'},
 global => {directed => 1},
 graph  => {rankdir => 'TB'},
 node   => {shape => 'oval'},
);

$graph -> add_node(name => '', label => ''); # Same as add_node().
$graph -> add_node(name => 'Anonymous label 1', label => '');
$graph -> add_node(name => 'Anonymous label 2', label => '');
$graph -> add_edge(from => '', to => ''); # This uses the name '', and hence the first node.

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "anonymous.$format");
  $graph->run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 2 - gen.anonymous.svg

Input file # 3 - t/gen.circo.t

Demonstrates calling circo instead of dot.

# Annotation: Demonstrates calling circo instead of dot.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {
          rankdir => 'TB',
          page => '8.25,10.75',
          rotate => '90',
          margin => '0.125',
          size => '8.25,10.75'
        },
	node   => {shape => 'oval'},
);
$graph -> add_edge(from => 'Here', to => 'There');
$graph -> add_edge(from => 'There', to => 'Everywhere');
$graph -> add_edge(from => 'Everywhere', to => 'Here');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "circo.$format");
  $graph->run(driver => 'circo', format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 3 - gen.circo.svg

Input file # 4 - t/gen.cluster.t

Demonstrates a cluster.

# Annotation: Demonstrates a cluster.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
 edge   => {color => 'grey'},
 global => {directed => 1},
 graph  => {clusterrank => 'local', compound => 1, rankdir => 'TB'},
 node   => {shape => 'oval'},
);

$graph -> push_subgraph(name => 'cluster_Europe', graph => {
  bgcolor => 'grey', label => 'Europe'
});
$graph -> add_node(name => 'London', color => 'blue');
$graph -> add_node(
  name => 'Paris', color => 'green', label => 'City of\nlurve',
);
$graph -> add_edge(from => 'London', to => 'Paris');
$graph -> add_edge(from => 'Paris', to => 'London');
$graph -> pop_subgraph;

$graph -> add_node(name => 'New York', color => 'yellow');
$graph -> add_edge(from => 'London', to => 'New York', label => 'Far');

$graph -> push_subgraph(name => 'cluster_Australia', graph => {
  bgcolor => 'grey', label => 'Australia',
});
$graph -> add_node(name => 'Victoria', color => 'blue');
$graph -> add_node(name => 'New South Wales', color => 'green');
$graph -> add_node(name => 'Tasmania', color => 'red');
$graph -> add_edge(from => 'Victoria', to => 'New South Wales');
$graph -> add_edge(from => 'Victoria', to => 'Tasmania');
$graph -> pop_subgraph;

$graph -> add_edge(
  from => 'Victoria',
  to => 'London',
  ltail => 'cluster_Australia',
  lhead => 'cluster_Europe',
);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "cluster.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 4 - gen.cluster.svg

Input file # 5 - t/gen.html.labels.1.t

Demonstrates a HTML label without a table.

# Annotation: Demonstrates a HTML label without a table.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id    = 1;
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {
	  label => "HTML label demo # $id - Using \\< ... \\>",
          rankdir => 'TB',
        },
	node   => {shape => 'oval'},
);
$graph -> default_node(shape     => 'circle', style => 'filled');
$graph -> default_edge(arrowsize => 4);

$graph -> add_node(name => 'Carnegie', shape => 'circle');
$graph -> add_node(name => 'Carnegie', color => 'red');

$graph -> default_node(style => 'rounded');

$graph -> add_node(
  name => 'Murrumbeena',
  shape => 'doublecircle',
  color => 'green',
  label =>
    '<Murrumbeena<br/><font color="#0000ff">Victoria</font><br/>Australia>',
);
$graph -> add_node(
  name => 'Oakleigh',
  shape => 'record',
  color => 'blue',
  label => ['West Oakleigh', 'East Oakleigh'],
);

$graph -> add_edge(
  from => 'Murrumbeena',
  to => 'Carnegie',
  arrowsize => 2,
  label => '<Bike<br/>Train<br/>Stroll>',
);

$graph -> default_edge(arrowsize => 1);

$graph -> add_edge(
  from => 'Murrumbeena',
  to => 'Oakleigh:port1',
  color => 'brown',
  label => '<Meander<br/>Promenade<br/>Saunter>',
);
$graph -> add_edge(
  from => 'Murrumbeena',
  to => 'Oakleigh:port2',
  color => 'green',
  label => '<Drive<br/>Run<br/>Sprint>',
);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "html.labels.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 5 - gen.html.labels.1.svg

Input file # 6 - t/gen.html.labels.2.t

Demonstrates a HTML label with a table.

# Annotation: Demonstrates a HTML label with a table.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id    = 2;
my $graph = GraphViz2->new(
	global => {directed => 1},
	graph  => {
          label => "HTML label demo # $id - Using \\<\\<table\\> ... " .
            "\\</table\\>\\>",
        },
);

$graph->add_node(
	label => q|
<<table bgcolor = 'white'>
<tr>
	<td bgcolor = 'palegreen'>The green node is the start node</td>
</tr>
<tr>
	<td bgcolor = 'lightblue'>Lightblue nodes are for lexeme attributes</td>
</tr>
<tr>
	<td bgcolor = 'orchid'>Orchid nodes are for lexemes</td>
</tr>
<tr>
	<td bgcolor = 'goldenrod'>Golden nodes are for actions</td>
</tr>
<tr>
	<td bgcolor = 'firebrick1'>Red nodes are for events</td>
</tr>
</table>>
|,
	name  => 'Legend',
	shape => 'plaintext',
);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "html.labels.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 6 - gen.html.labels.2.svg

Input file # 7 - t/gen.html.labels.3.t

Demonstrates HTML labels with newlines and double-quotes.

# Annotation: Demonstrates HTML labels with newlines and double-quotes.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id    = 3;
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => "HTML label demo # $id - Fixing newlines", rankdir => 'TB'},
	node   => {shape => 'oval'},
);

$graph -> add_node(name => 'One', label => '
<One<br/><font color="#0000ff">Blue</font><br/>>
');

$graph -> add_node(name => 'Two', label => '<
Two<br/><font color="#00ff00">Green</font><br/>
>');

$graph -> add_node(name => 'Three', color => 'red', label => '
<<table border="1"><tr><td align="left">Three</td></tr><tr align="right"><td>Red</td></tr></table>>
');

$graph -> add_node(name => 'Four', color => 'magenta', label => '<
<table border="1"><tr><td align="left">Four<br />magenta</td></tr></table>
>');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "html.labels.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 7 - gen.html.labels.3.svg

Input file # 8 - t/gen.jointed.edges.t

Demonstrates Y-shaped edges between 3 nodes.

# Annotation: Demonstrates Y-shaped edges between 3 nodes.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my %junction = (color => 'grey', shape => 'point', width => 0);
# Note: arrowhead is case-sensitive (i.e. arrowHead does not work).
my %headless_arrow = (arrowhead => 'none');

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {rankdir => 'TB'},
	node   => {shape => 'oval', style => 'filled'},
);

# Node set 1:
$graph->add_node(name => 'Carnegie',    color => 'aquamarine');
$graph->add_node(name => 'Murrumbeena', color => 'bisque');
$graph->add_node(name => 'Oakleigh',    color => 'blueviolet');
$graph->add_node(name => 'one', %junction); # 1st of 2 junction nodes
$graph->add_edge(from => 'Murrumbeena', to => 'one', %headless_arrow);
$graph->add_edge(from => 'Carnegie',    to => 'one', %headless_arrow);
$graph->add_edge(from => 'one',         to => 'Oakleigh');

# Node set 2:
$graph->add_node(name => 'Ashburton', color => 'lawngreen');
$graph->add_node(name => 'Chadstone', color => 'coral');
$graph->add_node(name => 'Waverley',  color => 'crimson');
$graph->add_node(name => 'two', %junction); # 2nd of 2 junction nodes
$graph->add_edge(from => 'Ashburton', to => 'two', %headless_arrow);
$graph->add_edge(from => 'Chadstone', to => 'two', %headless_arrow);
$graph->add_edge(from => 'two',       to => 'Waverley');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec->catfile('html', "jointed.edges.$format");
  $graph->run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 8 - gen.jointed.edges.svg

Input file # 9 - t/gen.macro.1.t

Demonstrates non-cluster subgraphs via a macro.

# Annotation: Demonstrates non-cluster subgraphs via a macro.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

sub macro {
	my($graph, $name, $node_1, $node_2) = @_;
	$graph->push_subgraph(
		 name  => $name,
		 graph => {label => $name},
		 node  => {color => 'magenta', shape => 'diamond'},
	);
	$graph->add_node(name => $node_1, shape => 'hexagon');
	$graph->add_node(name => $node_2, color => 'orange');
	$graph->add_edge(from => $node_1, to => $node_2);
	$graph->pop_subgraph;
}

my $id    = '1';
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => "Macro demo $id - Non-cluster sub-graphs", rankdir => 'TB'},
);

macro($graph, 'One', 'Chadstone', 'Waverley');
macro($graph, 'Two', 'Hughesdale', 'Notting Hill');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "macro.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 9 - gen.macro.1.svg

Input file # 10 - t/gen.macro.2.t

Demonstrates linked non-cluster subgraphs via a macro.

# Annotation: Demonstrates linked non-cluster subgraphs via a macro.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

sub macro {
	my ($graph, $name, $node_1, $node_2) = @_;
	$graph->push_subgraph(
		name  => $name,
		graph => {label => $name},
		node  => {color => 'magenta', shape => 'diamond'},
	);
	$graph->add_node(name => $node_1, shape => 'hexagon');
	$graph->add_node(name => $node_2, color => 'orange');
	$graph->add_edge(from => $node_1, to => $node_2);
	$graph->pop_subgraph;
}

my $id    = '2';
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => "Macro demo $id - Linked non-cluster sub-graphs", rankdir => 'TB'},
	node   => {shape => 'oval'},
);

macro($graph, 'One', 'Chadstone', 'Waverley');
macro($graph, 'Two', 'Hughesdale', 'Notting Hill');

$graph->add_edge(from => 'Chadstone', to => 'Notting Hill', minlen => 2);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "macro.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 10 - gen.macro.2.svg

Input file # 11 - t/gen.macro.3.t

Demonstrates cluster subgraphs via a macro.

# Annotation: Demonstrates cluster subgraphs via a macro.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

sub macro {
	my ($graph, $name, $node_1, $node_2) = @_;
	$graph->push_subgraph(
		name  => $name,
		graph => {label => $name},
		node  => {color => 'magenta', shape => 'diamond'},
	);
	$graph->add_node(name => $node_1, shape => 'hexagon');
	$graph->add_node(name => $node_2, color => 'orange');
	$graph->add_edge(from => $node_1, to => $node_2);
	$graph->pop_subgraph;
}

my $id    = '3';
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => "Macro demo $id - Cluster sub-graphs", rankdir => 'TB'},
);

macro($graph, 'cluster 1', 'Chadstone', 'Waverley');
macro($graph, 'cluster 2', 'Hughesdale', 'Notting Hill');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "macro.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  $graph->run(format => 'dot'); # leave here as a canary so test "run"
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 11 - gen.macro.3.svg

Input file # 12 - t/gen.macro.4.t

Demonstrates linked cluster subgraphs via a macro.

# Annotation: Demonstrates linked cluster subgraphs via a macro.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

sub macro {
	my ($graph, $name, $node_1, $node_2) = @_;
	$graph->push_subgraph(
		name  => $name,
		graph => {label => $name},
		node  => {color => 'magenta', shape => 'diamond'},
	);
	$graph->add_node(name => $node_1, shape => 'hexagon');
	$graph->add_node(name => $node_2, color => 'orange');
	$graph->add_edge(from => $node_1, to => $node_2);
	$graph->pop_subgraph;
}

my $id    = '4';
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => "Macro demo $id - Linked cluster sub-graphs", rankdir => 'TB'},
);

macro($graph, 'cluster 1', 'Chadstone', 'Waverley');
macro($graph, 'cluster 2', 'Hughesdale', 'Notting Hill');

$graph -> add_edge(from => 'Chadstone', to => 'Notting Hill', minlen => 2);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "macro.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 12 - gen.macro.4.svg

Input file # 13 - t/gen.macro.5.t

Demonstrates compound cluster subgraphs via a macro.

# Annotation: Demonstrates compound cluster subgraphs via a macro.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

sub macro {
	my ($graph, $name, $node_1, $node_2) = @_;
	$graph->push_subgraph(
		name  => $name,
		graph => {label => $name},
		node  => {color => 'magenta', shape => 'diamond'},
	);
	$graph->add_node(name => $node_1, shape => 'hexagon');
	$graph->add_node(name => $node_2, color => 'orange');
	$graph->add_edge(from => $node_1, to => $node_2);
	$graph->pop_subgraph;
}

my $id    = '5';
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {
		compound => 'true',
		label => "Macro demo $id - Compound cluster sub-graphs",
		rankdir => 'TB',
        },
);

macro($graph, 'cluster 1', 'Chadstone', 'Waverley');
macro($graph, 'cluster 2', 'Hughesdale', 'Notting Hill');

$graph->add_edge(
	from => 'Chadstone',
	to => 'Notting Hill',
	lhead => 'cluster 2',
	ltail => 'cluster 1',
	minlen => 2,
);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "macro.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 13 - gen.macro.5.svg

Input file # 14 - t/gen.map.3.t

Demonstrates a graph with a 'plaintext' shape.

# Annotation: Demonstrates a graph with a 'plaintext' shape.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id		= 3;
my $html_template = <<'EOF';
<html>
<head><title>Demo %1$s - A server-side image map</title></head>
<body><h1 align = 'center'>Demo %1$s - A server-side image map</h1></body>
</html>
EOF
my $file_main = "gen.map.$id.1.html";
my $file_2 = "gen.map.$id.2.html";
my $file_3 = "gen.map.$id.3.html";
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {
		directed	=> 1,
		name		=> 'mainmap',
	},
	graph	=> {rankdir => 'TB'},
	im_meta	=> {
		URL => $file_main,	# Note: URL must be in caps.
	},
	node	=> {shape => 'oval'},
);

$graph->add_node(name => 'source', URL => $file_2);
$graph->add_node(name => 'destination');
$graph->add_edge(from => 'source', to => 'destination', URL => $file_3);

if (@ARGV) {
  my($format)			= shift || 'png';
  my $output_file = shift || "map.$id.$format";
  (my $volume, my $dirname) = File::Spec->splitpath($output_file);
  my($im_format)		= shift || 'imap';
  my $im_output_file = shift || File::Spec->catpath($volume, $dirname, "gen.map.$id.map");
  $graph->run(format => $format, output_file => $output_file, im_format => $im_format, im_output_file => $im_output_file);
  for ($file_main, $file_2, $file_3) {
    open my $fh, '>', File::Spec->catpath($volume, $dirname, $_) or die "$_: $!";
    print $fh sprintf $html_template, $_;
  }
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 14 - gen.map.3.svg

Input file # 15 - t/gen.map.4.t

Demonstrates a graph with a 'plaintext' shape.

# Annotation: Demonstrates a graph with a 'plaintext' shape.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id		= 4;
my $html_template = <<'EOF';
<html>
<head><title>Demo %1$s - A server-side image map</title></head>
<body><h1 align = 'center'>Demo %1$s - A server-side image map</h1></body>
</html>
EOF
my $file_main = "gen.map.$id.1.html";
my $file_2 = "gen.map.$id.2.html";
my $file_3 = "gen.map.$id.3.html";
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {
		directed	=> 1,
		name		=> 'mainmap',
	},
	graph	=> {rankdir => 'TB'},
	im_meta	=> {
		URL => $file_main,	# Note: URL must be in caps.
	},
	node	=> {shape => 'oval'},
);

$graph->add_node(name => 'source', URL => $file_2);
$graph->add_node(name => 'destination');
$graph->add_edge(from => 'source', to => 'destination', URL => $file_3);

if (@ARGV) {
  my($format)			= shift || 'svg';
  my $output_file = shift || "map.$id.$format";
  my($im_format)		= shift || 'cmapx';
  (my $volume, my $dirname) = File::Spec->splitpath($output_file);
  my $im_output_file = shift || File::Spec->catpath($volume, $dirname, "gen.map.$id.map");
  $graph -> run(format => $format, output_file => $output_file, im_format => $im_format, im_output_file => $im_output_file);
  for ($file_main, $file_2, $file_3) {
    open my $fh, '>', File::Spec->catpath($volume, $dirname, $_) or die "$_: $!";
    print $fh sprintf $html_template, $_;
  }
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 15 - gen.map.4.svg

Input file # 16 - t/gen.parse.regexp.t

Demonstrates graphing a Perl regular expression.

# Annotation: Demonstrates graphing a Perl regular expression.

use strict;
use warnings;
use File::Spec;
use GraphViz2;
use GraphViz2::Parse::Regexp;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {rankdir => 'TB'},
	node   => {color => 'blue', shape => 'oval'},
);
my $g = GraphViz2::Parse::Regexp->new(graph => $graph);

$g->create(regexp => '(([abcd0-9])|(foo))');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "parse.regexp.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  local our $TODO = 'seems to vary by Perl version';
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 16 - gen.parse.regexp.svg

Input file # 17 - t/gen.parse.stt.t

Demonstrates graphing a Set::FA::Element's state transition table.

# Annotation: Demonstrates graphing a Set::FA::Element's state transition table.

use strict;
use warnings;
use File::Spec;
use GraphViz2;
use GraphViz2::Parse::STT;

sub read_file {
  open my $fh, '<:encoding(UTF-8)', $_[0] or die "$_[0]: $!";
  local $/;
  <$fh>;
}

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {rankdir => 'LR'},
	node   => {color => 'green', shape => 'oval'},
);
my $g = GraphViz2::Parse::STT->new(graph => $graph);
my $stt = read_file(File::Spec->catfile('t', 'sample.stt.1.dat') );

$g->create(stt => $stt);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "parse.stt.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 17 - gen.parse.stt.svg

Input file # 18 - t/gen.parse.yacc.t

Demonstrates graphing a byacc-style grammar.

# Annotation: Demonstrates graphing a byacc-style grammar.

use strict;
use warnings;
use File::Spec;
use GraphViz2;
use GraphViz2::Parse::Yacc;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {concentrate => 1, rankdir => 'TB'},
	node   => {color => 'blue', shape => 'oval'},
);
my $g = GraphViz2::Parse::Yacc->new(graph => $graph);

$g->create(file_name => File::Spec->catfile('t', 'calc3.output'));

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "parse.yacc.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 18 - gen.parse.yacc.svg

Input file # 19 - t/gen.parse.yapp.t

Demonstrates graphing a yapp-style grammar.

# Annotation: Demonstrates graphing a yapp-style grammar.

use strict;
use warnings;
use File::Spec;
use GraphViz2;
use GraphViz2::Parse::Yapp;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {concentrate => 1, rankdir => 'TB'},
	node   => {color => 'blue', shape => 'oval'},
);
my $g = GraphViz2::Parse::Yapp->new(graph => $graph);

$g->create(file_name => File::Spec -> catfile('t', 'calc.output'));

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "parse.yapp.$format");
  $graph->run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 19 - gen.parse.yapp.svg

Input file # 20 - t/gen.plaintext.t

Demonstrates a graph with a 'plaintext' shape.

# Annotation: Demonstrates a graph with a 'plaintext' shape.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new;

$graph->add_node(name => 'Murrumbeena', shape => 'plaintext');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "plaintext.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 20 - gen.plaintext.svg

Input file # 21 - t/gen.quote.t

Demonstrates (1) newlines and double-quotes in node names and labels, (2) justification.

# Annotation: Demonstrates (1) newlines and double-quotes in node names and labels, (2) justification.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	global => {directed => 1},
	graph  => {rankdir => 'LR'},
	node   => {shape => 'oval'},
);

$graph->add_node(name => "Embedded\\nnewline\\nnode\\nname");
$graph->add_node(
	name => "Embedded newline label name",
	label => "Embedded\\nnewline\\nlabel",
);
$graph->add_node(name => "Embedded\\ndouble-quote\\nnode\\nname\\n\\\"");
$graph->add_node(
	name => "Embedded\\double-quote\\label",
	label => qq|Embedded\\ndouble-quote\\nlabel\\n\"|,
);
$graph->add_node(
	name => 'Line justification 1',
	label => "A short line\\rA much longer line",
);
$graph->add_node(
	name => 'Line justification 2',
	label => "A much longer line\\rA short line",
);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "quote.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 21 - gen.quote.svg

Input file # 22 - t/gen.rank.sub.graph.1.t

Demonstrates subgraphs used to rank nodes horizontally (succinct version of code).

# Annotation: Demonstrates subgraphs used to rank nodes horizontally (succinct version of code).

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	edge     => {color => 'grey'},
	global   => {directed => 1},
	graph    => {rankdir => 'TB'},
	node     => {shape => 'oval'},
	subgraph => {rank => 'same'},
);

$graph->add_node(name => 'Carnegie',    shape => 'circle');
$graph->add_node(name => 'Chadstone',   shape => 'circle', color => 'red');
$graph->add_node(name => 'Malvern',     shape => 'box', color => 'green');
$graph->add_node(name => 'Murrumbeena', shape => 'doublecircle', color => 'orange');
$graph->add_node(name => 'Oakleigh',    color => 'blue');

$graph->add_edge(from => 'Chadstone', to => 'Oakleigh', arrowhead => 'odot');
$graph->add_edge(from => 'Malvern',   to => 'Carnegie', arrowsize => 2);
$graph->add_edge(from => 'Malvern',   to => 'Oakleigh', color => 'brown');

# a and b are arbitrary values. All that's happening is that all nodes
# in @{$rank{a} } will be in the same horizontal line, and likewise for b.

my %rank = (a => [qw(Malvern Prahran)], b => [qw(Oakleigh Murrumbeena)]);

for my $key (sort keys %rank) {
	$graph->push_subgraph;
	$graph->add_node(name => $_) for @{$rank{$key} };
	$graph->pop_subgraph;
}

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec->catfile('html', "rank.sub.graph.1.$format");
  $graph->run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 22 - gen.rank.sub.graph.1.svg

Input file # 23 - t/gen.record.1.t

Nested records using strings as labels.

# Annotation: Nested records using strings as labels.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id    = '1';
my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => "Record demo $id - Nested records using strings as labels"},
	node   => {shape => 'record'},
);

$graph->add_node(name => 'struct1::x', label => '<f0> left|<f1> mid dle|<f2> right');
$graph->add_node(name => 'struct2', label => '<f0> one|<f1> two');
$graph->add_node(
	name => 'struct3',
	label => "hello\\nworld |{ b |{c|<here> d|e}| f}| g | h",
);

$graph->add_edge(from => 'struct1::x:f1', to => 'struct2:f0', color => 'blue');
$graph->add_edge(from => 'struct1::x:f2', to => 'struct3:here', color => 'red');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec->catfile('html', "record.$id.$format");
  $graph->run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 23 - gen.record.1.svg

Input file # 24 - t/gen.record.2.t

Nested records using an arrayref of hashrefs as labels.

# Annotation: Nested records using an arrayref of hashrefs as labels.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id    = '2';
my $graph = GraphViz2->new(
	global => {directed => 1},
	graph  => {label => "Record demo $id - Nested records using an arrayref of hashrefs as labels"},
	node   => {shape => 'record'},
);

$graph->add_node(name => 'struct1', label => '<f0> left|<f1> mid dle|<f2> right');
$graph->add_node(name => 'struct2', label => '<f0> one|<f1> two');
$graph->add_node(name => 'struct3', label => [
	{
		text => "hello\\nworld",
	},
	{
		text => '{b',
	},
	{
		text => '{c',
	},
	{
		port => '<here>',
		text => 'd',
	},
	{
		text => 'e}',
	},
	{
		text => 'f}',
	},
	{
		text => 'g',
	},
	{
		text => 'h',
	},
]);

$graph->add_edge(from => 'struct1:f1', to => 'struct2:f0',   color => 'blue');
$graph->add_edge(from => 'struct1:f2', to => 'struct3:here', color => 'red');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "record.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 24 - gen.record.2.svg

Input file # 25 - t/gen.record.3.t

Deeply nested records using strings as labels.

# Annotation: Deeply nested records using strings as labels.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id    = '3';
my $graph = GraphViz2->new(
	global => {directed => 1},
	graph  => {
          label => "Record demo $id - Deeply nested records " .
            "using strings as labels"
        },
	node   => {shape => 'record'},
);

$graph->add_node(name => 'Alphabet',
label => join('|',
  '<port_a> a:port_a ',
  '{<port_b> b:port_b ',
  ' c ',
  '{<port_d> d:port_d ',
  ' e ',
  ' f ',
  '{ g ',
  '<port_h> h:port_h ',
  ' i ',
  ' j ',
  '{ k ',
  ' l ',
  ' m ',
  '<port_n> n:port_n ',
  ' o ',
  ' p}',
  ' q ',
  ' r ',
  '<port_s> s:port_s ',
  ' t }',
  ' u ',
  ' v ',
  '<port_w> w:port_w }',
  ' x ',
  '<port_y> y:port_y }',
  ' z',
));

$graph -> add_edge(
  from => 'Alphabet:port_a', to => 'Alphabet:port_n', color => 'maroon',
);
$graph -> add_edge(
  from => 'Alphabet:port_b', to => 'Alphabet:port_s', color => 'blue',
);
$graph -> add_edge(
  from => 'Alphabet:port_d', to => 'Alphabet:port_w', color => 'red',
);
$graph -> add_edge(
  from => 'Alphabet:port_y', to => 'Alphabet:port_h', color => 'green',
);

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "record.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 25 - gen.record.3.svg

Input file # 26 - t/gen.record.4.t

Set record-style node labels and shapes in various ways.

# Annotation: Set record-style node labels and shapes in various ways.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $id    = '4';
my $graph = GraphViz2->new(
	global => {directed => 1},
	graph  => {label => "Record demo $id - Set record shapes in various ways"},
	node   => {color => 'magenta'},
);

$graph->add_node(name => 'One',   label => []);
$graph->add_node(name => 'Two',   label => ['Left', 'Right']);
$graph->add_node(name => 'Three', color => 'black', label => ['Good', 'Bad'], shape => 'record');
$graph->add_node(name => 'Four',  label => [
	{
		text => '{Big',
	},
	{
		text => 'Small}',
	},
]);
$graph->add_node(name => 'Five', label => [
	{
		text => '{Yin',
	},
	{
		text => 'Yang}',
	},
], shape => 'record');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "record.$id.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 26 - gen.record.4.svg

Input file # 27 - t/gen.sub.graph.t

Demonstrates a subgraph (with a frame because the subgroup is called cluster_*).

# Annotation: Demonstrates a subgraph (with a frame because the subgroup is called cluster_*).

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => 'sub.graph.pl', rankdir => 'TB'},
	node   => {shape => 'oval'},
);

$graph->add_node(name => 'Carnegie', shape => 'circle');
$graph->add_node(name => 'Murrumbeena', shape => 'doublecircle', color => 'green');
$graph->add_node(name => 'Oakleigh',    color => 'blue');
$graph->add_edge(from => 'Murrumbeena', to    => 'Carnegie', arrowsize => 2);
$graph->add_edge(from => 'Murrumbeena', to    => 'Oakleigh', color => 'brown');

$graph->push_subgraph(
 name  => 'cluster_1',
 graph => {label => 'Child'},
 node  => {color => 'magenta', shape => 'diamond'},
);
$graph->add_node(name => 'Chadstone', shape => 'hexagon');
$graph->add_node(name => 'Waverley', color => 'orange');
$graph->add_edge(from => 'Chadstone', to => 'Waverley');
$graph->pop_subgraph;

$graph->default_node(color => 'cyan');

$graph->add_node(name => 'Malvern');
$graph->add_node(name => 'Prahran', shape => 'trapezium');
$graph->add_edge(from => 'Malvern', to => 'Prahran');
$graph->add_edge(from => 'Malvern', to => 'Murrumbeena');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "sub.graph.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 27 - gen.sub.graph.svg

Input file # 28 - t/gen.sub.graph.frames.t

Demonstrates clusters with and without frames.

# Annotation: Demonstrates clusters with and without frames.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	edge   => {color => 'grey', penwidth => 3},
	global => {directed => 1},
	graph  => {label => 'Demo of 3 subgraphs (2 being clusters), and 1 frame', rankdir => 'TB'},
	node   => {shape => 'oval'},
);

$graph->add_node(name => 'One', color => 'red',   shape => 'circle');
$graph->add_node(name => 'Two', color => 'green', shape => 'doublecircle');
$graph->add_edge(from => 'One', to => 'Two', color => 'maroon');

$graph->push_subgraph(
	graph    => {label => 'Child the First'},
	name     => 'cluster First subgraph',
	node     => {color => 'magenta', shape => 'diamond'},
	subgraph => {pencolor => 'white'}, # Required because name =~ /^cluster/.
);
$graph->add_node(name => 'Three'); # Default color and shape.
$graph->add_node(name => 'Four',  color => 'orange', shape => 'rectangle');
$graph->add_edge(from => 'Three', to => 'Four');
$graph->pop_subgraph;

$graph->push_subgraph(
	graph    => {label => 'Child the Second'},
	name     => 'cluster Second subgraph',
	node     => {color => 'magenta', shape => 'diamond'},
	subgraph => {pencolor => 'purple'}, # Required because name =~ /^cluster/.
);
$graph->add_node(name => 'Five', color => 'blue'); # Default shape.
$graph->add_node(name => 'Six',  color => 'orange', shape => 'rectangle');
$graph->add_edge(from => 'Five', to => 'Six');
$graph->pop_subgraph;

$graph->push_subgraph(
	name     => 'Third subgraph',
	graph    => {label => 'Child the Third'},
	node     => {color => 'magenta', shape => 'diamond'},
);
$graph->add_node(name => 'Seven', color => 'blue',   shape => 'doubleoctagon');
$graph->add_node(name => 'Eight', color => 'orange', shape => 'rectangle');
$graph->add_edge(from => 'Seven', to => 'Eight');
$graph->pop_subgraph;

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "sub.graph.frames.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 28 - gen.sub.graph.frames.svg

Input file # 29 - t/gen.sub.sub.graph.t

Demonstrates a subsubgraph.

# Annotation: Demonstrates a subsubgraph.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => 'sub.sub.graph.pl', rankdir => 'TB'},
	node   => {shape => 'oval'},
);

$graph->add_node(name => 'Carnegie', shape => 'circle');
$graph->add_node(name => 'Murrumbeena', shape => 'doublecircle', color => 'green');
$graph->add_node(name => 'Oakleigh',    color => 'blue');
$graph->add_edge(from => 'Murrumbeena', to    => 'Carnegie', arrowsize => 2);
$graph->add_edge(from => 'Murrumbeena', to    => 'Oakleigh', color => 'brown');

$graph->push_subgraph(
 name  => 'cluster_subgraph_1',
 graph => {label => 'Child'},
 node  => {color => 'magenta', shape => 'diamond'},
);
$graph->add_node(name => 'Chadstone', shape => 'hexagon');
$graph->add_node(name => 'Waverley', color => 'orange');
$graph->add_edge(from => 'Chadstone', to => 'Waverley');

$graph->push_subgraph(
 name  => 'cluster_2',
 graph => {label => 'Grandchild'},
 node  => {color => 'blue3', shape => 'triangle'},
);
$graph->add_node(name => 'Glen Waverley', shape => 'pentagon');
$graph->add_node(name => 'Mount Waverley', color => 'darkslategrey');
$graph->add_edge(from => 'Glen Waverley', to => 'Mount Waverley');
$graph->pop_subgraph;

$graph->pop_subgraph;

$graph->default_node(color => 'cyan');
$graph->add_node(name => 'Malvern');
$graph->add_node(name => 'Prahran', shape => 'trapezium');
$graph->add_edge(from => 'Malvern', to => 'Prahran');
$graph->add_edge(from => 'Malvern', to => 'Murrumbeena');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "sub.sub.graph.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 29 - gen.sub.sub.graph.svg

Input file # 30 - t/gen.trivial.t

Demonstrates a trivial 3-node graph, with colors.

# Annotation: Demonstrates a trivial 3-node graph, with colors.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {rankdir => 'TB'},
	node   => {shape => 'oval'},
);

$graph->default_node(shape     => 'circle', style => 'filled');
$graph->default_edge(arrowsize => 4);

$graph->add_node(name => 'Carnegie', shape => 'circle');
$graph->add_node(name => 'Carnegie', color => 'red');

$graph->default_node(style => 'rounded');

$graph->add_node(name => 'Murrumbeena', shape => 'doublecircle', color => 'green');
$graph->add_node(name => 'Oakleigh',    shape => 'oval',         color => 'blue');
$graph->add_edge(from => 'Murrumbeena', to => 'Carnegie', arrowsize => 2);

$graph->default_edge(arrowsize => 4);

$graph->add_edge(from => 'Murrumbeena', to => 'Oakleigh', color => 'brown');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "trivial.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 30 - gen.trivial.svg

Input file # 31 - t/gen.unnamed.sub.graph.t

Demonstrates named and unnamed subgraphs.

# Annotation: Demonstrates named and unnamed subgraphs.

use strict;
use warnings;
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {label => 'Named and unnamed subgraphs', rankdir => 'TB'},
);

$graph->push_subgraph(
	graph => {label => 'Subgraph One'},
	node  => {color => 'magenta', shape => 'diamond'},
);
$graph->add_node(name => 'Chadstone', shape => 'hexagon');
$graph->add_node(name => 'Waverley', color => 'orange');
$graph->add_edge(from => 'Chadstone', to => 'Waverley');
$graph->pop_subgraph;

$graph->push_subgraph;
$graph->add_node(name => 'Glen Waverley', color => 'blue3', shape => 'pentagon');
$graph->add_node(name => 'Mount Waverley', color => 'darkslategrey', shape => 'rectangle');
$graph->add_edge(from => 'Glen Waverley', to => 'Mount Waverley');
$graph->pop_subgraph;

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "unnamed.sub.graph.$format");
  $graph -> run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 31 - gen.unnamed.sub.graph.svg

Input file # 32 - t/gen.utf8.1.t

Demonstrates utf8 chars in labels.

# Annotation: Demonstrates utf8 chars in labels.

use strict;
use utf8;
use warnings;
use warnings  qw(FATAL utf8);    # Fatalize encoding glitches.
use File::Spec;
use GraphViz2;

my $graph = GraphViz2->new(
	edge   => {color => 'grey'},
	global => {directed => 1},
	graph  => {rankdir => 'TB'},
	node   => {shape => 'oval'},
);

$graph->add_node(name => 'Zero',  label => 'The Orient Express');
$graph->add_node(name => 'One',   label => 'Reichwaldstraße');
$graph->add_node(name => 'Two',   label => 'Böhme');
$graph->add_node(name => 'Three', label => 'ʎ ʏ ʐ ʑ ʒ ʓ ʙ ʚ');
$graph->add_node(name => 'Four',  label => 'Πηληϊάδεω Ἀχιλῆος');
$graph->add_node(name => 'Five',  label => 'ΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔΔ');
$graph->add_edge(from => 'Zero',  to => 'One');
$graph->add_edge(from => 'Zero',  to => 'Three');
$graph->add_edge(from => 'One',   to => 'Two');
$graph->add_edge(from => 'Three', to => 'Four');
$graph->add_edge(from => 'Two',   to => 'Five', label => 'Label has a ☃');
$graph->add_edge(from => 'Four',  to => 'Five', label => 'Label has a ✔');

if (@ARGV) {
  my($format)      = shift || 'svg';
  my($output_file) = shift || File::Spec -> catfile('html', "utf8.1.$format");
  $graph->run(format => $format, output_file => $output_file);
} else {
  # run as a test
  require Test::More;
  require Test::Snapshot;
  Test::Snapshot::is_deeply_snapshot($graph->dot_input, 'dot file');
  Test::More::done_testing();
}

Output file # 32 - gen.utf8.1.svg

Links

Index page for all graph module demos


Environment

Author
Date
2020-10-15
OS
Debian V 8.10
Perl
5.26.1