Graph-Layderer

 view release on metacpan or  search on metacpan

lib/Graph/Layouter/Spring.pm  view on Meta::CPAN

weight the edges have, stronger are they in pulling nodes near each other.

So to recapitulate, we have I<repulsive force> pushing nodes from each other
and I<attractive force> pushing connected nodes near each other. We then just
apply the repulsive force between each two nodes and the attractive force
between each two connected nodes; each node will have a resulting movement
force, which we will apply to the node's position (initially randomzero-zero)
after the forces calculation is finished.

However, we need to let this repeat for several times in order for the
positions to stabilize. In fact, a lot of iterations is needed; higher the
better, but also higher the slower, you can very easily get to tens of seconds
here so beware. Currently, the number of iterations is hardcoded to 500, but
this is expected to get configurable soon.

=cut

# TODO : _This_ should be all adjustable!

my $iterations = 100; # undef for no iterations limit
my $max_wait = 10; # (in seconds) undef for no time limit
my $max_repulsive_force_distance = 6;
my $k = 2;
my $c = 0.01;
my $max_vertex_movement = 0.5;

sub layout {
	my $graph = shift;

	Graph::Layouter::_layout_prepare($graph);

	# Cache
	my @vertices = $graph->vertices;

	# Bound execution based on time
	my $end;
	$end = time + $max_wait if defined $max_wait;

	unless (defined $end or defined $iterations) {
		croak "You did not bound the layouting loop by either time or iterations count!";
	}

	for (my $i = 0;
	     (defined $iterations ? $i < $iterations : 1)
	     	and (defined $end ? time <= $end : 1);
	     $i++) {
		_layout_iteration($graph, \@vertices);
	}

	Graph::Layouter::_layout_calc_bounds($graph);
}


sub _layout_repulsive($$$) {



( run in 1.956 second using v1.01-cache-2.11-cpan-96521ef73a4 )