Graph-Layout-Aesthetic
view release on metacpan or search on metacpan
lib/Graph/Layout/Aesthetic/Force.pm view on Meta::CPAN
package Whatever;
use base qw(Graph::Layout::Aesthetic::Force);
sub name {
return "Whatever";
}
$force = some_new_force_object();
$force->register($name);
$force->register;
$old_private_data = $force->_private_data;
$old_private_data = $force->_private_data($new_private_data);
$old_user_data = $force->user_data;
$old_user_data = $force->user_data($new_user_data);
or
Graph::Layout::Aesthetic::Force::name2force($name);
=head1 DESCRIPTION
Graph::Layout::Aesthetic::Force is a base class for the aesthetic forces
used by the L<Graph::Layout::Aesthetic|Graph::Layout::Aesthetic> package.
Each force represents one aspect the graph should be optimized for, concepts
like "Nodes should be not too close together" or "edges should not be too
long". This works by passing the current configuration to the
L<aesth_gradient|"aesth_gradient"> function in the force module, which then
returns a "force" for each node corresponding to how much it would like to
move that node in that direction to improve the target aesthetic.
The combination of all forces will then determine the direction and size of
the step that's applied to all nodes. The step sizes get restricted by a scalar
that's called the "temperature". Since initial step sizes can be big, they
don't necessarily improve on the target aesthetics since a step can reach far
beyond the minimum for an aesthetic in the given direction (this is intentional
so that a state will be able to escape from a local minimum). But as the
temperature lowers and the steps get smaller, the steps will more and more tend
to optimize the target aesthetic.
The L<Graph::Layout::Aesthetic|Graph::Layout::Aesthetic> package comes with a
number of predefined aesthetics, these being:
=over
=item L<Graph::Layout::Aesthetic::Force::Centripetal|Graph::Layout::Aesthetic::Force::Centripetal>
Repulsion from the centroid of the current configuration, magnitude 1/d
=item L<Graph::Layout::Aesthetic::Force::MinEdgeLength|Graph::Layout::Aesthetic::Force::MinEdgeLength>
Nodes connected to each other by an edge attract each other with force d**2
=item L<Graph::Layout::Aesthetic::Force::NodeRepulsion|Graph::Layout::Aesthetic::Force::NodeRepulsion>
Nodes repel each other with a force 1/d
=item L<Graph::Layout::Aesthetic::Force::NodeEdgeRepulsion|Graph::Layout::Aesthetic::Force::NodeEdgeRepulsion>
Nodes repel from the nearest point on the line through an edge
if that point is between the endpoints of the edge. Magnitude 1/d.
=item L<Graph::Layout::Aesthetic::Force::MinEdgeIntersect|Graph::Layout::Aesthetic::Force::MinEdgeIntersect>
Crossed edge midpoints repel each other with a constant magnitude of 1.
Only works in 2 dimensions.
=item L<Graph::Layout::Aesthetic::Force::MinEdgeIntersect2|Graph::Layout::Aesthetic::Force::MinEdgeIntersect2>
Crossed edge midpoints repel each other with a force d.
Only works in 2 dimensions.
=item L<Graph::Layout::Aesthetic::Force::ParentLeft|Graph::Layout::Aesthetic::Force::ParentLeft>
This is mainly meant for DAGs (Directed Acyclic Graphs). If a node
gets placed to the left of it's parent (position on the first coordinate, the
x-axis) plus 5, it wants to move to the other side with a force d**2.
=item L<Graph::Layout::Aesthetic::Force::MinLevelVariance|Graph::Layout::Aesthetic::Force::MinLevelVariance>
This is again mainly meant for DAGs (Directed Acyclic Graphs). Each node gets
assigned a level (its distance from the leafs). Then it tries to give all nodes
with the same level at the same distance from the left (position on the first
coordinate, the x-axis). The force is d**3 (d is how much the node is to the
left or the right from the average position of all nodes of its own level).
=back
The main role of this module is to function as base class for particular forces
that are written as L<XS|perlxs> extension modules. It has a default DESTROY
method that frees an assumed underlying C structure, so don't use this as a
baseclass for pure perl modules. However, see
L<Graph::Layout::Aesthetic::Force::Perl|Graph::Layout::Aesthetic::Force::Perl>
for how to write forces in perl. On the other hand, if you want to write your
own standalone force packages based on XS code, then you'll need to look at
L<Graph::Layout::Aesthetic::Include|Graph::Layout::Aesthetic::Include> to
get the right definitions of the C level datastructures.
A typical derived class should normally have a module file that loads the
L<XS|perlxs> object and creates one standard instance of the force which it
then L<registers|"register"> with Graph::Layout::Aesthetic::Force.
The L<XS|perlxs> object should have a constructor that encapsulates a
struct aglo_force (see include/aglo.h) with 3 callback function pointers:
=over
=item aesth_setup
Called once when a force is added to a state (see
L<Graph::Layout::Aesthetic::add_force|Graph::Layout::Aesthetic/add_force>).
It should do any necessary preparation for later
L<aesth_gradient|"aesth_gradient"> (e.g. L<Graph::Layout::Aesthetic::Force::MinLevelVariance|Graph::Layout::Aesthetic::Force::MinLevelVariance> uses it to
calculate the levels of each node in a graph so they don't have to be
recalculated every time). It should return a pointer that will be passed to
every L<aesth_gradient|"aesth_gradient"> call and later to
L<aesth_cleanup|"aesth_cleanup"> for any needed cleanup. This for example can
be used to set up scratch memory that will be needed during calculations.
=item aesth_cleanup
( run in 2.389 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )