How to specify minimum and maximum sizes of NodeRealizers
Questions & AnswersSummary
Description
In some applications it makes sense to specify 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() {
//provide the minimum and maximum sizes this realizer shall have.
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() {
//provide the minimum and maximum sizes this realizer shall have.
//in this case the minimum size is determined by the first node label.
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()) {//only resize on bounds changes of the first label
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 minimum size. The layout algorithms will not keep to the provided maximum size, since more space might be needed for the inner graph. 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");
See also the according sections in the developers guide: