Both types of graph elements, i.e., nodes and edges, provide at least one label, which can be used to show a descriptive text that marks the respective graph element. The label's purpose is served best when it is both readable and also near its element, where readability most importantly results from the label being placed so that it does not overlap with other graph elements.
The yFiles library offers advanced labeling algorithms that automatically generate label arrangements that, whenever feasible, completely eliminate all overlaps, or minimize the number thereof otherwise. Labeling algorithms can be applied in two different scenarios: general labeling and integrated labeling.
General labeling is independent of any layout algorithms and can be run "stand-alone" and at any time. It generates label placements without altering node positions, node sizes, or edge paths. Integrated labeling, in contrast, is directly provided by certain major layout algorithms as an integrated part of the layout calculation. This approach allows, e.g., to place labels before any edge path is generated, or change the position of nodes to make room for a big label.
Integrated labeling's advantage is that, by design, it prevents label overlaps completely, in other words, it can guarantee the absence of overlaps. General labeling cannot give such a guarantee, since it has to deal with a fixed environment. However, the graph's dimensions will remain constant or grow only minimally with general labeling.
In essence, labels are nothing more than boxes with given width and height that
should be placed in such a manner that conflicts with other graph elements or
labels are avoided.
Interface LabelLayout
defines the basis
of all label implementations accordingly, see
Figure 5.67, “Basic interface for label implementations”.
With the means provided by the yFiles Layout distribution, label boxes are
set up explicitly using NodeLabelLayout and EdgeLabelLayout implementations.
Example 5.28, “Creating label boxes” demonstrates the usage of class
EdgeLabelLayoutImpl
to define label
boxes for an edge.
Users of the yFiles Viewer distribution use the functionality provided by class
YLabel
and its descendants to set up node
and edge labels.
Example 5.28. Creating label boxes
// Set up two boxes that represent edge labels for an edge 'e'. // Usually, the size of a label will be determined by calculating the bounding // box of its text, which would also account for the text's font (size, etc.). EdgeLabelLayoutImpl ell1 = new EdgeLabelLayoutImpl(); ell1.setBox(new YRectangle(0, 0, 80, 20)); EdgeLabelLayoutImpl ell2 = new EdgeLabelLayoutImpl(); ell2.setBox(new YRectangle(0, 0, 40, 20)); // Associate the label boxes with the edge. EdgeLabelLayout[] ells = new EdgeLabelLayout[]{ell1, ell2}; graph.setLabelLayout(e, ells);
Both node label and edge label have associated a so-called "label model," that defines a set of valid positions where the label can be placed relative to its respective graph element. In the context of automatic label placement, all valid positions are at the same time "candidates" among which a labeling algorithm can choose the best match to ultimately place the label.
In terms of minimization of overlaps, more candidates mean better prospects for the outcome of a general labeling algorithm.
Table 5.36, “Predefined node label models” lists the available node label models, their class hierarchy is presented in Figure 5.68, “Predefined node label models”.
Table 5.36. Predefined node label models
| Class Name | Description |
|---|---|
| DiscreteNodeLabelModel |
Defines a maximum of eight positions outside the node's bounding box, and also a maximum of nine positions inside. |
| FreeNodeLabelModel |
Supports label placement at any given offset relative to the node's upper
left corner.
In effect, "free" defines a single fixed position for a label.
Static inner class
FreeNodeLabelModel.ModelParameter |
For general labeling, DiscreteNodeLabelModel with its up to nine valid positions (inside a node's area) is a much better choice for a node label model than FreeNodeLabelModel. However, FreeNodeLabelModel allows for an arbitrary label position, while the positions of DiscreteNodeLabelModel are all predefined.
Table 5.37, “Predefined edge label models” lists the available edge label models, their class hierarchy is presented in Figure 5.69, “Predefined edge label models”.
Table 5.37. Predefined edge label models
| Class Name | Description |
|---|---|
| DiscreteEdgeLabelModel |
Defines a maximum of six positions along the edge's path, and also a maximum of three positions directly on the edge. |
| FreeEdgeLabelModel |
Supports label placement at any given offset relative to the edge's
intersection point with its source node.
In effect, "free" defines a single fixed position for a label.
Static inner class
FreeEdgeLabelModel.ModelParameter |
| SliderEdgeLabelModel |
Supports continuous label positions along the edge's path as well as directly
on it.
Static inner class
SliderEdgeLabelModel.ModelParameter |
For general labeling, SliderEdgeLabelModel with its dynamic positions is the best choice for an edge label model, followed by DiscreteEdgeLabelModel. Both offer more variety than FreeEdgeLabelModel. However, FreeEdgeLabelModel allows for an arbitrary label position, while the positions of SliderEdgeLabelModel and DiscreteEdgeLabelModel are all directly along or on the edge path, respectively.
Integrated labeling, in contrast, favors FreeEdgeLabelModel, followed by SliderEdgeLabelModel, since it does not work with the candidates initially. Instead, it first computes an optimal location for the label, and then tries to find the best matching label position for that location in the given label model.
Associating an edge label with one of the predefined edge label models is shown in Example 5.29, “Setting edge label models”.
Example 5.29. Setting edge label models
// Set center slider edge label model, where the label is placed directly on // the edge's path. ell1.setEdgeLabelModel( new SliderEdgeLabelModel(SliderEdgeLabelModel.CENTER_SLIDER)); // Set side slider edge label model, where the label is placed along the edge's // path. ell2.setEdgeLabelModel( new SliderEdgeLabelModel(SliderEdgeLabelModel.SIDE_SLIDER));
A general labeling algorithm computes label positions for the labels from a
given graph so that they, ideally, do not overlap with each other or with graph
elements.
It does so without altering nodes or edges in any way.
As an option, the set of labels can be restricted to node labels only or to
edge labels only.
Figure 5.70, “Class hierarchy for labeling algorithms” shows the class hierarchy of the general
labeling algorithms that are provided in package
y.layout.labeling
.
The labeling algorithm uses the model that is associated with a label to determine the available candidate positions. From the set of candidates it then chooses one that best matches the calculated position. The label model's model parameter is then used to encode this position.
The outcome of a labeling algorithm is a single model parameter that directly derives from its respective label model. The model parameter expresses the calculated label position within a given model, and is the only means to to get an actual location for the label.
Example 5.30, “Getting a label's position from its model parameter” shows how to turn the information from a model parameter into a proper location for an actual label.
Example 5.30. Getting a label's position from its model parameter
/* * Returns the calculated location of the edge label. * Note that the labeling machinery returns the edge label's position as a * parameter of the model that belongs to the label. This model parameter can * be used to retrieve the actual location of the label as shown in this * method. */ YPoint getEdgeLabelLocation(LayoutGraph graph, Edge e, EdgeLabelLayout ell) { YPoint ellp = ell.getLabelModel().getLabelPlacement( ell.getBox(), graph.getEdgeLayout(e), graph.getNodeLayout(e.source()), graph.getNodeLayout(e.target()), ell.getModelParameter()); return ellp; }
The base class for all major layout algorithms, class
CanonicMultiStageLayouter
, allows to
conveniently enable/disable general labeling for each layout run.
The labeling algorithm is then invoked after the actual layout algorithm has
finished.
Additionally, the labeling algorithm itself can also be set.
API Excerpt 5.30, “Labeling-related methods from class CanonicMultiStageLayouter” lists the methods provided by class
CanonicMultiStageLayouter that are related to labeling.
API Excerpt 5.30. Labeling-related methods from class CanonicMultiStageLayouter
// Getter/setter for enabling/disabling general as well as integrated labeling. boolean isLabelLayouterEnabled() void setLabelLayouterEnabled(boolean enabled) // Getter/setter for the actual labeling algorithm to be used. LayoutStage getLabelLayouter() void setLabelLayouter(LayoutStage labeler)
Integrated labeling denotes automatic edge label placement as an integrated part of a layout algorithm. All edge labels of a graph are arranged in such a manner that there are no overlaps of edge labels with each other or with graph elements.
Table 5.38, “Layout support for integrated labeling” lists the major layout algorithms that provide support for integrated labeling.
Table 5.38. Layout support for integrated labeling
| Layout Style | Classname | Note |
|---|---|---|
| Hierarchical | HierarchicLayouter |
With class IncrementalHierarchicLayouter, integrated labeling can conveniently be enabled using appropriate configuration methods. See the descriptions of classic hierarchical layout and incremental hierarchical layout for more information. |
| Orthogonal | OrthogonalLayouter |
See the descriptions of orthogonal layout and directed orthogonal layout for more information. |
| Tree | TreeLayouter |
Integrated labeling can conveniently be enabled using appropriate configuration methods. See the descriptions of directed tree layout and generic tree layout for more information. |
Integrated labeling relies on the services of class
LabelLayoutTranslator
which converts
label layout information so that it is understood by a layout algorithm.
Example 5.31, “Using class LabelLayoutTranslator” shows how to configure integrated
labeling in the absence of an appropriate configuration method.
Layout algorithms that provide such a configuration method automatically ensure
proper use of LabelLayoutTranslator.
Example 5.31. Using class LabelLayoutTranslator
void useIntegratedLabeling(Layouter layouter) { // Use integrated labeling support, and let class LabelLayoutTranslator do // the conversion of information held by an edge label's EdgeLabelLayout // object to data provider-based information that is understood by the // algorithm. layouter.setLabelLayouter(new LabelLayoutTranslator()); layouter.setLabelLayouterEnabled(true); }
The tutorial demo application
LayoutWithoutAView.java shows the setup for
running a labeling algorithm without the presence of the yFiles library package
y.view
.
LabelingDemo.java shows the
setup with classes NodeLabel
and
EdgeLabel
available.
|
Copyright ©2004-2008, yWorks GmbH. All rights reserved. |