Graphviz-DSL
view release on metacpan or search on metacpan
lib/Graphviz/DSL/Graph.pm view on Meta::CPAN
my $dotfile = "${path}.dot";
open my $fh, '>', $dotfile or Carp::croak("Can't open $dotfile: $!");
print {$fh} Encode::encode($encoding, $self->as_string);
close $fh;
if ($type) {
my $dot = File::Which::which('dot');
unless (defined $dot) {
Carp::carp("Cannot generate image. Please install Graphviz(dot command).");
return;
}
my $output = "${path}.${type}";
my $cmd_str = sprintf "%s -T%s %s -o %s", $dot, $type, $dotfile, $output;
my @cmd = split /\s/, $cmd_str;
system(@cmd) == 0 or Carp::croak("Failed command: '@cmd'");
}
}
sub rank {
my ($self, $type, @nodes) = @_;
unless (@nodes) {
Carp::croak("not specified nodes");
}
my @types = qw/same min max source sink/;
unless ( grep { $type eq $_} @types) {
Carp::croak("type must match any of '@types'");
}
push @{$self->{ranks}}, [$type, \@nodes];
}
sub _build_attrs {
my ($attrs, $is_join) = @_;
return '' unless @{$attrs};
unless (defined $is_join) {
$is_join = 1;
}
my @strs;
for my $attr (@{$attrs}) {
my ($k, $v) = @{$attr};
my $str = qq{$k="$v"};
$str =~ s{\n}{\\n}g;
push @strs, $str;
}
if ($is_join) {
my $joined = join q{,}, @strs;
return "[${joined}]";
} else {
return \@strs;
}
}
sub update_attrs {
my ($self, $attr_key, @args) = @_;
OUTER:
while (my ($key, $val) = splice @args, 0, 2) {
for my $old_attr (@{$self->{$attr_key}}) {
my ($old_key, $old_val) = @{$old_attr};
if ($key eq $old_key) {
$old_attr->[1] = $val;
next OUTER;
}
}
push @{$self->{$attr_key}}, [$key, $val];
}
}
my %print_func = (
'Graphviz::DSL::Graph' => sub {
my $graph = shift;
return if $graph->{delayed};
my @lines = split /\n/, $graph->as_string;
my @results;
for my $line (@lines) {
chomp $line;
push @results, " ${line}";
}
return @results;
},
'Graphviz::DSL::Edge' => sub {
my ($edge, $is_directed) = @_;
sprintf " %s%s;", $edge->as_string($is_directed), _build_attrs($edge->attributes);
},
'Graphviz::DSL::Node' => sub {
my $node = shift;
sprintf " %s%s;", $node->as_string, _build_attrs($node->attributes);
},
);
sub as_string {
my $self = shift;
my @result;
my $is_directed = $self->{type} eq 'digraph' ? 1 : 0;
my $indent = ' ';
my $graph_type = $self->{is_subgraph} ? 'subgraph' : $self->{type};
push @result, sprintf "%s \"%s\" {", $graph_type, $self->{id};
if (@{$self->{graph_attrs}}) {
my $graph_attrs_str = join ";\n$indent", @{_build_attrs($self->{graph_attrs}, 0)};
push @result, sprintf "%s%s;", $indent, $graph_attrs_str;
}
if (@{$self->{gnode_attrs}}) {
my $gnode_attr_str = _build_attrs($self->{gnode_attrs});
push @result, sprintf "%snode%s;", $indent, $gnode_attr_str;
}
( run in 1.220 second using v1.01-cache-2.11-cpan-39bf76dae61 )