Minimizing Label Overlaps

Questions & Answers

Summary

yFiles makes available advanced optimization algorithms that help minimizing overlaps of labels with other graph elements.
For a better user experience, please go to the integrated documentation viewer to read this article.

Description

Minimizing overlaps for labels can be easily achieved using the automatic labeling algorithms present in package y.layout.labeling, namely GreedyMISLabeling and SALabeling.
These labeling algorithms use so-called "label models" to determine possible positions for labels in an existing layout.

Automatic label placement using a labeling algorithm means placing the labels only. All other graph elements are not altered.

Labeling Algorithms and Label Models

Labels have associated a label model in order to define 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 generic labeling algorithm.

For generic node labeling, label model FreeNodeLabelModel, which defines a large number of nearly continuous label positions around a node, is a much better choice for a node label model than DiscreteNodeLabelModel, which defines a set of fixed positions around and inside a node.

Since yFiles for Java 2.9 new label models SmartNodeLabelModel and SmartEdgeLabelModel enable free label placement of node labels and edge labels. The label models provide smart dynamic behavior including support for automatic label rotation corresponding to the direction of an edge label's associated edge segment and fixed as well as proportional node label alignment with node borders.

More information on the available node label models can be found in the yFiles Developer's Guide.

A label model for a node label is specified as presented in the following sample code.

// 'node' is a node from a Graph2D.

// Setting FreeNodeLabelModel as the label model for each node label.
NodeRealizer nr = graph.getRealizer(node);
for (int i = 0; i < nr.labelCount(); i++) {
  NodeLabel nl = nr.getLabel(i);
  nl.setModel(NodeLabel.FREE);
}

For generic edge labeling, label model FreeEdgeLabelModel, which defines a large number of nearly continuous label positions along the edge's path, in some distance to the edge's path, and also directly on it, is the best choice for an edge label model, followed by SliderEdgeLabelModel and then DiscreteEdgeLabelModel.
More information on the available edge label models can be found in the yFiles Developer's Guide.

Similar to the setup of node label models, a label model for an edge label can be specified as shwon in the following sample code.

// 'edge' is an edge from a Graph2D.

// Setting FreeEdgeLabelModel as the label model for each edge label.
EdgeRealizer er = graph.getRealizer(edge);
for (int i = 0; i < er.labelCount(); i++) {
  EdgeLabel el = er.getLabel(i);
  el.setModel(EdgeLabel.FREE);
}

The setup of a labeling algorithm is shown in the following sample code. In order to have only node labels processed, for example, edge label placement is explicitly disabled. (By default, both node labels and edge labels will be placed.)
The optional post-processing step, which tries to further improve on the label positions, is also enabled. Note that this option increases the run-time.

Additionally, an optimization strategy is chosen that primarily reduces overlaps between nodes and labels. Other optimization strategies that put more emphasis on reducing overlaps between edges and labels, for example, are also available. Note that this option increases the run-time.

public AbstractLabelingAlgorithm getConfiguredLabelingAlgorithm() {
  // SALabeling is one of the labeling algorithms from package y.layout.labeling.
  MISLabelingAlgorithm result = new SALabeling();

  // Calling setters available with abstract class AbstractLabelingAlgorithm.
  result.setPlaceEdgeLabels(false); // Comment out for edge label placement.
  //result.setPlaceNodeLabels(false); // Uncomment for edge label placement.
  result.setApplyPostprocessing(true);

  // Calling setters from class MISLabelingAlgorithm.
  result.setOptimizationStrategy(MISLabelingAlgorithm.OPTIMIZATION_NODE_OVERLAP);
  return result;
}

With the label models and the labeling algorithm properly set up, the labeling algorithm can be run stand-alone using the following line of code.

// 'graph' is an implementation of interface y.layout.GraphLayout.

new BufferedLayouter(getConfiguredLabelingAlgorithm()).doLayout(graph);

In conjunction with one of the yFiles major layout algorithms, the labeling algorithm can be invoked as part of the greater layout process as seen in the following sample code.
What the sample code does:

  • Sets an optional labeling algorithm.
  • Enables the labeling stage optionally available with CanonicMultiStageLayouter, which is invoked subsequent to the actual layouter.
  • Runs the layouter in buffered mode.
// 'layouter' is of type y.layout.CanonicMultiStageLayouter.

layouter.setLabelLayouter(getConfiguredLabelingAlgorithm());
layouter.setLabelLayouterEnabled(true);

// Run the layout in buffered mode. The labeling algorithm will be invoked as part 
// of the greater layout process after the layouter itself has processed the graph.
new BufferedLayouter(layouter).doLayout(graph);

Categories this article belongs to:
yFiles for Java > yFiles Layout > Automatic Graph Layout > Automatic Label Placement
Applies to:
yFiles for Java 2: 2.6, 2.7, 2.8, 2.9, 2.10, 2.11, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.18
Keywords:
label - model - FreeNodeLabelModel - FreeEdgeLabelModel - CanonicMultiStageLayouter - free - node - edge - labeling - generic - optimization - minimize - overlap