public class IlvGraphLayoutRenderer extends IlvFilterSDMRenderer
IlvGraphLayoutRenderer
is a
filtering renderer that applies a graph layout algorithm
to the links and/or the nodes of the graph.
You must specify the layout algorithm that you want to use by adding a declaration in the style sheet:
SDM { GraphLayout : "Hierarchical"; }
You can use any graph layout algorithm of the Perforce JViews library.
You can specify an abbreviated graph layout name (for example
"Hierarchical"
), or a fully qualified class name
(for example, "ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout"
).
The properties of the IlvGraphLayout
instance can be customized
in the style sheet. For example:
SDM { GraphLayout : "Hierarchical"; } GraphLayout { globalLinkStyle : "ORTHOGONAL_STYLE"; flowDirection : "Bottom"; }
Perforce JViews layout algorithms (that is, subclasses of
IlvGraphLayout
) provide many parameters
that control how a specific layout will be applied to a particular node
or link. Starting with Perforce JViews 5.5, the graph layout renderer lets you
set all these per-object parameters from the style sheet as in the following
examples:
node.tag1 { class : "..."; ... Fixed : "true"; } link.tag2 { class : "..."; ... ToPortSide : "NORTH"; FromPortSide : "SOUTH"; }
The first rule will cause the method
ilog.views.graphlayout.IlvGraphLayout#setFixed
to be called for all the nodes that match the rule.
The second rule will cause the method
ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout#setToPortSide
to be called for all the links that match the rule.
The general mechanism is the following. A parameter property is created for each method
of the IlvGraphLayout
subclass that matches the following criteria:
"set"
.
Object
(this first
argument is assumed to be a graphic object).
The name of the parameter property is the name of the method, without the
"set"
prefix. The initial capital letter is preserved; this
is consistent with the naming of SDM rendering properties, and avoids
ambiguities with the Bean properties of graphic objects.
The right-hand-side value of the CSS declaration contains the parameters of the method, not including the first argument (the graphic object). If the method expects more than two arguments, the declaration must be a comma-separated list. For example, the following declaration:
node.tag1 { class : "..."; ... NumberOfPorts : "EAST,5"; }
will cause the method
ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout#setNumberOfPorts
to be called as follows: layout.setNumberOfPorts(graphic, EAST, 5)
.
The values in the CSS declaration will be converted automatically to the
type expected by the corresponding method. For example, "EAST"
will be converted to the value of the property
ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout#EAST
.
You can also use a fully qualified property name, for example
"ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout.EAST"
.
It is also possible to call the same method several times as follows:
node.tag1 { NumberOfPorts : "WEST,3;EAST,5"; }This will call
layout.setNumberOfPorts(graphic, WEST, 3)
and
layout.setNumberOfPorts(graphic, EAST, 5)
. Note that the
parameters of the different calls are separated by semi-colons.
The default introspection mechanism for setting per-object parameters can be
overridden if needed. You can provide an explicit piece of Java code to set
a parameter, using the method #addParameterSetter
and the class
ParameterSetter
.
In addition, the following two properties are handled directly by the renderer:
LayoutIgnored
- If this property is set to true
,
the object will be completely ignored by the
graph model (using an IlvLayoutGraphicFilter
).
LayoutGroup
- This property is used to apply the layout
algorithm successively to different groups of objects.
For each different value of the property, the layout algorithm
is applied only to the objects whose LayoutGroup
property is set to the same value.
If the layout algorithm is an IlvHierarchicalLayout
,
the property MarkedForIncremental
can be used. When this property is set to
true
for an object, the method
ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout#markForIncremental
is called
for this object, which means that the position of the object will be recomputed during the
next incremental layout. This property has an effect only if the incrementalMode
of the layout itself was set to true
. For example:
GraphLayout { incrementalMode: "true"; } node:selected { MarkedForIncremental : "true"; }
If the layout algorithm is an IlvCircularLayout
,
you can add a node to several clusters by setting the ClusterId
property
several times:
node[name="foo"] { ClusterId : "cluster1;cluster2;cluster3"; }
You can optionally specify an index inside each cluster:
ClusterId : "cluster1,5;cluster2,1;cluster3,4";
Note: Starting with JViews 6.5, if you are not using any node or link parameters,
you can disable this mechanism using
setUsePerObjectParameters(false)
.
This will remove the overhead of testing the parameters, which can speed up
the SDM rendering process significantly.
The property GraphLayout
can be set on a subgraph node.
This lets you use a different layout algorithm for each subgraph.
For example, the following rule says that subgraph nodes of tag
group
must be laid out using an
IlvGridLayout
algorithm:
node.group { GraphLayout : "Grid"; }You can also use an
"@#"
construct, which lets you customize
the parameters of the subgraph's layout:
node.group { GraphLayout : "@#grid"; } Subobject#grid { class : "ilog.views.graphlayout.grid.IlvGridLayout"; layoutMode : "TILE_TO_ROWS"; }
The following rendering properties were used in Perforce JViews 5.0 and previous versions. They are now superseded by the new method introspection mechanism, but can still be used for compatibility:
LayoutFixed
- Equivalent to Fixed
, calls ilog.views.graphlayout.IlvGraphLayout#setFixed
.
LayoutCluster
- Equivalent to ClusterId
, calls ilog.views.graphlayout.circular.IlvCircularLayout#setClusterId
.
LayoutStarCenter
- Equivalent to StarCenter
, calls ilog.views.graphlayout.circular.IlvCircularLayout#setStarCenter
.
If an IlvGraphLayoutRenderer
and an IlvLinkLayoutRenderer
are used at the same time, you may sometimes encounter conflicts between
node or link properties that have the same name in the two layout algorithms.
A common example of this is the linkStyle
property:
SDM { GraphLayout : "Hierarchical"; LinkLayout : "true"; } link { linkStyle : "POLYLINE_STYLE"; }With these rules, since both
IlvHierarchicalLayout
and
IlvLinkLayout
classes define a setLinkStyle
method, the declaration
will call the method for the two layout objects. Unfortunately, the
value POLYLINE_STYLE
is valid only for the hierarchical
layout, not for the link layout, so an exception will be thrown.
To solve this problem, you have to specify that the declaration must
be applied only to the hierarchical layout. This is done using the
pseudoclass graphLayoutRenderer
:
link:graphLayoutRenderer { linkStyle : "POLYLINE_STYLE"; }Similarly, you could use the pseudo-class
linkLayoutRenderer
to specify that a declaration applies only to the link layout object.
Furthermore, you can specify rules for nodes and links that are only applied for a given layout style, by using the layout name as pseudo-class:
link:graphLayoutRenderer:hierarchical { linkStyle : "POLYLINE_STYLE"; }
If the graph layout algorithm is an instance of
IlvHierarchicalLayout
,
you can define constraints
(see IlvHierarchicalConstraint
)
between the nodes of the graph by setting special properties in the
style sheet.
The following rule says that all participant
nodes should
be placed on the "east" side of the hierarchy (that is, on the right
for a top-bottom layout):
node.participant { ExtremityConstraint : "EAST"; }
The following rule says that the source node and the destination node
of a link of tag application_link
should be placed at the
same level in the hierarchy:
link.application_link { GroupSpreadConstraint : "true"; }In addition, you could use the
SideBySideConstraint
property
to say that the two nodes should be kept "side by side," that is,
without any node between them:
node.application_link { GroupSpreadConstraint : "true"; SideBySideConstraint : "true"; }
The following rule separates the graph into two "swimlanes," one
the activity
nodes and one for the participant
nodes:
node.activity { SwimLaneConstraint : "Activities"; } node.participant { SwimLaneConstraint : "Participants"; }
The following rule says that all selected nodes should be placed at a higher level in the hierarchy than unselected nodes:
node:selected { HigherRelativeLevelConstraint : "selection"; } node { LowerRelativeLevelConstraint : "selection"; }Note that the "higher" and "lower" groups are associated by setting the two properties to the same value. The value is arbitrary. You can use different values to define several "relative level" constraints.
The following rule says that all selected nodes should be placed at a higher position in each level than unselected nodes:
node:selected { HigherRelativePositionConstraint : "selection"; } node { LowerRelativePositionConstraint : "selection"; }
The next sections explain the mechanism in more detail, but the examples should generally be sufficient.
IlvGroupSpreadConstraint
can be used to keep a group of nodes at the same level in the hierarchy.
Node groups are built according to the values of the constraint properties. Two nodes belong to the same node group if the values of a constraint property for these two nodes are equal. Here is an example:
node.activity { GroupSpreadConstraint : "@participant_id"; } node.participant { GroupSpreadConstraint : "@__ID"; }The
activity
nodes are assumed to have a property participant_id
that holds the ID of the participant assigned to the activity. So, the value
of the GroupSpreadConstraint
property in both rules is the same
(the ID of the participant), and thus the two nodes form a node group.
Note that node groups are not limited to two nodes; if the GroupSpreadConstraint
of a third node had the same value, it would have been included in the node group as well.
When two nodes are connected by a link, you can use a simpler syntax to define
a node group containing these two nodes. Assuming the activity and the participant
were connected by a link of tag participant_link
, you could
have written:
participant_link { GroupSpreadConstraint : "true"; }This would create a constraint between the two extremities of the link.
GroupSpread
constraint. These additional parameters can be specified
after the node group identifier, separated by commas. For example:
participant_link { GroupSpreadConstraint : "true,1"; // spread size = 1 }
IlvHierarchicalConstraint
.
ExtremityConstraint
: Defines one or more
IlvExtremityConstraint
instances.
The value of the property is the side where the node should be placed;
it must be one of "NORTH"
, "SOUTH"
, "EAST"
, "WEST"
.
Note that this constraint does not act on node groups. Instead, a new constraint
is created for each node that has the property.
GroupSpreadConstraint
: Defines one or more
IlvGroupSpreadConstraint
instances.
All the nodes that have the same value for this property will be kept at
the same level in the hierarchy.
This constraint accepts one additional integer parameter: the "spread size",
that is, the number of levels on which the nodes are allowed to be spread.
The spread size is optional; by default it is 0
(all nodes strictly
at the same level).
If the property is set on a link, the
constraint is defined between the source and the destination of the link.
LevelRangeConstraint
: Defines one or more
IlvLevelRangeConstraint
instances.
All the nodes that have the same value for this property will be kept in
a specified range of levels in the hierarchy.
This constraint needs two additional
parameters: a minimum and a maximum level.
If the property is set on a link, the
constraint is defined for the source and the destination of the link.
LowerRelativeLevelConstraint
, HigherRelativeLevelConstraint
:
These two properties are used together to define one or more
IlvRelativeLevelConstraint
instances.
The value of the properties identify two groups of nodes: a "lower" group and
a "higher" group. The nodes of the "lower" group will be placed at a lower level
in the hierarchy (that is, nearer to the top for a top-bottom layout).
The values of the matching "lower" and "higher" properties must be the same.
This constraint accepts one additional floating-point parameter, which is the priority of
the constraint. The priority is optional; by default it is 0
.
LowerRelativePositionConstraint
, HigherRelativePositionConstraint
:
These two properties are used together to define one or more
IlvRelativePositionConstraint
instances.
The values of the properties identify two groups of nodes: a "lower" group and
a "higher" group. The nodes of the "lower" group will be placed at a lower position
in a given level of the hierarchy (that is, nearer to the left for a top-bottom layout).
The values of the matching "lower" and "higher" properties must be the same.
This constraint accepts one additional floating-point parameter, which is the priority of
the constraint. The priority is optional; by default it is 0
.
SideBySideConstraint
: Defines one or several
IlvSideBySideConstraint
instances.
All the nodes that have the same value for this property will be kept side by side,
that is, no other nodes will be placed between any two nodes of the
group in the same level of the hierarchy.
This constraint accepts one additional floating-point parameter, which is the priority of
the constraint. The priority is optional; by default it is 0
.
If the property is set on a link, the
constraint is defined between the source and the destination of the link.
SwimLaneConstraint
: Defines one or several
IlvSwimLaneConstraint
instances.
All the nodes that have the same value for this property will be placed in the same
swimlane.
This constraint accepts three additional floating-point parameters: the relative size of the
swimlane, the position index, and the minimum margin. By default, the relative size
is -1
, the position index is -1
, and the margin
is 20
. See
IlvSwimLaneConstraint
for more explanation
of swimlanes. See also the class IlvSwimLanesRenderer
which is responsible
for displaying the swimlanes graphically.
Note: Starting with JViews 6.5, if you are not using any
hierarchical constraints, nor any node or link parameters, you can disable
this mechanism using
setUsePerObjectParameters(false)
.
This will remove the overhead of testing the presence of constraints, which can speed up
the SDM rendering process significantly.
CSS example:
GraphLayout {
alias : "<value>";
connectingLinksToShape : "false";
constraintsURL : "url(spec)";
enabled : "false";
ensureAppropriateLinks : "false";
ensureModelOrdering : "false";
graphLayout : "@#hierarchicalLayout";
graphLayoutExceptionPassedOn : "false";
linkConnectorMode : "CENTER";
partialLayout : "false";
performingLayoutOnZoom : "false";
rotationAngle : "3.0";
rotationTransformer : "0.3, 0.5, 0.5, 0.3, 0.5, 0.5";
savingNodePositions : "false";
usePerObjectParameters : "false";
}
Subobject#hierarchicalLayout {
class : "ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout";
}
IlvGraphLayout
Modifier and Type | Property and Description |
---|---|
java.lang.String |
alias
Sets the alias of this renderer. |
boolean |
connectingLinksToShape
Specifies whether the graph layout algorithm should connect the links to the shape of the nodes or to the global bounding box of the nodes. |
java.net.URL |
constraintsURL
Sets the URL that specifies the layout constraints. |
boolean |
enabled
Enables or disables the graph layout algorithm. |
boolean |
ensureAppropriateLinks
Sets whether the renderer automatically makes sure that appropriate links and link connectors are used when needed. |
boolean |
ensureModelOrdering
Specifies that the graphic nodes and links should be ordered during graph layout in the same order as the corresponding SDM model objects. |
IlvGraphLayout |
graphLayout
Sets the graph layout algorithm that this renderer will apply to the grapher. |
boolean |
graphLayoutExceptionPassedOn
Sets whether the graph layout exception is passed on. |
int |
linkConnectorMode
Sets the link connector mode. |
boolean |
partialLayout
Enables or disables the partial layout mode of the layout. |
boolean |
performingLayoutOnZoom
Specifies whether the layout algorithm should be applied every time the transformer of the reference view changes, or only when the data is initially rendered. |
double |
rotationAngle
Sets the rotation angle of the graph model. |
ilog.views.IlvTransformer |
rotationTransformer
Sets the rotation transformer of the graph model. |
boolean |
savingNodePositions
Specifies whether the positions of the nodes, as computed by the graph layout algorithm, will be saved to the data model, or if the data model will be left unchanged. |
boolean |
usePerObjectParameters
Enables or disables per-object layout parameters. |
public java.lang.String alias
SubGraph
or GraphLayout
.
alias : "<value>";
public boolean connectingLinksToShape
Some nodes (for example, the IlvGeneralNode
)
have a basic shape and a label that may be outside the shape. If this method is
called with a true
parameter, the links will be connected to
the shape, and the label will not be considered part of the node. If the
method is called with a false
parameter, the links will be
connected to the global bounding rectangle of the node, that is,
the union of the shape's bounding rectangle and the label's bounding rectangle.
The bounding rectangle of the shape is the rectangle returned by the
ilog.views.sdm.renderer.IlvSDMRenderer#getLinkConnectionRectangle
.
The global bounding rectangle of the node is the rectangle returned by the
IlvGraphic.boundingBox(ilog.views.IlvTransformer)
.
CSS example:
connectingLinksToShape : "false";
public java.net.URL constraintsURL
constraintsURL : "url(spec)";
public boolean enabled
enabled : "false";
public boolean ensureAppropriateLinks
ilog.views.graphic.IlvPolylineLinkImage
and subclasses of IlvFreeLinkConnector
are suitable for
all layout algorithms.
If layout cannot be performed because an inappropriate link or link connector is detected, then the following happens:
IlvInappropriateLinkException
is thrown.
ilog.views.graphic.IlvPolylineLinkImage
, and the inappropriate link connectors
are replaced by instances of IlvSDMFreeLinkConnector
.
Then layout is performed.
ensureAppropriateLinks : "false";
public boolean ensureModelOrdering
The option is enabled by default. Only when the option is disabled, it is
possible to specify a node or link comparator.
CSS example:
ensureModelOrdering : "false";
public IlvGraphLayout graphLayout
graphLayout : "@#hierarchicalLayout";
Subobject#hierarchicalLayout {
class : "ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout";
}
Allowed values: | ||
Circular |
new ilog.views.graphlayout.circular.IlvCircularLayout() | |
Grid |
new ilog.views.graphlayout.grid.IlvGridLayout() | |
Hierarchical |
new ilog.views.graphlayout.hierarchical.IlvHierarchicalLayout() | |
Random |
new ilog.views.graphlayout.random.IlvRandomLayout() | |
SpringEmbedder |
new ilog.views.graphlayout.springembedder.IlvSpringEmbedderLayout() | |
TopologicalMesh |
new ilog.views.graphlayout.topologicalmesh.IlvTopologicalMeshLayout() | |
Tree |
new ilog.views.graphlayout.tree.IlvTreeLayout() | |
UniformLengthEdges |
new ilog.views.graphlayout.uniformlengthedges.IlvUniformLengthEdgesLayout() |
public boolean graphLayoutExceptionPassedOn
IlvGraphLayoutException
are passed to the outside as runtime exceptions. If disabled, the
exceptions are caught and handled internally.
This option is disabled by default.
It is useful only for debugging purpose to pass on the graph layout
exception.
Independently of whether the exception is passed on or not, the exception
is logged at the logger "ilog.views.sdm.renderer.graphlayout".
graphLayoutExceptionPassedOn : "false";
public int linkConnectorMode
IlvStyleSheetRenderer#CENTER
-
Link connector mode: Use IlvSDMLinkConnector
for all nodes.
The links will be connected to the node center.
IlvStyleSheetRenderer#FREE
-
Link connector mode: Use IlvSDMFreeLinkConnector
for all nodes.
The links will be connected to the node border.
IlvStyleSheetRenderer#CLIP
-
Use IlvSDMClippingLinkConnector
for all nodes.
The links will point to the node but end on the outline of
the shape of the node. How the outline of a node is calculated
depends on the implementation of
IlvGraphic#getIntersectionWithOutline
.
IlvStyleSheetRenderer#setLinkConnectorMode
.
linkConnectorMode : "CENTER";
Allowed values: | ||
CENTER |
Link connector mode: Use IlvSDMLinkConnector for all nodes.
The links will be connected to the center of the rectangle
returned by #getLinkConnectionRectangle . |
|
FREE |
Link connector mode: Use IlvSDMFreeLinkConnector for all nodes.
The links will be connected to the border of the rectangle
returned by #getLinkConnectionRectangle . |
|
CLIP |
Link connector mode: Use IlvSDMClippingLinkConnector for all nodes.
The links will point to the the rectangle returned by
#getLinkConnectionRectangle but end on the outline of the shape
of the node. How the outline of a node is calculated depends on the
implementation of IlvGraphic#getIntersectionWithOutline . |
public boolean partialLayout
true
, and objects are selected,
all the nodes except the selected nodes are marked as fixed, so that the
layout is applied only on the selected nodes.
partialLayout : "false";
public boolean performingLayoutOnZoom
performingLayoutOnZoom : "false";
public double rotationAngle
IlvRotatedGraphModel
that rotates all coordinates by
the specific angle.
The bounding box of nodes remains upright despite of the rotation.
Specifying a rotation angle is only suitable for flat graphs.
It is not suitable for nested graphs with intergraph links, since those
are routed incorrectly when a rotation is specified.
When using a rotation angle, it is recommended to the the link
connector mode to IlvStyleSheetRenderer#CLIP
, otherwise the
links do not end at the nodes.
Rotation works well with most layout styles on flat graphs. It does not work well with Bus Layout and Long Link Layout since those layouts are not fully rotatable.
Setting the rotation angle modifies the rotation transformer.
CSS example:
rotationAngle : "3.0";
public ilog.views.IlvTransformer rotationTransformer
null
, the renderer uses
a IlvRotatedGraphModel
that transform all coordinates.
The bounding box of nodes remains upright despite of the rotation.
Specifying a rotation transformer is only suitable for flat graphs.
It is not suitable for nested graphs with intergraph links, since those
are routed incorrectly when a rotation transformer is specified.
When using a rotation transformer, it is recommended to the the link
connector mode to IlvStyleSheetRenderer#CLIP
, otherwise the
links do not end at the nodes.
Rotation works well with most layout styles on flat graphs. It does
not work well with Bus Layout and Long Link Layout since those layouts
are not fully rotatable.
CSS example:
rotationTransformer : "0.3, 0.5, 0.5, 0.3, 0.5, 0.5";
public boolean savingNodePositions
savingNodePositions : "false";
public boolean usePerObjectParameters
This method can be used to disable or re-enable the mechanism that sets per-node or per-link parameters, as explained in the class description.
By default, per-object parameters are enabled. You can
disable them if you are sure that your style sheet does not
use any per-object layout parameters. Disabling per-object
parameters speeds up the SDM rendering process.
CSS example:
usePerObjectParameters : "false";
© Copyright 2024 Rogue Wave Software, Inc., a Perforce company.. All Rights Reserved.