The algorithm uses simulated annealing.
This is a general, randomized optimization technique that simulates
a thermodynamic particle system. Each label is moved to a new
random position within the limits given by its label descriptor.
The quality of the new position is calculated and compared to the
quality of the old position. If the quality has not improved, the
label is moved back to the old position. The amount of movement is
controlled by a conceptual temperature: when the system is hot, the
labels can move long distances, producing potentially large global
quality improvements. When the system cools down, the move
distances become smaller and hence focus on local fine-tuning of
the position.
Each label has its own label descriptor. The label descriptor
describes the path on which the label can move. If a label must
be placed at a city in a geographic map, then its label
descriptor makes sure that the label is always placed close to
the graphics that represent the city. If a label must be placed
at a specific point, the
IlvAnnealingPointLabelDescriptor
can be used and describes an approximately elliptical path around
the point. If a label must be placed at a polyline, the
IlvAnnealingPolylineLabelDescriptor
can be used and describes a boundary path at both sides of the
polyline.
Annealing Label Layout algorithm Example
In CSS
The sample below shows how to use CSS syntax to declare labels
at nodes of type IlvGeneralNode. The specification can be
loaded as a style file into an application that uses the
IlvDiagrammer
class (see Graph layout in Rogue Wave JViews Diagrammer).
SDM { LabelLayout: "true"; } LabelLayout { enabled: "true"; labelOffset: “5”; obstacleOffset: “10”; } node { class: "ilog.views.sdm.graphic.IlvGeneralNode"; label: "@name"; labelPosition: "Left"; labelSpacing: "2.0"; } node:labelLayout { maxDistFromPath: "5"; }
In Java™
The following code sample uses the
IlvAnnealingLabelLayout
class. This code sample shows how to perform an Annealing
Label Layout on a manager directly.:
... import ilog.views.*; import ilog.views.graphlayout.labellayout.*; import ilog.views.graphlayout.labellayout.annealing.*; ... IlvManager manager = new IlvManager(); IlvManagerView view = new IlvManagerView(manager); ... /* Fill in here code that fills the manager with labels and obstacles */ IlvAnnealingLabelLayout layout = new IlvAnnealingLabelLayout(); layout.attach(manager); /* Assume: label1 should be placed at the right side of rectangular node1 */ layout.setLabelDescriptor( label1, new IlvAnnealingPointLabelDescriptor( label1, node1, IlvAnnealingPointLabelDescriptor.RECTANGULAR, IlvDirection.Right)); ... /* Fill in here code that sets descriptors for all other labels */ IlvLabelLayoutReport layoutReport = layout.performLayout(); if (layoutReport.getCode() == IlvLabelLayoutReport.LAYOUT_DONE) System.out.println("Layout done."); else System.out.println("Layout not done, code = " + layoutReport.getCode());