How to determine minimum and maximum sizes of NodeRealizers
Applies to: yFiles 2.6 print article email article

Type: Questions & Answers

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() {
      //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 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:

Keywords: minimum - maximum - size - node - SizeConstraintProvider - NodeRealizer - label - getSizeConstraintProvider

Provide feedback:
How useful was this article?    less 1 2 3 4 5 more
Email address (optional):
COPYRIGHT © 2008 yWorks · ALL RIGHTS RESERVED imprint | top | home