uni2work.workflows/tools/visualize/gui.pl
2022-10-09 23:57:42 +02:00

224 lines
5.1 KiB
Perl

# SPDX-FileCopyrightText: 2022 Stephan Barth <barths@gate2.tcs.ifi.lmu.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
#!/usr/bin/perl
use strict;
use warnings;
use YAML::XS;
use Data::Dumper;
use Tk;
use Math::Trig;
BEGIN {
my $pwd = $0;
$pwd=~s#/[^/]+$##;
push @INC, $pwd;
};
use Graphy;
use WFparse;
my $fn = shift;
die unless -e $fn;
my $maindata = WFparse::parsefile($fn);
#my $fh = undef;
#open($fh, '<', $fn) or die "Could not open $fn, as: $!";
#my $data = join '', <$fh>;
#close $fh;
#
#my $yaml = Load($data);
#
##print "<<<<<<< ", ref $yaml;
#
#$yaml = {nodes => $yaml}
# unless
# 1 == %$yaml and exists $yaml->{nodes}
# #'HASH' eq ref $yaml
# ;
#
#print Dumper($yaml);
#
#print "Analyze \$yaml\n";
#for my $k(keys %$yaml) {
# print " Key found: $k\n";
#}
#
#my $nodes = $yaml->{nodes};
#
#print "Analyze \$nodes\n";
#for my $k(keys %$nodes) {
# print " Key found: $k\n";
#}
#
#print Dumper($nodes->{antrag});
#
#my $onenode = $nodes->{antrag};
#
#print "Analyze \$onenode\n";
#for my $k(keys %$onenode) {
# print " Key found: $k\n";
#}
#
#my $edges = $onenode->{edges};
#
#print Dumper($edges);
#
#
#for my $nk(sort keys %$nodes) {
# my $ed = $nodes->{$nk}->{edges};
# for my $ek(sort keys %$ed) {
# my $src = ' (thin air)';
# $src = $ed->{$ek}->{source} if $ed->{$ek}->{source};
# print "$src --$ek--> $nk\n";
# }
# #print " Key found: $k\n";
#}
my %xy = (); # xy-extradata, where it is not stated in the yaml
my %nodes = %$maindata;
my %layout = (
width=>800,
height=>800,
horsplit=>0.5,
vertsplit=>0.5,
);
my @nodekeys = sort keys %nodes;
for my $i(0..$#nodekeys) {
my $nk = $nodekeys[$i];
my $phi = ($i/@nodekeys) * 2 * pi;
my $x = 400 + 300*sin $phi;
my $y = 400 + 300*cos $phi;
#$x = $nodes->{$nk}->{x}*800 if $nodes->{$nk}->{x};
#$y = $nodes->{$nk}->{y}*800 if $nodes->{$nk}->{y};
$xy{$nk} = [$x,$y];
}
my $main = MainWindow->new();
my $can = $main->Canvas(-width=>800,-height=>800,-background=>'#000000')->pack(-side=>'left');
my $texte = $main->Frame->pack(-side=>'left');
my $knotentext = $texte->Text->pack;
my $knotenwahl = $texte->Frame->pack(-expand=>1,-fill=>'x');
my $kantentext = $texte->Text->pack;
my $zentrierer = $knotenwahl->Canvas(-width=>80,-height=>80,-background=>'#000044')->pack(-side=>'left');
my $filler = $knotenwahl->Frame->pack(-side=>'left',-expand=>1,-fill=>'x');
#$knotenwahl->Label(-text=>'Foo')->pack(-side=>'left',-expand=>1,-fill=>'x');
my $picker = sub {return undef};
my @hl = ();
$can->Tk::bind('<1>' => [sub {
my (undef, $x, $y) = @_;
my $got = $picker->($x,$y);
if(defined $got) {
push @hl, $got;
shift @hl if @hl > 2;
show();
}
}, Ev('x'), Ev('y')]);
$can->Tk::bind('<3>' => [sub {
my (undef, $x, $y) = @_;
@hl = ();
show();
}, Ev('x'), Ev('y')]);
show();
MainLoop;
sub show {
$can->delete('all');
my %pts = ();
my @trans = ();
for my $nk(sort keys %nodes) {
my $ed = $nodes{$nk}->{edges};
for my $ek(sort keys %$ed) {
my ($xt,$yt) = @{$xy{$nk}};
my $src = ' (thin air)';
my ($xs,$ys) = ($xt,$yt);
if($ed->{$ek}->{source}) {
$src = $ed->{$ek}->{source};
print "$src --$ek--> $nk\n";
($xs,$ys) = @{$xy{$src}};
} else {
$_ = $_-400 for $xs,$ys;
$_ = $_*1.3 for $xs,$ys;
my $dx = $ys*0.3;
my $dy = -$xs*0.3;
$xs += $dx;
$ys += $dy;
$_ = $_+400 for $xs,$ys;
$src = "$nk (thin~ air)";
$pts{$src} = {x=>$xs,y=>$ys,col=>'#8888aa'};
}
#$can->createLine($xs,$ys,$xt,$yt,-fill=>'#ffffff',-width=>3);
push @trans, {from=>$src, to=>$nk, col=>'#ffffff'}
}
#print " Key found: $k\n";
my ($x,$y) = @{$xy{$nk}};
$pts{$nk} = {x=>$x,y=>$y,col=>'#8888aa'};
}
$picker = Graphy::display(
$can,
\%pts,
\@trans,
[],
{circr=>42, linescale=>5}
);
{
my ($x0,$y0,$x1,$y1) = ();
if($hl[0]) {
my $o = $nodes{$hl[0]};
($x0, $y0) = @{$xy{$hl[0]}};
my $r = 46;
$can->createOval($x0-$r,$y0-$r,$x0+$r,$y0+$r,-fill=>undef,-outline=>'#ff00ff',-width=>6);
}
if($hl[1]) {
my $o = $nodes{$hl[1]};
($x1, $y1) = @{$xy{$hl[1]}};
my $r = 50;
$can->createOval($x1-$r,$y1-$r,$x1+$r,$y1+$r,-fill=>undef,-outline=>'#ff00ff',-width=>9);
my $minr = 12;
$can->createOval($x1-$minr,$y1-$minr,$x1+$minr,$y1+$minr,-fill=>'#8800ff',-outline=>'#ffffff');
$can->createLine($x0,$y0,$x1,$y1,-fill=>'#8800ff',-width=>$minr);
}
}
}
sub show_ {
$can->delete('all');
for my $nk(sort keys %nodes) {
my $ed = $nodes{$nk}->{edges};
for my $ek(sort keys %$ed) {
my ($xt,$yt) = @{$xy{$nk}};
my $src = ' (thin air)';
my ($xs,$ys) = ($xt,$yt);
if($ed->{$ek}->{source}) {
$src = $ed->{$ek}->{source};
print "$src --$ek--> $nk\n";
($xs,$ys) = @{$xy{$src}};
} else {
$_ = ($_-400)*1.2+400 for $xs,$ys;
}
$can->createLine($xs,$ys,$xt,$yt,-fill=>'#ffffff',-width=>3);
}
#print " Key found: $k\n";
}
for my $nk(sort keys %nodes) {
my ($x,$y) = @{$xy{$nk}};
$can->createOval($x-7,$y-7,$x+7,$y+7,-fill=>'#ffffff');
$can->createText($x,$y,-fill=>'#8888ff',-text=>$nk);
}
}