|
||||||||||
PREV NEXT | FRAMES NO FRAMES |
See:
Description
Packages | |
suvi | Classes that have responsibilities over the entire Suvi-library. |
suvi.alg | Implementation of the overall layout algorithm chassis. |
suvi.alg.contracts | Design-by-Contract [Meyer1997] decorators [Gamma1995] for the algorithm interfaces. |
suvi.alg.interfaces | Interfaces between the phases of the algorithm and the overall algorithm chassis. |
suvi.alg.policies | Various implementations of the policies that the layout algorithm chassis uses. |
suvi.alg.util | Utilities for graph layout algorithm implementation. |
suvi.api.adt.layout | Interfaces and classes related to the representation of layout information. |
suvi.api.alg | Interface to the layout algorithm. |
suvi.api.alg.attr | Layout attribute interfaces. |
suvi.api.geom | Interfaces for accessing layouts based on geometric properties. |
suvi.api.render | Framework for rendering graphs. |
suvi.parse | Parser for attributed graphs. |
suvi.testapp | Testing application. |
suvi.util.geom | Utilities for manipulating geometric objects. |
The Suvi-library implements multiple graph layout algorithms and serves as a framework for implementing graph layout algorithms.
In order to get a concrete contact point into the library, let's start with a simple example that calculates a layout for a very simple graph.
We first need a simple graph. The following code simply uses one of
the predefined graphs from the TestGraphConstants
-interface. The
predefined graphs in that interface are only intended for testing
purposes. In general, users simply implement the Graph
-adapter interface and use their own
existing graph representations.
Graph
graph =TestGraphConstants.CLOTHING_GRAPH
;
Then we need a graph layout algorithm. The following code uses the
GraphLayoutAlgGen
-class to
generate a graph layout algorithm for us.
GraphLayoutAlg
layoutAlg =GraphLayoutAlgGen.alg
(GraphLayoutAlgGenConstants.LAQ_BEST_VISUAL_QUALITY
, 0);
Now we have almost everything we need. We also need to specify layout attributes, or parameters, for the layout algorithm. In this example, we don't have any special attributes that we would like the layout algorithm to consider, so we'll just create an empty attribute map.
GraphLayoutAttrMap
attrMap = newGraphLayoutAttrMap
();
We are now ready to ask the algorithm to compute a layout for our graph.
finalGraphLayout
layout = layoutAlg.layout
(graph, attrMap);
The next logical step would be to render the graph in some way. The following pseudo code example shows one possible template for rendering a graph according to a computed layout.
newNodesAndEdgesIterTemplate
() { protected voiddoNode
(Object node) { drawNode(node, layout.nodeBox
(node)); } protected voiddoEdge
(Object edge) { drawEdge(edge, layout.edgeBSpline
(edge)); } }.iter
(layout.graph
());
You should now have a basic idea about what this library is all about.
This documentation is aimed at both users of the library and library maintainers. Different parts of the documentation are relevant to users and maintainers.
The documentation that is most relevant to users is in:
GraphLayoutAlgGen
The API specifies the interface, inputs and outputs, between a layout algorithm and the user. In order to understand how to use the library, you should read through most of the API documentation.
As a user, you are probably not interested in how the algorithm implementation is divided into components. The algorithm generator shields users from the implementation details of graph layout algorithms. To use a layout algorithm, you can use the algorithm generator to create a layout algorithm for you.
Users should also read the following overview intended for library maintainers.
Almost all of the documentation is naturally relevant to library
maintainers. A good starting place to learn about the design of the
implementation of graph layout algorithms is the graph layout
algorithm chassis GraphLayoutAlgChassis
.
Maintenance includes correcting defects in the existing code and adding new functionality. According to statistical evidence collected from many projects, most development work labelled as "maintenance" is actually about adding new functionality or refactoring of existing functionality, which isn't that different from initial design.
The Suvi-library uses many utility classes in the implementation of graph algorithms. If you intend to maintain the library, you probably want to read through the utility package and class documentation to get a sense of what is already implemented. You don't want to waste time reimplementing general algorithms that are already implemented.
While the documentation contains some examples, it may still be
difficult to get a sense of how some general utility class or method
or some other component is actually used. Good places to look for
further examples are the various unit test classes. Reading through
the test code (not the test documentation) can be a very effective
way to gain an understanding of the component being tested. Links to
all the unit test classes can be found from the class CompleteTestSuiteRunnerConstants
.
The Suvi-library has been divided into many packages guided by the design principles described in [Martin2002]. Unfortunately there is no one-line summary that would capture the essense of the packaging principles. In particular, simplistic minimization of dependencies is not a driving design force. Instead, dependencies are managed so that harmful dependencies are avoided. Not all dependencies are harmful. It is strongly recommended that you read and seek to understand the packaging principles described in [Martin2002] before changing the package structure.
In case you need to develop a new class and you need to decide the package into which you place the class, you should read through the package descriptions to understand the intention behind each package. While choosing the package, it should help to consider the following questions.
If your new class does not fit any of the above categories, you should think twice where you put your new class. You should also ask whether the role, or responsibility, of the class is actually well defined. A class should only have a single well defined responsibility.
The classes and methods in the Suvi-library are named fairly systematically using a relatively small number of naming patterns.
The naming conventions used in the Suvi-library are different from the Java naming conventions used by Sun. In Suvi, in general, method names start with a verb if and only if the method is decisively imperative and the client calls the method explicitly for the side-effects of the method. On the other hand, methods that are functional, and do not have externally observable side-effects do not, in general, start with a verb. We feel that these conventions yield short and logical names that communicate the intentions of the methods well.
Abstract*
AbstractGraphLayoutAttrBuilder
*Alg
GraphLayoutAlg
*Attr
EdgeLabelAttr
Basic*
BasicGraphLayoutAlgProgressPolicy
*Builder
AbstractGraphLayoutAttrBuilder
*Constants
FlowTrendConstants
*Contract
GraphLayoutAlgContract
*Decorator
NodeOrderingPolicyWithTransposeDecorator
*Gen
GraphLayoutAlgGen
*Map
GraphLayoutAttrMap
*Policy
ComponentLayoutPolicy
Simplistic*
SimplisticNodeRankingPolicy
*s (plural)
EdgeRoutingPolicies
*Test
GraphLayoutAlgGenTest
The following is a complete alphabetical listing of references made in the documentation. Please note that this documentation is not intended as an introduction to software design. The references point out to readily available software design, algorithm and programming texts whose material is general enough that it is not worth rephrasing here.
|
||||||||||
PREV NEXT | FRAMES NO FRAMES |