This article describes how one can determine minimum and maximum sizes of NodeRealizers and how to use this approach to guarantee that a node won't become smaller than its label. This is especially interesting to prevent layout algorithms from making group nodes smaller than their according labels.
In some applications it makes sense to determine the minimum and/or maximum size a node can have. If such a size is given it is not possible for the user to resize nodes interactivley to a size smaller or bigger than the given restrictions.
In yFiles 2.6 so called
SizeConstraintProviders
have been introduced. Each
NodeRealizer
can be queried for a SizeConstraintProvider that will determine the minimum and maximum size of a specific node.
A NodeRealizer that provides a SizeConstraintsProvider:
A simple version of a NodeRealizer that will have a fixed minimum and maximum size could look like this:
public static class SizeConstraintShapeNodeRealizer extends ShapeNodeRealizer {
protected final double MIN_NODE_HEIGHT = 10;
protected final double MIN_NODE_WIDTH = 10;
protected final double MAX_NODE_HEIGHT = 200;
protected final double MAX_NODE_WIDTH = 200;
public SizeConstraintShapeNodeRealizer() {
super(RECT, 0, 0, "");
}
public SizeConstraintShapeNodeRealizer(NodeRealizer nr) {
super(nr);
}
public NodeRealizer createCopy(NodeRealizer nr) {
return new SizeConstraintShapeNodeRealizer(nr);
}
public SizeConstraintProvider getSizeConstraintProvider() {
return new SizeConstraintProvider.Default(MIN_NODE_WIDTH, MIN_NODE_HEIGHT, MAX_NODE_WIDTH, MAX_NODE_HEIGHT);
}
}
|
A NodeRealizer that provides a SizeConstraintsProvider that provides minimum sizes according to the node's label:
This approach can also be used to prevent that a node will be made smaller than its label:
/**
* This custom ShapeNodeRealizer reacts on label bounds changes of its first label and resizes
* the node accordingly. Furthermor it provides a SizeConstraintProvider that is used to
* determine minimum and maximum node sizes. This provider is for example used for
* interactive HotSpot resizing.
*/
public static class LabelAwareShapeNodeRealizer extends ShapeNodeRealizer {
protected final double MAX_NODE_HEIGHT = Double.MAX_VALUE;
protected final double MAX_NODE_WIDTH = Double.MAX_VALUE;
public LabelAwareShapeNodeRealizer() {
super(RECT, 0, 0, "");
}
public LabelAwareShapeNodeRealizer(NodeRealizer nr) {
super(nr);
}
public NodeRealizer createCopy(NodeRealizer nr) {
return new LabelAwareShapeNodeRealizer(nr);
}
public SizeConstraintProvider getSizeConstraintProvider() {
return new SizeConstraintProvider.Default(Math.max(1, getLabel().getWidth()),
Math.max(1, getLabel().getHeight()), MAX_NODE_WIDTH, MAX_NODE_HEIGHT);
}
protected void labelBoundsChanged(NodeLabel label) {
if (label == getLabel()) { setSize(Math.max(30, label.getWidth()), Math.max(30, label.getHeight()));
}
}
}
|
Using SizeConstraintsProviders to prevent group nodes from becoming smaller than their label during automatic layouts:
The latter approach is especially interesting for group nodes.
By default layout algorithms will resize group nodes according to the inner graph of such a node. Thus the group nodes would often be made smaller than the according label, which will then overlap the node:

If a SizeConstraintProvider is provided by the group node realizer, the layout algorithms will keep to the provided sizes. For convenience both
GroupNodeRealizer
and
GenericGroupNodeRealizer
provide methods to determine whether a SizeConstraintProvider shall be returned that provides minimum sizes for this group node according to the group's label.
By default this feature is deactivated. To activate it, do the following:
For GroupNoderealizers:
- call y.view.hierarchy.GroupNodeRealizer#setConsiderNodeLabelSize(true);
For GenericGroupNoderealizers:
- Add a configuration to the factory that uses a custom DefaultGenericAutoBoundsFeature
:
GenericGroupNodeRealizer group = new GenericGroupNodeRealizer();
Map implementationMap = GenericGroupNodeRealizer.createDefaultConfigurationMap();
DefaultGenericAutoBoundsFeature abf = new DefaultGenericAutoBoundsFeature();
abf.setConsiderNodeLabelSize(true);
implementationMap.put(GenericGroupNodeRealizer.GenericAutoBoundsFeature.class, abf);
GenericNodeRealizer.getFactory().addConfiguration("group", implementationMap);
group.setConfiguration("group");
|
| Note |
|
Minimum and maximum node sizes provided by SizeConstraintProviders are queried and sticked to by the following layout algorithms:
Layouter algorithms that currently do not keep to the provided sizes are:
|
| Note |
|
Size constraints are queried and checked for interactive resizing (e.g. via HotSpotMode ) and for automatic node resizes from layout algorithms (See the above list of layout algorithms that support this feature).
When setting a node size directly in the source code, e.g. by calling NodeRealizer.setSize(double, double) , the constraints will not be checked and the node will be resized no matter if it will afterwards stick to the constraints or not. |
See also the according sections in the
developers guide
: